stm32/boards/LEGO_HUB_NO6: Implement robust filesystem-load updates.
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
d84ebc31f7
commit
87ca431f3f
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Damien P. George
|
||||
* Copyright (c) 2021-2022 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -75,6 +75,7 @@ void board_init(void) {
|
|||
|
||||
#if BUILDING_MBOOT
|
||||
|
||||
#include "drivers/memory/spiflash.h"
|
||||
#include "mboot/mboot.h"
|
||||
#include "boardctrl.h"
|
||||
#include "adc.h"
|
||||
|
@ -88,6 +89,14 @@ void board_init(void) {
|
|||
#define PATTERN_N (0x01296ad2)
|
||||
#define PATTERN_S (0x0064104c)
|
||||
|
||||
// Location and value for the SPI flash update key. If this key exists at the defined
|
||||
// location then mboot will attempt to do a filesystem-load update of the main firmware.
|
||||
// This makes the update robust to power failures: if the update does not complete then
|
||||
// it will be restarted the next time it powers up. Only when it fully completes will
|
||||
// this key be erased, and then the application can run.
|
||||
#define SPIFLASH_UPDATE_KEY_ADDR (1020 * 1024)
|
||||
#define SPIFLASH_UPDATE_KEY_VALUE (0x12345678)
|
||||
|
||||
static void board_led_pattern(int reset_mode, uint16_t brightness) {
|
||||
static const uint32_t pixels[] = {
|
||||
0,
|
||||
|
@ -162,9 +171,36 @@ int board_mboot_get_reset_mode(uint32_t *initial_r0) {
|
|||
mp_hal_delay_ms(50);
|
||||
}
|
||||
mp_hal_delay_ms(300);
|
||||
} else {
|
||||
// Button not pressed, check flash for update key and start an update if the key exists.
|
||||
|
||||
// Initialise the external SPI flash.
|
||||
MBOOT_SPIFLASH_SPIFLASH->config = MBOOT_SPIFLASH_CONFIG;
|
||||
mp_spiflash_init(MBOOT_SPIFLASH_SPIFLASH);
|
||||
|
||||
// Read in the key.
|
||||
uint32_t buf;
|
||||
mp_spiflash_read(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR, 4, (uint8_t *)&buf);
|
||||
|
||||
if (buf == SPIFLASH_UPDATE_KEY_VALUE) {
|
||||
// The key has the correct value, so read in the FS-load elements and enter the bootloader.
|
||||
mp_spiflash_read(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR + 4, ELEM_DATA_SIZE, ELEM_DATA_START);
|
||||
*initial_r0 = MBOOT_INITIAL_R0_KEY_FSLOAD;
|
||||
reset_mode = BOARDCTRL_RESET_MODE_BOOTLOADER;
|
||||
}
|
||||
}
|
||||
board_led_pattern(0, 0);
|
||||
return reset_mode;
|
||||
}
|
||||
|
||||
void board_mboot_state_change(int state, uint32_t arg) {
|
||||
if (state == MBOOT_STATE_FSLOAD_END) {
|
||||
// The FS-load update completed (either with success or failure), so erase the
|
||||
// update key and write the result of the FS-load operation into flash.
|
||||
mp_spiflash_erase_block(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR);
|
||||
mp_spiflash_write(MBOOT_SPIFLASH_SPIFLASH, SPIFLASH_UPDATE_KEY_ADDR + 4, 4, (const uint8_t *)&arg);
|
||||
}
|
||||
mboot_state_change_default(state, arg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -153,6 +153,7 @@
|
|||
#define MBOOT_BOARD_EARLY_INIT(initial_r0) board_init()
|
||||
#define MBOOT_BOARD_CLEANUP board_mboot_cleanup
|
||||
#define MBOOT_BOARD_GET_RESET_MODE board_mboot_get_reset_mode
|
||||
#define MBOOT_BOARD_STATE_CHANGE board_mboot_state_change
|
||||
|
||||
/******************************************************************************/
|
||||
// Function declarations
|
||||
|
@ -167,4 +168,5 @@ void board_mboot_cleanup(int reset_mode);
|
|||
void board_mboot_led_init(void);
|
||||
void board_mboot_led_state(int led, int state);
|
||||
int board_mboot_get_reset_mode(uint32_t *initial_r0);
|
||||
void board_mboot_state_change(int state, uint32_t arg);
|
||||
void *btstack_chipset_cc256x_instance(void);
|
||||
|
|
Loading…
Reference in New Issue