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.
Dependencies: nRF51_Vdd TextLCD BME280
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_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 0; 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 0; 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 0; 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 0; 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 0; 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 Jul 12 2022 15:15:45 by
