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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 "platform/mbed_assert.h" 00019 #include "platform/mbed_atomic.h" 00020 #include <algorithm> 00021 #include <stdlib.h> 00022 #include <string.h> 00023 #include "mbed_assert.h" 00024 00025 namespace mbed { 00026 00027 static const bd_size_t min_blank_buf_size = 32; 00028 00029 static inline uint32_t align_up(bd_size_t val, bd_size_t size) 00030 { 00031 return (((val - 1) / size) + 1) * size; 00032 } 00033 00034 FlashSimBlockDevice::FlashSimBlockDevice(BlockDevice *bd, uint8_t erase_value) : 00035 _erase_value(erase_value), _blank_buf_size(0), 00036 _blank_buf(0), _bd(bd), _init_ref_count(0), _is_initialized(false) 00037 { 00038 MBED_ASSERT(bd); 00039 } 00040 00041 FlashSimBlockDevice::~FlashSimBlockDevice() 00042 { 00043 deinit(); 00044 delete[] _blank_buf; 00045 } 00046 00047 int FlashSimBlockDevice::init() 00048 { 00049 int err; 00050 uint32_t val = core_util_atomic_incr_u32 (&_init_ref_count, 1); 00051 00052 if (val != 1) { 00053 return BD_ERROR_OK; 00054 } 00055 00056 err = _bd->init(); 00057 if (err) { 00058 goto fail; 00059 } 00060 _blank_buf_size = align_up(min_blank_buf_size, _bd->get_program_size()); 00061 if (!_blank_buf) { 00062 _blank_buf = new uint8_t[_blank_buf_size]; 00063 MBED_ASSERT(_blank_buf); 00064 } 00065 00066 _is_initialized = true; 00067 return BD_ERROR_OK; 00068 00069 fail: 00070 _is_initialized = false; 00071 _init_ref_count = 0; 00072 return err; 00073 } 00074 00075 int FlashSimBlockDevice::deinit() 00076 { 00077 if (!_is_initialized) { 00078 return BD_ERROR_OK; 00079 } 00080 00081 uint32_t val = core_util_atomic_decr_u32 (&_init_ref_count, 1); 00082 00083 if (val) { 00084 return BD_ERROR_OK; 00085 } 00086 00087 _is_initialized = false; 00088 return _bd->deinit(); 00089 } 00090 00091 int FlashSimBlockDevice::sync() 00092 { 00093 if (!_is_initialized) { 00094 return BD_ERROR_DEVICE_ERROR; 00095 } 00096 00097 return _bd->sync(); 00098 } 00099 00100 bd_size_t FlashSimBlockDevice::get_read_size() const 00101 { 00102 if (!_is_initialized) { 00103 return 0; 00104 } 00105 00106 return _bd->get_read_size(); 00107 } 00108 00109 bd_size_t FlashSimBlockDevice::get_program_size() const 00110 { 00111 if (!_is_initialized) { 00112 return 0; 00113 } 00114 00115 return _bd->get_program_size(); 00116 } 00117 00118 bd_size_t FlashSimBlockDevice::get_erase_size() const 00119 { 00120 if (!_is_initialized) { 00121 return 0; 00122 } 00123 00124 return _bd->get_erase_size(); 00125 } 00126 00127 bd_size_t FlashSimBlockDevice::get_erase_size(bd_addr_t addr) const 00128 { 00129 if (!_is_initialized) { 00130 return 0; 00131 } 00132 00133 return _bd->get_erase_size(addr); 00134 } 00135 00136 bd_size_t FlashSimBlockDevice::size() const 00137 { 00138 if (!_is_initialized) { 00139 return 0; 00140 } 00141 00142 return _bd->size(); 00143 } 00144 00145 int FlashSimBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) 00146 { 00147 if (!_is_initialized) { 00148 return BD_ERROR_DEVICE_ERROR; 00149 } 00150 00151 return _bd->read(b, addr, size); 00152 } 00153 00154 int FlashSimBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size) 00155 { 00156 MBED_ASSERT(is_valid_program(addr, size)); 00157 if (!_is_initialized) { 00158 return BD_ERROR_DEVICE_ERROR; 00159 } 00160 00161 bd_addr_t curr_addr = addr; 00162 bd_size_t curr_size = size; 00163 00164 const uint8_t *buf = (const uint8_t *) b; 00165 while (curr_size) { 00166 bd_size_t read_size = std::min(_blank_buf_size, curr_size); 00167 int ret = _bd->read(_blank_buf, curr_addr, read_size); 00168 if (ret) { 00169 return ret; 00170 } 00171 for (bd_size_t i = 0; i < read_size; i++) { 00172 // Allow either programming on blanks or programming the same value 00173 // (as real flash devices do) 00174 if ((_blank_buf[i] != _erase_value) && (_blank_buf[i] != *buf)) { 00175 return BD_ERROR_NOT_ERASED; 00176 } 00177 buf++; 00178 } 00179 curr_addr += read_size; 00180 curr_size -= read_size; 00181 } 00182 00183 return _bd->program(b, addr, size); 00184 } 00185 00186 int FlashSimBlockDevice::erase(bd_addr_t addr, bd_size_t size) 00187 { 00188 MBED_ASSERT(is_valid_erase(addr, size)); 00189 00190 if (!_is_initialized) { 00191 return BD_ERROR_DEVICE_ERROR; 00192 } 00193 00194 bd_addr_t curr_addr = addr; 00195 bd_size_t curr_size = size; 00196 00197 memset(_blank_buf, _erase_value, (unsigned int) _blank_buf_size); 00198 00199 while (curr_size) { 00200 bd_size_t prog_size = std::min(_blank_buf_size, curr_size); 00201 int ret = _bd->program(_blank_buf, curr_addr, prog_size); 00202 if (ret) { 00203 return ret; 00204 } 00205 curr_addr += prog_size; 00206 curr_size -= prog_size; 00207 } 00208 00209 return BD_ERROR_OK; 00210 } 00211 00212 int FlashSimBlockDevice::get_erase_value() const 00213 { 00214 return _erase_value; 00215 } 00216 00217 const char *FlashSimBlockDevice::get_type() const 00218 { 00219 if (_bd != NULL) { 00220 return _bd->get_type(); 00221 } 00222 00223 return NULL; 00224 } 00225 00226 } // namespace mbed 00227
Generated on Tue Jul 12 2022 13:54:22 by
