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.
FlashIAPBlockDevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2016 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 #ifdef DEVICE_FLASH 00018 00019 #include "FlashIAPBlockDevice.h" 00020 #include "mbed_critical.h" 00021 00022 #include "mbed.h" 00023 00024 #include <inttypes.h> 00025 00026 #define FLASHIAP_READ_SIZE 1 00027 00028 // Debug available 00029 #ifndef FLASHIAP_DEBUG 00030 #define FLASHIAP_DEBUG 0 00031 #endif 00032 00033 #if FLASHIAP_DEBUG 00034 #define DEBUG_PRINTF(...) printf(__VA_ARGS__) 00035 #else 00036 #define DEBUG_PRINTF(...) 00037 #endif 00038 00039 FlashIAPBlockDevice::FlashIAPBlockDevice(uint32_t address, uint32_t size) 00040 : _flash(), _base(address), _size(size), _is_initialized(false), _init_ref_count(0) 00041 { 00042 00043 } 00044 00045 FlashIAPBlockDevice::~FlashIAPBlockDevice() 00046 { 00047 deinit(); 00048 } 00049 00050 int FlashIAPBlockDevice::init() 00051 { 00052 DEBUG_PRINTF("init\r\n"); 00053 00054 if (!_is_initialized) { 00055 _init_ref_count = 0; 00056 } 00057 00058 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); 00059 00060 if (val != 1) { 00061 return BD_ERROR_OK; 00062 } 00063 00064 int ret = _flash.init(); 00065 00066 if (ret) { 00067 core_util_atomic_decr_u32(&_init_ref_count, 1); 00068 return ret; 00069 } 00070 00071 if (_size + _base > _flash.get_flash_size() + _flash.get_flash_start()) { 00072 core_util_atomic_decr_u32(&_init_ref_count, 1); 00073 return BD_ERROR_DEVICE_ERROR; 00074 } 00075 00076 if (_base < _flash.get_flash_start()) { 00077 core_util_atomic_decr_u32(&_init_ref_count, 1); 00078 return BD_ERROR_DEVICE_ERROR; 00079 } 00080 00081 if (!_base) { 00082 _base = _flash.get_flash_start(); 00083 } 00084 00085 if (!_size) { 00086 _size = _flash.get_flash_size() - (_base - _flash.get_flash_start()); 00087 } 00088 00089 _is_initialized = true; 00090 return ret; 00091 } 00092 00093 int FlashIAPBlockDevice::deinit() 00094 { 00095 DEBUG_PRINTF("deinit\r\n"); 00096 00097 if (!_is_initialized) { 00098 _init_ref_count = 0; 00099 return 0; 00100 } 00101 00102 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); 00103 00104 if (val) { 00105 return 0; 00106 } 00107 00108 _is_initialized = false; 00109 00110 return _flash.deinit(); 00111 } 00112 00113 int FlashIAPBlockDevice::read(void *buffer, 00114 bd_addr_t virtual_address, 00115 bd_size_t size) 00116 { 00117 DEBUG_PRINTF("read: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size); 00118 00119 /* Default to error return code; success must be set explicitly. */ 00120 int result = BD_ERROR_DEVICE_ERROR; 00121 00122 /* Check that the address and size are properly aligned and fit. */ 00123 if (_is_initialized && is_valid_read(virtual_address, size)) { 00124 00125 /* Convert virtual address to the physical address for the device. */ 00126 bd_addr_t physical_address = _base + virtual_address; 00127 00128 /* Read data using the internal flash driver. */ 00129 result = _flash.read(buffer, physical_address, size); 00130 00131 DEBUG_PRINTF("physical: %" PRIX64 "\r\n", physical_address); 00132 } 00133 00134 return result; 00135 } 00136 00137 int FlashIAPBlockDevice::program(const void *buffer, 00138 bd_addr_t virtual_address, 00139 bd_size_t size) 00140 { 00141 DEBUG_PRINTF("program: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size); 00142 00143 /* Default to error return code; success must be set explicitly. */ 00144 int result = BD_ERROR_DEVICE_ERROR; 00145 00146 /* Check that the address and size are properly aligned and fit. */ 00147 if (_is_initialized && is_valid_program(virtual_address, size)) { 00148 00149 /* Convert virtual address to the physical address for the device. */ 00150 bd_addr_t physical_address = _base + virtual_address; 00151 00152 /* Write data using the internal flash driver. */ 00153 result = _flash.program(buffer, physical_address, size); 00154 00155 DEBUG_PRINTF("physical: %" PRIX64 " %" PRIX64 "\r\n", 00156 physical_address, 00157 size); 00158 } 00159 00160 return result; 00161 } 00162 00163 int FlashIAPBlockDevice::erase(bd_addr_t virtual_address, 00164 bd_size_t size) 00165 { 00166 DEBUG_PRINTF("erase: %" PRIX64 " %" PRIX64 "\r\n", virtual_address, size); 00167 00168 /* Default to error return code; success must be set explicitly. */ 00169 int result = BD_ERROR_DEVICE_ERROR; 00170 00171 /* Check that the address and size are properly aligned and fit. */ 00172 if (_is_initialized && is_valid_erase(virtual_address, size)) { 00173 00174 /* Convert virtual address to the physical address for the device. */ 00175 bd_addr_t physical_address = _base + virtual_address; 00176 00177 /* Erase sector */ 00178 result = _flash.erase(physical_address, size); 00179 } 00180 00181 return result; 00182 } 00183 00184 bd_size_t FlashIAPBlockDevice::get_read_size() const 00185 { 00186 DEBUG_PRINTF("get_read_size: %d\r\n", FLASHIAP_READ_SIZE); 00187 00188 return FLASHIAP_READ_SIZE; 00189 } 00190 00191 bd_size_t FlashIAPBlockDevice::get_program_size() const 00192 { 00193 if (!_is_initialized) { 00194 return 0; 00195 } 00196 00197 uint32_t page_size = _flash.get_page_size(); 00198 00199 DEBUG_PRINTF("get_program_size: %" PRIX32 "\r\n", page_size); 00200 00201 return page_size; 00202 } 00203 00204 bd_size_t FlashIAPBlockDevice::get_erase_size() const 00205 { 00206 if (!_is_initialized) { 00207 return 0; 00208 } 00209 00210 uint32_t erase_size = _flash.get_sector_size(_base); 00211 00212 DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); 00213 00214 return erase_size; 00215 } 00216 00217 bd_size_t FlashIAPBlockDevice::get_erase_size(bd_addr_t addr) const 00218 { 00219 if (!_is_initialized) { 00220 return 0; 00221 } 00222 00223 uint32_t erase_size = _flash.get_sector_size(_base + addr); 00224 00225 DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); 00226 00227 return erase_size; 00228 } 00229 00230 bd_size_t FlashIAPBlockDevice::size() const 00231 { 00232 DEBUG_PRINTF("size: %" PRIX64 "\r\n", _size); 00233 00234 return _size; 00235 } 00236 00237 #endif /* DEVICE_FLASH */
Generated on Tue Jul 12 2022 20:52:43 by
1.7.2