mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: drivers/FlashIAP.cpp
- Revision:
- 189:f392fc9709a3
- Parent:
- 188:bcfe06ba3d64
--- a/drivers/FlashIAP.cpp Thu Nov 08 11:46:34 2018 +0000 +++ b/drivers/FlashIAP.cpp Wed Feb 20 22:31:08 2019 +0000 @@ -25,12 +25,16 @@ #include <algorithm> #include "FlashIAP.h" #include "platform/mbed_assert.h" +#include "platform/ScopedRamExecutionLock.h" +#include "platform/ScopedRomWriteLock.h" -#ifdef DEVICE_FLASH +#if DEVICE_FLASH namespace mbed { +const unsigned int num_write_retries = 16; + SingletonPtr<PlatformMutex> FlashIAP::_mutex; static inline bool is_aligned(uint32_t number, uint32_t alignment) @@ -56,8 +60,12 @@ { int ret = 0; _mutex->lock(); - if (flash_init(&_flash)) { - ret = -1; + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + if (flash_init(&_flash)) { + ret = -1; + } } uint32_t page_size = get_page_size(); _page_buf = new uint8_t[page_size]; @@ -70,8 +78,12 @@ { int ret = 0; _mutex->lock(); - if (flash_free(&_flash)) { - ret = -1; + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + if (flash_free(&_flash)) { + ret = -1; + } } delete[] _page_buf; _mutex->unlock(); @@ -83,7 +95,11 @@ { int32_t ret = -1; _mutex->lock(); - ret = flash_read(&_flash, addr, (uint8_t *) buffer, size); + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + ret = flash_read(&_flash, addr, (uint8_t *) buffer, size); + } _mutex->unlock(); return ret; } @@ -105,7 +121,7 @@ int ret = 0; _mutex->lock(); - while (size) { + while (size && !ret) { uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); bool unaligned_src = (((size_t) buf / sizeof(uint32_t) * sizeof(uint32_t)) != (size_t) buf); chunk = std::min(current_sector_size - (addr % current_sector_size), size); @@ -126,9 +142,19 @@ prog_buf = buf; prog_size = chunk; } - if (flash_program_page(&_flash, addr, prog_buf, prog_size)) { - ret = -1; - break; + { + // Few boards may fail the write actions due to HW limitations (like critical drivers that + // disable flash operations). Just retry a few times until success. + for (unsigned int retry = 0; retry < num_write_retries; retry++) { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + ret = flash_program_page(&_flash, addr, prog_buf, prog_size); + if (ret) { + ret = -1; + } else { + break; + } + } } size -= chunk; addr += chunk; @@ -169,11 +195,18 @@ int32_t ret = 0; _mutex->lock(); - while (size) { - ret = flash_erase_sector(&_flash, addr); - if (ret != 0) { - ret = -1; - break; + while (size && !ret) { + // Few boards may fail the erase actions due to HW limitations (like critical drivers that + // disable flash operations). Just retry a few times until success. + for (unsigned int retry = 0; retry < num_write_retries; retry++) { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + ret = flash_erase_sector(&_flash, addr); + if (ret) { + ret = -1; + } else { + break; + } } current_sector_size = flash_get_sector_size(&_flash, addr); size -= current_sector_size; @@ -203,6 +236,11 @@ return flash_get_size(&_flash); } +uint8_t FlashIAP::get_erase_value() const +{ + return flash_get_erase_value(&_flash); +} + } #endif