stm32/boards/LEGO_HUB_NO6: Implement robust filesystem-load updates.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2022-06-02 13:43:46 +10:00
parent d84ebc31f7
commit 87ca431f3f
2 changed files with 39 additions and 1 deletions

View File

@ -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

View File

@ -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);