mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9548 from davidsaada/david_flashiap_retries
FlashIAP driver: Add retries to erase and program operations.pull/9682/head
commit
87e57d3ced
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue