stm32/mboot: Add support for reading from SD card.

Tested on PYBV10 and PYBD_SF6, with MBOOT_FSLOAD enabled and programming
new firmware from a .dfu.gz file stored on the SD card.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2022-03-17 17:11:44 +11:00
parent 9b07d38c7e
commit e316306546
6 changed files with 57 additions and 0 deletions

View File

@ -110,6 +110,7 @@ SRC_C += \
fsload.c \ fsload.c \
gzstream.c \ gzstream.c \
pack.c \ pack.c \
sdcard.c \
vfs_fat.c \ vfs_fat.c \
vfs_lfs.c \ vfs_lfs.c \
drivers/bus/softspi.c \ drivers/bus/softspi.c \
@ -142,6 +143,7 @@ endif
$(BUILD)/$(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_ll_usb.o: CFLAGS += -Wno-attributes $(BUILD)/$(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_ll_usb.o: CFLAGS += -Wno-attributes
SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal_cortex.c \ hal_cortex.c \
hal_dma.c \
hal_flash.c \ hal_flash.c \
hal_flash_ex.c \ hal_flash_ex.c \
hal_pcd.c \ hal_pcd.c \
@ -151,6 +153,14 @@ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
ll_usb.c \ ll_usb.c \
) )
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7))
SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal_mmc.c \
hal_sd.c \
ll_sdmmc.c \
)
endif
SRC_USBDEV += $(addprefix ports/stm32/$(USBDEV_DIR)/,\ SRC_USBDEV += $(addprefix ports/stm32/$(USBDEV_DIR)/,\
core/src/usbd_core.c \ core/src/usbd_core.c \
core/src/usbd_ctlreq.c \ core/src/usbd_ctlreq.c \

View File

@ -59,6 +59,13 @@ How to use
second one use the same configuration names as above but with second one use the same configuration names as above but with
`SPIFLASH2`, ie `MBOOT_SPIFLASH2_ADDR` etc. `SPIFLASH2`, ie `MBOOT_SPIFLASH2_ADDR` etc.
SD card support (read-only, useful in combination with `MBOOT_FSLOAD`)
can be enabled with the following options:
#define MBOOT_ADDRESS_SPACE_64BIT (1)
#define MBOOT_SDCARD_ADDR (0x100000000ULL)
#define MBOOT_SDCARD_BYTE_SIZE (0x400000000ULL)
To enable loading firmware from a filesystem use: To enable loading firmware from a filesystem use:
#define MBOOT_FSLOAD (1) #define MBOOT_FSLOAD (1)
@ -159,6 +166,11 @@ firmware.dfu.gz stored on the default FAT filesystem:
The 0x80000000 value is the address understood by Mboot as the location of The 0x80000000 value is the address understood by Mboot as the location of
the external SPI flash, configured via `MBOOT_SPIFLASH_ADDR`. the external SPI flash, configured via `MBOOT_SPIFLASH_ADDR`.
To load a file from the SD card (see `MBOOT_SDCARD_ADDR`), assuming it is a
16GiB card, use:
fwupdate.update_mpy('firmware.dfu.gz', 0x1_00000000, 0x4_00000000, addr_64bit=True)
Signed and encrypted DFU support Signed and encrypted DFU support
-------------------------------- --------------------------------

View File

@ -37,6 +37,7 @@
#include "irq.h" #include "irq.h"
#include "mboot.h" #include "mboot.h"
#include "powerctrl.h" #include "powerctrl.h"
#include "sdcard.h"
#include "dfu.h" #include "dfu.h"
#include "pack.h" #include "pack.h"
@ -653,6 +654,16 @@ void hw_read(mboot_addr_t addr, size_t len, uint8_t *buf) {
mp_spiflash_read(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, buf); mp_spiflash_read(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, buf);
} else } else
#endif #endif
#if defined(MBOOT_SDCARD_ADDR)
if (MBOOT_SDCARD_ADDR <= addr && addr < MBOOT_SDCARD_ADDR + MBOOT_SDCARD_BYTE_SIZE) {
// Read address and length must be aligned.
if (addr % SDCARD_BLOCK_SIZE == 0 && len % SDCARD_BLOCK_SIZE == 0) {
sdcard_read_blocks(buf, (addr - MBOOT_SDCARD_ADDR) / SDCARD_BLOCK_SIZE, len / SDCARD_BLOCK_SIZE);
} else {
memset(buf, 0xff, len);
}
} else
#endif
{ {
// Other addresses, just read directly from memory // Other addresses, just read directly from memory
memcpy(buf, (void *)(uintptr_t)addr, len); memcpy(buf, (void *)(uintptr_t)addr, len);
@ -1540,6 +1551,12 @@ enter_bootloader:
mp_spiflash_init(MBOOT_SPIFLASH2_SPIFLASH); mp_spiflash_init(MBOOT_SPIFLASH2_SPIFLASH);
#endif #endif
#if defined(MBOOT_SDCARD_ADDR)
sdcard_init();
sdcard_select_sd();
sdcard_power_on();
#endif
#if MBOOT_ENABLE_PACKING #if MBOOT_ENABLE_PACKING
mboot_pack_init(); mboot_pack_init();
#endif #endif

View File

@ -0,0 +1,13 @@
// Include relevant source files for SD card only when it's needed and
// configured at the C level (in mpconfigboard.h).
#include "py/mpconfig.h"
#if defined(MBOOT_SDCARD_ADDR)
#define MICROPY_HW_DMA_ENABLE_AUTO_TURN_OFF (0)
#include "ports/stm32/dma.c"
#include "ports/stm32/sdcard.c"
#endif

View File

@ -688,6 +688,8 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
// //
// Expose the SD card or MMC as an object with the block protocol. // Expose the SD card or MMC as an object with the block protocol.
#if !BUILDING_MBOOT
// There are singleton SDCard/MMCard objects // There are singleton SDCard/MMCard objects
#if MICROPY_HW_ENABLE_SDCARD #if MICROPY_HW_ENABLE_SDCARD
const mp_obj_base_t pyb_sdcard_obj = {&pyb_sdcard_type}; const mp_obj_base_t pyb_sdcard_obj = {&pyb_sdcard_type};
@ -905,4 +907,6 @@ void sdcard_init_vfs(fs_user_mount_t *vfs, int part) {
vfs->blockdev.u.ioctl[1] = MP_OBJ_FROM_PTR(&pyb_sdcard_obj); vfs->blockdev.u.ioctl[1] = MP_OBJ_FROM_PTR(&pyb_sdcard_obj);
} }
#endif // !BUILDING_MBOOT
#endif // MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD #endif // MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD

View File

@ -292,6 +292,7 @@ function ci_stm32_pyb_build {
make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1 make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1
make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBV10 CFLAGS_EXTRA='-DMBOOT_FSLOAD=1 -DMBOOT_VFS_LFS2=1' make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBV10 CFLAGS_EXTRA='-DMBOOT_FSLOAD=1 -DMBOOT_VFS_LFS2=1'
make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6 make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6
make ${MAKEOPTS} -C ports/stm32/mboot BOARD=STM32F769DISC CFLAGS_EXTRA='-DMBOOT_ADDRESS_SPACE_64BIT=1 -DMBOOT_SDCARD_ADDR=0x100000000ULL -DMBOOT_SDCARD_BYTE_SIZE=0x400000000ULL -DMBOOT_FSLOAD=1 -DMBOOT_VFS_FAT=1'
} }
function ci_stm32_nucleo_build { function ci_stm32_nucleo_build {