Skip to content

Commit 481b6fb

Browse files
Cruz MonrrealCruz Monrreal II
authored andcommitted
Merge pull request #9548 from davidsaada/david_flashiap_retries
FlashIAP driver: Add retries to erase and program operations.
1 parent 3f5c4de commit 481b6fb

File tree

2 files changed

+25
-34
lines changed

2 files changed

+25
-34
lines changed

drivers/FlashIAP.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
namespace mbed {
3535

36+
const unsigned int num_write_retries = 16;
37+
3638
SingletonPtr<PlatformMutex> FlashIAP::_mutex;
3739

3840
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)
119121

120122
int ret = 0;
121123
_mutex->lock();
122-
while (size) {
124+
while (size && !ret) {
123125
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
124126
bool unaligned_src = (((size_t) buf / sizeof(uint32_t) * sizeof(uint32_t)) != (size_t) buf);
125127
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)
141143
prog_size = chunk;
142144
}
143145
{
144-
ScopedRamExecutionLock make_ram_executable;
145-
ScopedRomWriteLock make_rom_writable;
146-
if (flash_program_page(&_flash, addr, prog_buf, prog_size)) {
147-
ret = -1;
148-
break;
146+
// Few boards may fail the write actions due to HW limitations (like critical drivers that
147+
// disable flash operations). Just retry a few times until success.
148+
for (unsigned int retry = 0; retry < num_write_retries; retry++) {
149+
ScopedRamExecutionLock make_ram_executable;
150+
ScopedRomWriteLock make_rom_writable;
151+
ret = flash_program_page(&_flash, addr, prog_buf, prog_size);
152+
if (ret) {
153+
ret = -1;
154+
} else {
155+
break;
156+
}
149157
}
150158
}
151159
size -= chunk;
@@ -187,15 +195,18 @@ int FlashIAP::erase(uint32_t addr, uint32_t size)
187195

188196
int32_t ret = 0;
189197
_mutex->lock();
190-
while (size) {
191-
{
198+
while (size && !ret) {
199+
// Few boards may fail the erase actions due to HW limitations (like critical drivers that
200+
// disable flash operations). Just retry a few times until success.
201+
for (unsigned int retry = 0; retry < num_write_retries; retry++) {
192202
ScopedRamExecutionLock make_ram_executable;
193203
ScopedRomWriteLock make_rom_writable;
194204
ret = flash_erase_sector(&_flash, addr);
195-
}
196-
if (ret != 0) {
197-
ret = -1;
198-
break;
205+
if (ret) {
206+
ret = -1;
207+
} else {
208+
break;
209+
}
199210
}
200211
current_sector_size = flash_get_sector_size(&_flash, addr);
201212
size -= current_sector_size;

features/storage/nvstore/source/nvstore.cpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ typedef struct {
7272
static const uint32_t min_area_size = 4096;
7373
static const uint32_t max_data_size = 4096;
7474

75-
static const int num_write_retries = 16;
76-
7775
static const uint8_t blank_flash_val = 0xFF;
7876

7977
typedef enum {
@@ -234,31 +232,13 @@ int NVStore::flash_read_area(uint8_t area, uint32_t offset, uint32_t size, void
234232

235233
int NVStore::flash_write_area(uint8_t area, uint32_t offset, uint32_t size, const void *buf)
236234
{
237-
int ret;
238-
// On some boards, write action can fail due to HW limitations (like critical drivers
239-
// that disable all other actions). Just retry a few times until success.
240-
for (int i = 0; i < num_write_retries; i++) {
241-
ret = _flash->program(buf, _flash_area_params[area].address + offset, size);
242-
if (!ret) {
243-
return ret;
244-
}
245-
wait_ms(1);
246-
}
235+
int ret = _flash->program(buf, _flash_area_params[area].address + offset, size);
247236
return ret;
248237
}
249238

250239
int NVStore::flash_erase_area(uint8_t area)
251240
{
252-
int ret;
253-
// On some boards, write action can fail due to HW limitations (like critical drivers
254-
// that disable all other actions). Just retry a few times until success.
255-
for (int i = 0; i < num_write_retries; i++) {
256-
ret = _flash->erase(_flash_area_params[area].address, _flash_area_params[area].size);
257-
if (!ret) {
258-
return ret;
259-
}
260-
wait_ms(1);
261-
}
241+
int ret = _flash->erase(_flash_area_params[area].address, _flash_area_params[area].size);
262242
return ret;
263243
}
264244

0 commit comments

Comments
 (0)