Merge pull request #9548 from davidsaada/david_flashiap_retries

FlashIAP driver: Add retries to erase and program operations.
pull/9682/head
Cruz Monrreal 2019-01-30 17:32:19 -06:00 committed by GitHub
commit 87e57d3ced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 34 deletions

View File

@ -33,6 +33,8 @@
namespace mbed {
const unsigned int num_write_retries = 16;
SingletonPtr<PlatformMutex> FlashIAP::_mutex;
static inline bool is_aligned(uint32_t number, uint32_t alignment)
@ -119,7 +121,7 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
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);
@ -141,11 +143,17 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
prog_size = chunk;
}
{
ScopedRamExecutionLock make_ram_executable;
ScopedRomWriteLock make_rom_writable;
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;
@ -187,15 +195,18 @@ int FlashIAP::erase(uint32_t addr, uint32_t size)
int32_t ret = 0;
_mutex->lock();
while (size) {
{
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 != 0) {
ret = -1;
break;
if (ret) {
ret = -1;
} else {
break;
}
}
current_sector_size = flash_get_sector_size(&_flash, addr);
size -= current_sector_size;

View File

@ -72,8 +72,6 @@ typedef struct {
static const uint32_t min_area_size = 4096;
static const uint32_t max_data_size = 4096;
static const int num_write_retries = 16;
static const uint8_t blank_flash_val = 0xFF;
typedef enum {
@ -234,31 +232,13 @@ int NVStore::flash_read_area(uint8_t area, uint32_t offset, uint32_t size, void
int NVStore::flash_write_area(uint8_t area, uint32_t offset, uint32_t size, const void *buf)
{
int ret;
// On some boards, write action can fail due to HW limitations (like critical drivers
// that disable all other actions). Just retry a few times until success.
for (int i = 0; i < num_write_retries; i++) {
ret = _flash->program(buf, _flash_area_params[area].address + offset, size);
if (!ret) {
return ret;
}
wait_ms(1);
}
int ret = _flash->program(buf, _flash_area_params[area].address + offset, size);
return ret;
}
int NVStore::flash_erase_area(uint8_t area)
{
int ret;
// On some boards, write action can fail due to HW limitations (like critical drivers
// that disable all other actions). Just retry a few times until success.
for (int i = 0; i < num_write_retries; i++) {
ret = _flash->erase(_flash_area_params[area].address, _flash_area_params[area].size);
if (!ret) {
return ret;
}
wait_ms(1);
}
int ret = _flash->erase(_flash_area_params[area].address, _flash_area_params[area].size);
return ret;
}