3333
3434namespace mbed {
3535
36+ const unsigned int num_write_retries = 16 ;
37+
3638SingletonPtr<PlatformMutex> FlashIAP::_mutex;
3739
3840static 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;
0 commit comments