33
33
34
34
namespace mbed {
35
35
36
+ const unsigned int num_write_retries = 16 ;
37
+
36
38
SingletonPtr<PlatformMutex> FlashIAP::_mutex;
37
39
38
40
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)
119
121
120
122
int ret = 0 ;
121
123
_mutex->lock ();
122
- while (size) {
124
+ while (size && !ret ) {
123
125
uint32_t current_sector_size = flash_get_sector_size (&_flash, addr);
124
126
bool unaligned_src = (((size_t ) buf / sizeof (uint32_t ) * sizeof (uint32_t )) != (size_t ) buf);
125
127
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)
141
143
prog_size = chunk;
142
144
}
143
145
{
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
+ }
149
157
}
150
158
}
151
159
size -= chunk;
@@ -187,15 +195,18 @@ int FlashIAP::erase(uint32_t addr, uint32_t size)
187
195
188
196
int32_t ret = 0 ;
189
197
_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++) {
192
202
ScopedRamExecutionLock make_ram_executable;
193
203
ScopedRomWriteLock make_rom_writable;
194
204
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
+ }
199
210
}
200
211
current_sector_size = flash_get_sector_size (&_flash, addr);
201
212
size -= current_sector_size;
0 commit comments