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.
FlashIAP.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00020 * SOFTWARE. 00021 */ 00022 00023 #include <string.h> 00024 #include "FlashIAP.h" 00025 #include "mbed_assert.h" 00026 00027 00028 #ifdef DEVICE_FLASH 00029 00030 namespace mbed { 00031 00032 SingletonPtr<PlatformMutex> FlashIAP::_mutex; 00033 00034 static inline bool is_aligned(uint32_t number, uint32_t alignment) 00035 { 00036 if ((number % alignment) != 0) { 00037 return false; 00038 } else { 00039 return true; 00040 } 00041 } 00042 00043 FlashIAP::FlashIAP() 00044 { 00045 00046 } 00047 00048 FlashIAP::~FlashIAP() 00049 { 00050 00051 } 00052 00053 int FlashIAP::init() 00054 { 00055 int ret = 0; 00056 _mutex->lock(); 00057 if (flash_init(&_flash)) { 00058 ret = -1; 00059 } 00060 _mutex->unlock(); 00061 return ret; 00062 } 00063 00064 int FlashIAP::deinit() 00065 { 00066 int ret = 0; 00067 _mutex->lock(); 00068 if (flash_free(&_flash)) { 00069 ret = -1; 00070 } 00071 _mutex->unlock(); 00072 return ret; 00073 } 00074 00075 00076 int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size) 00077 { 00078 int32_t ret = -1; 00079 _mutex->lock(); 00080 ret = flash_read(&_flash, addr, (uint8_t *) buffer, size); 00081 _mutex->unlock(); 00082 return ret; 00083 } 00084 00085 int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size) 00086 { 00087 uint32_t page_size = get_page_size(); 00088 uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); 00089 // addr and size should be aligned to page size, and multiple of page size 00090 // page program should not cross sector boundaries 00091 if (!is_aligned(addr, page_size) || 00092 !is_aligned(size, page_size) || 00093 (size < page_size) || 00094 (((addr % current_sector_size) + size) > current_sector_size)) { 00095 return -1; 00096 } 00097 00098 int ret = 0; 00099 _mutex->lock(); 00100 if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) { 00101 ret = -1; 00102 } 00103 _mutex->unlock(); 00104 return ret; 00105 } 00106 00107 bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size) 00108 { 00109 uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); 00110 if (!is_aligned(size, current_sector_size) || 00111 !is_aligned(addr, current_sector_size)) { 00112 return false; 00113 } else { 00114 return true; 00115 } 00116 } 00117 00118 int FlashIAP::erase(uint32_t addr, uint32_t size) 00119 { 00120 uint32_t current_sector_size = 0UL; 00121 00122 if (!is_aligned_to_sector(addr, size)) { 00123 return -1; 00124 } 00125 00126 int32_t ret = 0; 00127 _mutex->lock(); 00128 while (size) { 00129 ret = flash_erase_sector(&_flash, addr); 00130 if (ret != 0) { 00131 ret = -1; 00132 break; 00133 } 00134 current_sector_size = flash_get_sector_size(&_flash, addr); 00135 if (!is_aligned_to_sector(addr, size)) { 00136 ret = -1; 00137 break; 00138 } 00139 size -= current_sector_size; 00140 addr += current_sector_size; 00141 } 00142 _mutex->unlock(); 00143 return ret; 00144 } 00145 00146 uint32_t FlashIAP::get_page_size() const 00147 { 00148 return flash_get_page_size(&_flash); 00149 } 00150 00151 uint32_t FlashIAP::get_sector_size(uint32_t addr) const 00152 { 00153 return flash_get_sector_size(&_flash, addr); 00154 } 00155 00156 uint32_t FlashIAP::get_flash_start() const 00157 { 00158 return flash_get_start_address(&_flash); 00159 } 00160 00161 uint32_t FlashIAP::get_flash_size() const 00162 { 00163 return flash_get_size(&_flash); 00164 } 00165 00166 } 00167 00168 #endif
Generated on Thu Jul 14 2022 14:36:16 by
