add need_erase for flash_nrf5x. Only uf2 erase when flush, dfu serial (uart and cdc) will prepare erase in advance.
This commit is contained in:
parent
51411ff85d
commit
cb1ae6d947
@ -433,7 +433,7 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flash_nrf5x_write(DFU_BANK_0_REGION_START+m_data_received, p_data, data_length);
|
flash_nrf5x_write(DFU_BANK_0_REGION_START + m_data_received, p_data, data_length, false);
|
||||||
pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length);
|
pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( !is_ota() ) flash_nrf5x_flush();
|
if ( !is_ota() ) flash_nrf5x_flush(false);
|
||||||
|
|
||||||
// The entire image has been received. Return NRF_SUCCESS.
|
// The entire image has been received. Return NRF_SUCCESS.
|
||||||
err_code = NRF_SUCCESS;
|
err_code = NRF_SUCCESS;
|
||||||
|
@ -45,33 +45,31 @@
|
|||||||
static uint32_t _fl_addr = FLASH_CACHE_INVALID_ADDR;
|
static uint32_t _fl_addr = FLASH_CACHE_INVALID_ADDR;
|
||||||
static uint8_t _fl_buf[FLASH_PAGE_SIZE] __attribute__((aligned(4)));
|
static uint8_t _fl_buf[FLASH_PAGE_SIZE] __attribute__((aligned(4)));
|
||||||
|
|
||||||
void flash_nrf5x_flush(void)
|
void flash_nrf5x_flush (bool need_erase)
|
||||||
{
|
{
|
||||||
if ( _fl_addr == FLASH_CACHE_INVALID_ADDR ) return;
|
if ( _fl_addr == FLASH_CACHE_INVALID_ADDR ) return;
|
||||||
|
|
||||||
if ( memcmp(_fl_buf, (void *) _fl_addr, FLASH_PAGE_SIZE) != 0 )
|
if ( memcmp(_fl_buf, (void *) _fl_addr, FLASH_PAGE_SIZE) != 0 )
|
||||||
{
|
{
|
||||||
#ifdef NRF52840_XXAA
|
|
||||||
// - nRF52832 dfu via uart can miss incoming byte when erasing because cpu is blocked for > 2ms.
|
// - nRF52832 dfu via uart can miss incoming byte when erasing because cpu is blocked for > 2ms.
|
||||||
// Since dfu_prepare_func_app_erase() already erase the page for us, we can skip it here.
|
// Since dfu_prepare_func_app_erase() already erase the page for us, we can skip it here.
|
||||||
//
|
|
||||||
// - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems. Note MSC uf2
|
// - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems. Note MSC uf2
|
||||||
// does not erase page in advance like dfu serial
|
// does not erase page in advance like dfu serial
|
||||||
nrf_nvmc_page_erase(_fl_addr);
|
if ( need_erase ) nrf_nvmc_page_erase(_fl_addr);
|
||||||
#endif
|
|
||||||
nrf_nvmc_write_words(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4);
|
nrf_nvmc_write_words(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fl_addr = FLASH_CACHE_INVALID_ADDR;
|
_fl_addr = FLASH_CACHE_INVALID_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flash_nrf5x_write (uint32_t dst, void const *src, int len)
|
void flash_nrf5x_write (uint32_t dst, void const *src, int len, bool need_erase)
|
||||||
{
|
{
|
||||||
uint32_t newAddr = dst & ~(FLASH_PAGE_SIZE - 1);
|
uint32_t newAddr = dst & ~(FLASH_PAGE_SIZE - 1);
|
||||||
|
|
||||||
if ( newAddr != _fl_addr )
|
if ( newAddr != _fl_addr )
|
||||||
{
|
{
|
||||||
flash_nrf5x_flush();
|
flash_nrf5x_flush(need_erase);
|
||||||
_fl_addr = newAddr;
|
_fl_addr = newAddr;
|
||||||
memcpy(_fl_buf, (void *) newAddr, FLASH_PAGE_SIZE);
|
memcpy(_fl_buf, (void *) newAddr, FLASH_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//void flash_erase(uint32_t page_addr);
|
void flash_nrf5x_write (uint32_t dst, void const *src, int len, bool need_erase);
|
||||||
void flash_nrf5x_write (uint32_t dst, void const *src, int len);
|
void flash_nrf5x_flush (bool need_erase);
|
||||||
void flash_nrf5x_flush(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -170,8 +170,12 @@ int main(void)
|
|||||||
// When updating SoftDevice, bootloader will reset before swapping SD
|
// When updating SoftDevice, bootloader will reset before swapping SD
|
||||||
if (bootloader_dfu_sd_in_progress())
|
if (bootloader_dfu_sd_in_progress())
|
||||||
{
|
{
|
||||||
|
led_blink_fast(true);
|
||||||
|
|
||||||
APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() );
|
APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() );
|
||||||
APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() );
|
APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() );
|
||||||
|
|
||||||
|
led_blink_fast(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/
|
/*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/
|
||||||
|
@ -51,8 +51,8 @@ typedef struct {
|
|||||||
STATIC_ASSERT(sizeof(DirEntry) == 32);
|
STATIC_ASSERT(sizeof(DirEntry) == 32);
|
||||||
|
|
||||||
struct TextFile {
|
struct TextFile {
|
||||||
const char name[11];
|
char const name[11];
|
||||||
const char *content;
|
char const *content;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_FAT_BLOCKS UF2_NUM_BLOCKS
|
#define NUM_FAT_BLOCKS UF2_NUM_BLOCKS
|
||||||
@ -76,7 +76,7 @@ const char indexFile[] = //
|
|||||||
"</body>"
|
"</body>"
|
||||||
"</html>\n";
|
"</html>\n";
|
||||||
|
|
||||||
static const struct TextFile info[] = {
|
static struct TextFile const info[] = {
|
||||||
{.name = "INFO_UF2TXT", .content = infoUf2File},
|
{.name = "INFO_UF2TXT", .content = infoUf2File},
|
||||||
{.name = "INDEX HTM", .content = indexFile},
|
{.name = "INDEX HTM", .content = indexFile},
|
||||||
{.name = "CURRENT UF2"},
|
{.name = "CURRENT UF2"},
|
||||||
@ -97,7 +97,7 @@ static const struct TextFile info[] = {
|
|||||||
#define START_ROOTDIR (START_FAT1 + SECTORS_PER_FAT)
|
#define START_ROOTDIR (START_FAT1 + SECTORS_PER_FAT)
|
||||||
#define START_CLUSTERS (START_ROOTDIR + ROOT_DIR_SECTORS)
|
#define START_CLUSTERS (START_ROOTDIR + ROOT_DIR_SECTORS)
|
||||||
|
|
||||||
static const FAT_BootBlock BootBlock = {
|
static FAT_BootBlock const BootBlock = {
|
||||||
.JumpInstruction = {0xeb, 0x3c, 0x90},
|
.JumpInstruction = {0xeb, 0x3c, 0x90},
|
||||||
.OEMInfo = "UF2 UF2 ",
|
.OEMInfo = "UF2 UF2 ",
|
||||||
.SectorSize = 512,
|
.SectorSize = 512,
|
||||||
@ -133,7 +133,7 @@ static uint32_t get_flash_size(void)
|
|||||||
flash_sz = 256;
|
flash_sz = 256;
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
const bootloader_settings_t * boot_setting;
|
bootloader_settings_t const * boot_setting;
|
||||||
bootloader_util_settings_get(&boot_setting);
|
bootloader_util_settings_get(&boot_setting);
|
||||||
|
|
||||||
// if bank0 size is not valid, happens when flashed with jlink
|
// if bank0 size is not valid, happens when flashed with jlink
|
||||||
@ -150,7 +150,8 @@ static uint32_t get_flash_size(void)
|
|||||||
return flash_sz;
|
return flash_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void padded_memcpy(char *dst, const char *src, int len) {
|
void padded_memcpy (char *dst, char const *src, int len)
|
||||||
|
{
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
if (*src)
|
if (*src)
|
||||||
*dst = *src++;
|
*dst = *src++;
|
||||||
@ -193,11 +194,11 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
|||||||
sectionIdx -= START_ROOTDIR;
|
sectionIdx -= START_ROOTDIR;
|
||||||
if (sectionIdx == 0) {
|
if (sectionIdx == 0) {
|
||||||
DirEntry *d = (void *)data;
|
DirEntry *d = (void *)data;
|
||||||
padded_memcpy(d->name, (const char *)BootBlock.VolumeLabel, 11);
|
padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11);
|
||||||
d->attrs = 0x28;
|
d->attrs = 0x28;
|
||||||
for (int i = 0; i < NUM_INFO; ++i) {
|
for (int i = 0; i < NUM_INFO; ++i) {
|
||||||
d++;
|
d++;
|
||||||
const struct TextFile *inf = &info[i];
|
struct TextFile const *inf = &info[i];
|
||||||
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
|
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
|
||||||
d->startCluster = i + 2;
|
d->startCluster = i + 2;
|
||||||
padded_memcpy(d->name, inf->name, 11);
|
padded_memcpy(d->name, inf->name, 11);
|
||||||
@ -287,7 +288,7 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *stat
|
|||||||
led_blink_fast(true);
|
led_blink_fast(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
flash_nrf5x_write(bl->targetAddr, bl->data, bl->payloadSize);
|
flash_nrf5x_write(bl->targetAddr, bl->data, bl->payloadSize, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state && bl->numBlocks) {
|
if (state && bl->numBlocks) {
|
||||||
@ -307,7 +308,7 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *stat
|
|||||||
}
|
}
|
||||||
if (state->numWritten >= state->numBlocks) {
|
if (state->numWritten >= state->numBlocks) {
|
||||||
// flush last blocks
|
// flush last blocks
|
||||||
flash_nrf5x_flush();
|
flash_nrf5x_flush(true);
|
||||||
|
|
||||||
uf2_write_complete(state->numBlocks);
|
uf2_write_complete(state->numBlocks);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user