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
ExhaustibleBlockDevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 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 "ExhaustibleBlockDevice.h" 00018 #include "platform/mbed_atomic.h" 00019 #include "platform/mbed_assert.h" 00020 00021 namespace mbed { 00022 00023 ExhaustibleBlockDevice::ExhaustibleBlockDevice(BlockDevice *bd, uint32_t erase_cycles) 00024 : _bd(bd), _erase_array(NULL), _erase_cycles(erase_cycles), _init_ref_count(0), _is_initialized(false) 00025 { 00026 } 00027 00028 ExhaustibleBlockDevice::~ExhaustibleBlockDevice() 00029 { 00030 delete[] _erase_array; 00031 } 00032 00033 int ExhaustibleBlockDevice::init() 00034 { 00035 int err; 00036 uint32_t val = core_util_atomic_incr_u32 (&_init_ref_count, 1); 00037 00038 if (val != 1) { 00039 return BD_ERROR_OK; 00040 } 00041 00042 err = _bd->init(); 00043 if (err) { 00044 goto fail; 00045 } 00046 00047 if (!_erase_array) { 00048 // can only be allocated after initialization 00049 _erase_array = new uint32_t[_bd->size() / _bd->get_erase_size()]; 00050 for (size_t i = 0; i < _bd->size() / _bd->get_erase_size(); i++) { 00051 _erase_array[i] = _erase_cycles; 00052 } 00053 } 00054 00055 _is_initialized = true; 00056 return BD_ERROR_OK; 00057 00058 fail: 00059 _is_initialized = false; 00060 _init_ref_count = 0; 00061 return err; 00062 } 00063 00064 int ExhaustibleBlockDevice::deinit() 00065 { 00066 if (!_is_initialized) { 00067 return BD_ERROR_OK; 00068 } 00069 00070 core_util_atomic_decr_u32 (&_init_ref_count, 1); 00071 00072 if (_init_ref_count) { 00073 return BD_ERROR_OK; 00074 } 00075 00076 // _erase_array is lazily cleaned up in destructor to allow 00077 // data to live across de/reinitialization 00078 _is_initialized = false; 00079 return _bd->deinit(); 00080 } 00081 00082 int ExhaustibleBlockDevice::sync() 00083 { 00084 if (!_is_initialized) { 00085 return BD_ERROR_DEVICE_ERROR; 00086 } 00087 00088 return _bd->sync(); 00089 } 00090 00091 int ExhaustibleBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) 00092 { 00093 if (!_is_initialized) { 00094 return BD_ERROR_DEVICE_ERROR; 00095 } 00096 00097 return _bd->read(buffer, addr, size); 00098 } 00099 00100 int ExhaustibleBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size) 00101 { 00102 MBED_ASSERT(is_valid_program(addr, size)); 00103 00104 if (!_is_initialized) { 00105 return BD_ERROR_DEVICE_ERROR; 00106 } 00107 00108 if (_erase_array[addr / get_erase_size()] == 0) { 00109 return 0; 00110 } 00111 00112 return _bd->program(buffer, addr, size); 00113 } 00114 00115 int ExhaustibleBlockDevice::erase(bd_addr_t addr, bd_size_t size) 00116 { 00117 MBED_ASSERT(is_valid_erase(addr, size)); 00118 if (!_is_initialized) { 00119 return BD_ERROR_DEVICE_ERROR; 00120 } 00121 00122 bd_size_t eu_size = get_erase_size(); 00123 while (size) { 00124 // use an erase cycle 00125 if (_erase_array[addr / eu_size] > 0) { 00126 _erase_array[addr / eu_size] -= 1; 00127 } 00128 00129 if (_erase_array[addr / eu_size] > 0) { 00130 int err = _bd->erase(addr, eu_size); 00131 if (err) { 00132 return err; 00133 } 00134 } 00135 00136 addr += eu_size; 00137 size -= eu_size; 00138 } 00139 00140 return 0; 00141 } 00142 00143 bd_size_t ExhaustibleBlockDevice::get_read_size() const 00144 { 00145 if (!_is_initialized) { 00146 return 0; 00147 } 00148 00149 return _bd->get_read_size(); 00150 } 00151 00152 bd_size_t ExhaustibleBlockDevice::get_program_size() const 00153 { 00154 if (!_is_initialized) { 00155 return 0; 00156 } 00157 00158 return _bd->get_program_size(); 00159 } 00160 00161 bd_size_t ExhaustibleBlockDevice::get_erase_size() const 00162 { 00163 if (!_is_initialized) { 00164 return 0; 00165 } 00166 00167 return _bd->get_erase_size(); 00168 } 00169 00170 bd_size_t ExhaustibleBlockDevice::get_erase_size(bd_addr_t addr) const 00171 { 00172 if (!_is_initialized) { 00173 return 0; 00174 } 00175 00176 return _bd->get_erase_size(addr); 00177 } 00178 00179 int ExhaustibleBlockDevice::get_erase_value() const 00180 { 00181 if (!_is_initialized) { 00182 return BD_ERROR_DEVICE_ERROR; 00183 } 00184 00185 return _bd->get_erase_value(); 00186 } 00187 00188 bd_size_t ExhaustibleBlockDevice::size() const 00189 { 00190 if (!_is_initialized) { 00191 return 0; 00192 } 00193 00194 return _bd->size(); 00195 } 00196 00197 const char *ExhaustibleBlockDevice::get_type() const 00198 { 00199 if (_bd != NULL) { 00200 return _bd->get_type(); 00201 } 00202 00203 return NULL; 00204 } 00205 00206 } // namespace mbed 00207
Generated on Tue Jul 12 2022 13:54:19 by
1.7.2