Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FlashSimBlockDevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "FlashSimBlockDevice.h" 00018 #include "mbed_assert.h" 00019 #include "mbed_critical.h" 00020 #include <algorithm> 00021 #include <stdlib.h> 00022 #include <string.h> 00023 00024 static const bd_size_t min_blank_buf_size = 32; 00025 00026 static inline uint32_t align_up(bd_size_t val, bd_size_t size) 00027 { 00028 return (((val - 1) / size) + 1) * size; 00029 } 00030 00031 FlashSimBlockDevice::FlashSimBlockDevice(BlockDevice *bd, uint8_t erase_value) : 00032 _erase_value(erase_value), _blank_buf_size(0), 00033 _blank_buf(0), _bd(bd), _init_ref_count(0), _is_initialized(false) 00034 { 00035 } 00036 00037 FlashSimBlockDevice::~FlashSimBlockDevice() 00038 { 00039 deinit(); 00040 delete[] _blank_buf; 00041 } 00042 00043 int FlashSimBlockDevice::init() 00044 { 00045 int err; 00046 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); 00047 00048 if (val != 1) { 00049 return BD_ERROR_OK; 00050 } 00051 00052 err = _bd->init(); 00053 if (err) { 00054 goto fail; 00055 } 00056 _blank_buf_size = align_up(min_blank_buf_size, _bd->get_program_size()); 00057 if (!_blank_buf) { 00058 _blank_buf = new uint8_t[_blank_buf_size]; 00059 MBED_ASSERT(_blank_buf); 00060 } 00061 00062 _is_initialized = true; 00063 return BD_ERROR_OK; 00064 00065 fail: 00066 _is_initialized = false; 00067 _init_ref_count = 0; 00068 return err; 00069 } 00070 00071 int FlashSimBlockDevice::deinit() 00072 { 00073 if (!_is_initialized) { 00074 return BD_ERROR_OK; 00075 } 00076 00077 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); 00078 00079 if (val) { 00080 return BD_ERROR_OK; 00081 } 00082 00083 _is_initialized = false; 00084 return _bd->deinit(); 00085 } 00086 00087 int FlashSimBlockDevice::sync() 00088 { 00089 if (!_is_initialized) { 00090 return BD_ERROR_DEVICE_ERROR; 00091 } 00092 00093 return _bd->sync(); 00094 } 00095 00096 bd_size_t FlashSimBlockDevice::get_read_size() const 00097 { 00098 if (!_is_initialized) { 00099 return BD_ERROR_DEVICE_ERROR; 00100 } 00101 00102 return _bd->get_read_size(); 00103 } 00104 00105 bd_size_t FlashSimBlockDevice::get_program_size() const 00106 { 00107 if (!_is_initialized) { 00108 return BD_ERROR_DEVICE_ERROR; 00109 } 00110 00111 return _bd->get_program_size(); 00112 } 00113 00114 bd_size_t FlashSimBlockDevice::get_erase_size() const 00115 { 00116 if (!_is_initialized) { 00117 return BD_ERROR_DEVICE_ERROR; 00118 } 00119 00120 return _bd->get_erase_size(); 00121 } 00122 00123 bd_size_t FlashSimBlockDevice::get_erase_size(bd_addr_t addr) const 00124 { 00125 if (!_is_initialized) { 00126 return BD_ERROR_DEVICE_ERROR; 00127 } 00128 00129 return _bd->get_erase_size(addr); 00130 } 00131 00132 bd_size_t FlashSimBlockDevice::size() const 00133 { 00134 if (!_is_initialized) { 00135 return BD_ERROR_DEVICE_ERROR; 00136 } 00137 00138 return _bd->size(); 00139 } 00140 00141 int FlashSimBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) 00142 { 00143 if (!_is_initialized) { 00144 return BD_ERROR_DEVICE_ERROR; 00145 } 00146 00147 return _bd->read(b, addr, size); 00148 } 00149 00150 int FlashSimBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size) 00151 { 00152 MBED_ASSERT(is_valid_program(addr, size)); 00153 if (!_is_initialized) { 00154 return BD_ERROR_DEVICE_ERROR; 00155 } 00156 00157 bd_addr_t curr_addr = addr; 00158 bd_size_t curr_size = size; 00159 00160 const uint8_t *buf = (const uint8_t *) b; 00161 while (curr_size) { 00162 bd_size_t read_size = std::min(_blank_buf_size, curr_size); 00163 int ret = _bd->read(_blank_buf, curr_addr, read_size); 00164 if (ret) { 00165 return ret; 00166 } 00167 for (bd_size_t i = 0; i < read_size; i++) { 00168 // Allow either programming on blanks or programming the same value 00169 // (as real flash devices do) 00170 if ((_blank_buf[i] != _erase_value) && (_blank_buf[i] != *buf)) { 00171 return BD_ERROR_NOT_ERASED; 00172 } 00173 buf++; 00174 } 00175 curr_addr += read_size; 00176 curr_size -= read_size; 00177 } 00178 00179 return _bd->program(b, addr, size); 00180 } 00181 00182 int FlashSimBlockDevice::erase(bd_addr_t addr, bd_size_t size) 00183 { 00184 MBED_ASSERT(is_valid_erase(addr, size)); 00185 00186 if (!_is_initialized) { 00187 return BD_ERROR_DEVICE_ERROR; 00188 } 00189 00190 bd_addr_t curr_addr = addr; 00191 bd_size_t curr_size = size; 00192 00193 memset(_blank_buf, _erase_value, (unsigned int) _blank_buf_size); 00194 00195 while (curr_size) { 00196 bd_size_t prog_size = std::min(_blank_buf_size, curr_size); 00197 int ret = _bd->program(_blank_buf, curr_addr, prog_size); 00198 if (ret) { 00199 return ret; 00200 } 00201 curr_addr += prog_size; 00202 curr_size -= prog_size; 00203 } 00204 00205 return BD_ERROR_OK; 00206 } 00207 00208 int FlashSimBlockDevice::get_erase_value() const 00209 { 00210 return _erase_value; 00211 }
Generated on Tue Aug 9 2022 00:37:07 by
