Lazily allocated heap-backed block device. When writing data of ROM address, heap memory is not used.
Dependents: GR-PEACH-webcam GR-PEACH_DR_STRANGE_VR_GAME GR-Boards_WebCamera
RomRamBlockDevice.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 "RomRamBlockDevice.h" 00018 00019 00020 RomRamBlockDevice::RomRamBlockDevice(bd_size_t size, bd_size_t block) 00021 : _read_size(block), _program_size(block), _erase_size(block) 00022 , _count(size / block), _blocks(0), _rom_start(0xFFFFFFFF), _rom_end(0xFFFFFFFF) 00023 { 00024 MBED_ASSERT(_count * _erase_size == size); 00025 } 00026 00027 RomRamBlockDevice::RomRamBlockDevice(bd_size_t size, bd_size_t read, bd_size_t program, bd_size_t erase) 00028 : _read_size(read), _program_size(program), _erase_size(erase) 00029 , _count(size / erase), _blocks(0), _rom_start(0xFFFFFFFF), _rom_end(0xFFFFFFFF) 00030 { 00031 MBED_ASSERT(_count * _erase_size == size); 00032 } 00033 00034 RomRamBlockDevice::~RomRamBlockDevice() 00035 { 00036 if (_blocks) { 00037 for (size_t i = 0; i < _count; i++) { 00038 free(_blocks[i]); 00039 } 00040 00041 delete[] _blocks; 00042 _blocks = 0; 00043 } 00044 } 00045 00046 void RomRamBlockDevice::SetRomAddr(uint32_t rom_start_addr, uint32_t rom_end_addr) { 00047 _rom_start = rom_start_addr; 00048 _rom_end = rom_end_addr; 00049 } 00050 00051 int RomRamBlockDevice::init() 00052 { 00053 if (!_blocks) { 00054 _blocks = new uint8_t*[_count]; 00055 for (size_t i = 0; i < _count; i++) { 00056 _blocks[i] = 0; 00057 } 00058 } 00059 00060 return BD_ERROR_OK; 00061 } 00062 00063 int RomRamBlockDevice::deinit() 00064 { 00065 // Heapory is lazily cleaned up in destructor to allow 00066 // data to live across de/reinitialization 00067 return BD_ERROR_OK; 00068 } 00069 00070 bd_size_t RomRamBlockDevice::get_read_size() const 00071 { 00072 return _read_size; 00073 } 00074 00075 bd_size_t RomRamBlockDevice::get_program_size() const 00076 { 00077 return _program_size; 00078 } 00079 00080 bd_size_t RomRamBlockDevice::get_erase_size() const 00081 { 00082 return _erase_size; 00083 } 00084 00085 bd_size_t RomRamBlockDevice::size() const 00086 { 00087 return _count * _erase_size; 00088 } 00089 00090 int RomRamBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) 00091 { 00092 MBED_ASSERT(is_valid_read(addr, size)); 00093 uint8_t *buffer = static_cast<uint8_t*>(b); 00094 00095 while (size > 0) { 00096 bd_addr_t hi = addr / _erase_size; 00097 bd_addr_t lo = addr % _erase_size; 00098 00099 if (_blocks[hi]) { 00100 memcpy(buffer, &_blocks[hi][lo], _read_size); 00101 } else { 00102 memset(buffer, 0, _read_size); 00103 } 00104 00105 buffer += _read_size; 00106 addr += _read_size; 00107 size -= _read_size; 00108 } 00109 00110 return 0; 00111 } 00112 00113 int RomRamBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size) 00114 { 00115 MBED_ASSERT(is_valid_program(addr, size)); 00116 const uint8_t *buffer = static_cast<const uint8_t*>(b); 00117 00118 while (size > 0) { 00119 bd_addr_t hi = addr / _erase_size; 00120 bd_addr_t lo = addr % _erase_size; 00121 00122 if (isRomAddress(buffer)) { 00123 if (!isRomAddress(_blocks[hi])) { 00124 free(_blocks[hi]); 00125 } 00126 _blocks[hi] = (uint8_t*)buffer; 00127 } else { 00128 if (!_blocks[hi]) { 00129 _blocks[hi] = (uint8_t*)malloc(_erase_size); 00130 if (!_blocks[hi]) { 00131 return BD_ERROR_DEVICE_ERROR; 00132 } 00133 } 00134 memcpy(&_blocks[hi][lo], buffer, _program_size); 00135 } 00136 00137 buffer += _program_size; 00138 addr += _program_size; 00139 size -= _program_size; 00140 } 00141 00142 return 0; 00143 } 00144 00145 int RomRamBlockDevice::erase(bd_addr_t addr, bd_size_t size) 00146 { 00147 MBED_ASSERT(is_valid_erase(addr, size)); 00148 // TODO assert on programming unerased blocks 00149 00150 return 0; 00151 } 00152 00153 bool RomRamBlockDevice::isRomAddress(const uint8_t *address) { 00154 if (((uint32_t)address >= _rom_start) 00155 && ((uint32_t)address <= (_rom_end - _erase_size + 1))) { 00156 return true; 00157 } 00158 return false; 00159 } 00160
Generated on Thu Jul 14 2022 00:25:53 by
