Skip to content

Commit 02cb4a6

Browse files
committed
espressif: add forced aligned flash erase
Signed-off-by: Almir Okato <[email protected]>
1 parent 4fd4c98 commit 02cb4a6

File tree

1 file changed

+83
-11
lines changed

1 file changed

+83
-11
lines changed

boot/espressif/port/esp_mcuboot.c

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,73 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
277277
return true;
278278
}
279279

280+
static bool aligned_flash_erase(size_t addr, size_t size)
281+
{
282+
if (IS_ALIGNED(addr, FLASH_SECTOR_SIZE) && IS_ALIGNED(size, FLASH_SECTOR_SIZE)) {
283+
/* A single write operation is enough when all parameters are aligned */
284+
285+
return bootloader_flash_erase_range(addr, size) == ESP_OK;
286+
}
287+
288+
const uint32_t aligned_addr = ALIGN_DOWN(addr, FLASH_SECTOR_SIZE);
289+
const uint32_t addr_offset = ALIGN_OFFSET(addr, FLASH_SECTOR_SIZE);
290+
uint32_t bytes_remaining = size;
291+
uint8_t write_data[FLASH_SECTOR_SIZE] = {0};
292+
293+
/* Perform a read operation considering an offset not aligned to 4-byte boundary */
294+
295+
uint32_t bytes = MIN(bytes_remaining + addr_offset, sizeof(write_data));
296+
297+
if (bootloader_flash_read(aligned_addr, write_data, ALIGN_UP(bytes, FLASH_SECTOR_SIZE), true) != ESP_OK) {
298+
return false;
299+
}
300+
301+
302+
if (bootloader_flash_erase_range(aligned_addr, ALIGN_UP(bytes, FLASH_SECTOR_SIZE)) != ESP_OK) {
303+
BOOT_LOG_ERR("%s: Flash erase failed", __func__);
304+
return -1;
305+
}
306+
307+
uint32_t bytes_written = bytes - addr_offset;
308+
309+
/* Write first part of non-erased data */
310+
if(addr_offset > 0) {
311+
aligned_flash_write(aligned_addr, write_data, addr_offset);
312+
}
313+
314+
if(bytes < sizeof(write_data)) {
315+
aligned_flash_write(aligned_addr + bytes, write_data + bytes, sizeof(write_data) - bytes);
316+
}
317+
318+
bytes_remaining -= bytes_written;
319+
320+
/* Write remaining data to Flash if any */
321+
322+
uint32_t offset = bytes;
323+
324+
while (bytes_remaining != 0) {
325+
bytes = MIN(bytes_remaining, sizeof(write_data));
326+
if (bootloader_flash_read(aligned_addr + offset, write_data, ALIGN_UP(bytes, FLASH_SECTOR_SIZE), true) != ESP_OK) {
327+
return false;
328+
}
329+
330+
if (bootloader_flash_erase_range(aligned_addr + offset, ALIGN_UP(bytes, FLASH_SECTOR_SIZE)) != ESP_OK) {
331+
BOOT_LOG_ERR("%s: Flash erase failed", __func__);
332+
return -1;
333+
}
334+
335+
if(bytes < sizeof(write_data)) {
336+
aligned_flash_write(aligned_addr + offset + bytes, write_data + bytes, sizeof(write_data) - bytes);
337+
}
338+
339+
offset += bytes;
340+
bytes_written += bytes;
341+
bytes_remaining -= bytes;
342+
}
343+
344+
return true;
345+
}
346+
280347
int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
281348
uint32_t len)
282349
{
@@ -293,8 +360,8 @@ int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
293360
const uint32_t start_addr = fa->fa_off + off;
294361
BOOT_LOG_DBG("%s: Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
295362

296-
bool success = aligned_flash_write(start_addr, src, len);
297-
if (!success) {
363+
364+
if (!aligned_flash_write(start_addr, src, len)) {
298365
BOOT_LOG_ERR("%s: Flash write failed", __func__);
299366
return -1;
300367
}
@@ -308,19 +375,24 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
308375
return -1;
309376
}
310377

378+
const uint32_t start_addr = fa->fa_off + off;
379+
311380
if ((len % FLASH_SECTOR_SIZE) != 0 || (off % FLASH_SECTOR_SIZE) != 0) {
312-
BOOT_LOG_ERR("%s: Not aligned on sector Offset: 0x%x Length: 0x%x",
313-
__func__, (int)off, (int)len);
314-
return -1;
315-
}
381+
BOOT_LOG_DBG("%s: Not aligned on sector Offset: 0x%x Length: 0x%x",
382+
__func__, (int)start_addr, (int)len);
316383

317-
const uint32_t start_addr = fa->fa_off + off;
318-
BOOT_LOG_DBG("%s: Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
384+
if(!aligned_flash_erase(start_addr, len)) {
385+
return -1;
386+
}
387+
} else {
388+
BOOT_LOG_DBG("%s: Aligned Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
319389

320-
if (bootloader_flash_erase_range(start_addr, len) != ESP_OK) {
321-
BOOT_LOG_ERR("%s: Flash erase failed", __func__);
322-
return -1;
390+
if (bootloader_flash_erase_range(start_addr, len) != ESP_OK) {
391+
BOOT_LOG_ERR("%s: Flash erase failed", __func__);
392+
return -1;
393+
}
323394
}
395+
324396
#if VALIDATE_PROGRAM_OP
325397
for (size_t i = 0; i < len; i++) {
326398
uint8_t *val = (void *)(start_addr + i);

0 commit comments

Comments
 (0)