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