feat(core): use flash bursts for faster flashing

[no changelog]
pull/3621/head
tychovrahe 3 months ago committed by TychoVrahe
parent e1161866da
commit 70a673fabc

@ -227,12 +227,9 @@ static secbool copy_sdcard(void) {
// copy bootloader from SD card to Flash // copy bootloader from SD card to Flash
term_printf("copying new bootloader from SD card\n\n"); term_printf("copying new bootloader from SD card\n\n");
for (int j = 0; j < (IMAGE_HEADER_SIZE + codelen) / for (int j = 0; j < (IMAGE_HEADER_SIZE + codelen) / FLASH_BURST_SIZE; j++) {
(FLASH_BURST_LENGTH * sizeof(uint32_t)); ensure(flash_area_write_burst(&BOOTLOADER_AREA, j * FLASH_BURST_SIZE,
j++) { &sdcard_buf[j * FLASH_BURST_WORDS]),
ensure(flash_area_write_burst(&BOOTLOADER_AREA,
j * FLASH_BURST_LENGTH * sizeof(uint32_t),
&sdcard_buf[j * FLASH_BURST_LENGTH]),
NULL); NULL);
} }

@ -730,7 +730,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
// offset into the FIRMWARE_AREA part of the flash // offset into the FIRMWARE_AREA part of the flash
uint32_t write_offset = firmware_block * IMAGE_CHUNK_SIZE; uint32_t write_offset = firmware_block * IMAGE_CHUNK_SIZE;
ensure((chunk_size % FLASH_BLOCK_SIZE == 0) * sectrue, NULL); ensure((chunk_size % FLASH_BURST_SIZE == 0) * sectrue, NULL);
while (bytes_remaining > 0) { while (bytes_remaining > 0) {
// erase flash before writing // erase flash before writing
@ -754,9 +754,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
ensure(flash_unlock_write(), NULL); ensure(flash_unlock_write(), NULL);
while (write_offset < write_end) { while (write_offset < write_end) {
// write a block to the flash // write a block to the flash
ensure(flash_area_write_block(&FIRMWARE_AREA, write_offset, src), NULL); ensure(flash_area_write_burst(&FIRMWARE_AREA, write_offset, src), NULL);
write_offset += FLASH_BLOCK_SIZE; write_offset += FLASH_BURST_SIZE;
src += FLASH_BLOCK_WORDS; src += FLASH_BURST_WORDS;
} }
ensure(flash_lock_write(), NULL); ensure(flash_lock_write(), NULL);

@ -220,24 +220,24 @@ void check_and_replace_bootloader(void) {
uint32_t last_whole_word_addr = (((uint32_t)decomp.dest) & ~0x7F); uint32_t last_whole_word_addr = (((uint32_t)decomp.dest) & ~0x7F);
while ((uint32_t)p < last_whole_word_addr) { while ((uint32_t)p < last_whole_word_addr) {
ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, p), NULL); ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, p), NULL);
p += FLASH_BURST_LENGTH; p += FLASH_BURST_WORDS;
offset += FLASH_BURST_LENGTH * sizeof(uint32_t); offset += FLASH_BURST_WORDS * sizeof(uint32_t);
} }
if ((uint8_t *)p < decomp.dest) { if ((uint8_t *)p < decomp.dest) {
// last few bytes in case of unaligned data // last few bytes in case of unaligned data
uint32_t d[FLASH_BURST_LENGTH] = {0}; uint32_t d[FLASH_BURST_WORDS] = {0};
memcpy(&d, p, (uint32_t)decomp.dest - (uint32_t)p); memcpy(&d, p, (uint32_t)decomp.dest - (uint32_t)p);
ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, d), NULL); ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, d), NULL);
offset += FLASH_BURST_LENGTH * sizeof(uint32_t); offset += FLASH_BURST_WORDS * sizeof(uint32_t);
} }
decomp.dest = (uint8_t *)decomp_out; decomp.dest = (uint8_t *)decomp_out;
} while (uzlib_uncompress(&decomp) >= 0); } while (uzlib_uncompress(&decomp) >= 0);
uint32_t d[FLASH_BURST_LENGTH] = {0}; uint32_t d[FLASH_BURST_WORDS] = {0};
// fill the rest of the bootloader area with 0x00 // fill the rest of the bootloader area with 0x00
while (offset < bl_len) { while (offset < bl_len) {
ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, d), NULL); ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, d), NULL);
offset += FLASH_BURST_LENGTH * sizeof(uint32_t); offset += FLASH_BURST_WORDS * sizeof(uint32_t);
} }
ensure(flash_lock_write(), NULL); ensure(flash_lock_write(), NULL);

@ -28,7 +28,8 @@
#include "flash_ll.h" #include "flash_ll.h"
#define FLASH_BURST_LENGTH (4 * 8) #define FLASH_BURST_WORDS (4 * 8)
#define FLASH_BURST_SIZE (FLASH_BURST_WORDS * sizeof(uint32_t))
void flash_init(void); void flash_init(void);

@ -194,6 +194,20 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) {
return sectrue; return sectrue;
} }
secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data) {
if ((offset % FLASH_BURST_SIZE) != 0) {
return secfalse;
}
for (int i = 0; i < FLASH_BURST_WORDS; i++) {
if (sectrue !=
flash_write_word(sector, offset + i * sizeof(uint32_t), data[i])) {
return secfalse;
}
}
return sectrue;
}
secbool flash_write_block(uint16_t sector, uint32_t offset, secbool flash_write_block(uint16_t sector, uint32_t offset,
const flash_block_t block) { const flash_block_t block) {
return flash_write_word(sector, offset, block[0]); return flash_write_word(sector, offset, block[0]);

@ -171,23 +171,22 @@ secbool flash_write_quadword(uint16_t sector, uint32_t offset,
secbool flash_write_burst(uint16_t sector, uint32_t offset, secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data) { const uint32_t *data) {
uint32_t address = uint32_t address =
(uint32_t)flash_get_address(sector, offset, 8 * 4 * sizeof(uint32_t)); (uint32_t)flash_get_address(sector, offset, FLASH_BURST_SIZE);
if (address == 0) { if (address == 0) {
return secfalse; return secfalse;
} }
if (offset % if (offset % FLASH_BURST_SIZE) {
(8 * 4 * sizeof(uint32_t))) { // we write only at 16-byte boundary
return secfalse; return secfalse;
} }
for (int i = 0; i < 8 * 4; i++) { for (int i = 0; i < FLASH_BURST_WORDS; i++) {
if (data[i] != (data[i] & *((const uint32_t *)address + i))) { if (data[i] != (data[i] & *((const uint32_t *)address + i))) {
return secfalse; return secfalse;
} }
} }
secbool all_match = sectrue; secbool all_match = sectrue;
for (int i = 0; i < 8 * 4; i++) { for (int i = 0; i < FLASH_BURST_WORDS; i++) {
if (data[i] != *((const uint32_t *)address + i)) { if (data[i] != *((const uint32_t *)address + i)) {
all_match = secfalse; all_match = secfalse;
break; break;
@ -202,7 +201,7 @@ secbool flash_write_burst(uint16_t sector, uint32_t offset,
return secfalse; return secfalse;
} }
for (int i = 0; i < 8 * 4; i++) { for (int i = 0; i < FLASH_BURST_WORDS; i++) {
if (data[i] != *((const uint32_t *)address + i)) { if (data[i] != *((const uint32_t *)address + i)) {
return secfalse; return secfalse;
} }

@ -228,6 +228,20 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) {
return sectrue; return sectrue;
} }
secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data) {
if ((offset % FLASH_BURST_SIZE) != 0) {
return secfalse;
}
for (int i = 0; i < FLASH_BURST_WORDS; i++) {
if (sectrue !=
flash_write_word(sector, offset + i * sizeof(uint32_t), data[i])) {
return secfalse;
}
}
return sectrue;
}
secbool flash_write_block(uint16_t sector, uint32_t offset, secbool flash_write_block(uint16_t sector, uint32_t offset,
const flash_block_t block) { const flash_block_t block) {
if (offset % (sizeof(uint32_t) * if (offset % (sizeof(uint32_t) *

@ -26,6 +26,9 @@
#include "memory.h" #include "memory.h"
#include "supervise.h" #include "supervise.h"
#define FLASH_BURST_WORDS (4 * 8)
#define FLASH_BURST_SIZE (FLASH_BURST_WORDS * sizeof(uint32_t))
#define STORAGE_AREAS_COUNT 2 #define STORAGE_AREAS_COUNT 2
static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = {
@ -158,6 +161,20 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) {
return sectrue; return sectrue;
} }
secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data) {
if ((offset % FLASH_BURST_SIZE) != 0) {
return secfalse;
}
for (int i = 0; i < FLASH_BURST_WORDS; i++) {
if (sectrue !=
flash_write_word(sector, offset + i * sizeof(uint32_t), data[i])) {
return secfalse;
}
}
return sectrue;
}
secbool flash_write_block(uint16_t sector, uint32_t offset, secbool flash_write_block(uint16_t sector, uint32_t offset,
const flash_block_t block) { const flash_block_t block) {
return flash_write_word(sector, offset, block[0]); return flash_write_word(sector, offset, block[0]);

@ -106,20 +106,6 @@ secbool flash_area_write_word(const flash_area_t *area, uint32_t offset,
return flash_write_word(sector, sector_offset, data); return flash_write_word(sector, sector_offset, data);
} }
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data) {
if (offset % (8 * 16) != 0) {
return secfalse;
}
for (int i = 0; i < (8 * 4); i++) {
if (sectrue !=
flash_area_write_word(area, offset + i * sizeof(uint32_t), data[i])) {
return secfalse;
}
}
return sectrue;
}
#else // not defined FLASH_BIT_ACCESS #else // not defined FLASH_BIT_ACCESS
secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset, secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
@ -132,6 +118,8 @@ secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
return flash_write_quadword(sector, sector_offset, data); return flash_write_quadword(sector, sector_offset, data);
} }
#endif // not defined FLASH_BIT_ACCESS
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset, secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data) { const uint32_t *data) {
uint16_t sector; uint16_t sector;
@ -142,8 +130,6 @@ secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
return flash_write_burst(sector, sector_offset, data); return flash_write_burst(sector, sector_offset, data);
} }
#endif // not defined FLASH_BIT_ACCESS
secbool flash_area_write_block(const flash_area_t *area, uint32_t offset, secbool flash_area_write_block(const flash_area_t *area, uint32_t offset,
const flash_block_t block) { const flash_block_t block) {
if (!FLASH_IS_ALIGNED(offset)) { if (!FLASH_IS_ALIGNED(offset)) {

Loading…
Cancel
Save