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