From e316306546c9a0f76512692eaacfee9fe38892c5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 17 Mar 2022 17:11:44 +1100 Subject: [PATCH] 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 --- ports/stm32/mboot/Makefile | 10 ++++++++++ ports/stm32/mboot/README.md | 12 ++++++++++++ ports/stm32/mboot/main.c | 17 +++++++++++++++++ ports/stm32/mboot/sdcard.c | 13 +++++++++++++ ports/stm32/sdcard.c | 4 ++++ tools/ci.sh | 1 + 6 files changed, 57 insertions(+) create mode 100644 ports/stm32/mboot/sdcard.c diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index ee75fb2afe..61a102d02d 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -110,6 +110,7 @@ SRC_C += \ fsload.c \ gzstream.c \ pack.c \ + sdcard.c \ vfs_fat.c \ vfs_lfs.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 SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ hal_cortex.c \ + hal_dma.c \ hal_flash.c \ hal_flash_ex.c \ hal_pcd.c \ @@ -151,6 +153,14 @@ SRC_HAL += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ 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)/,\ core/src/usbd_core.c \ core/src/usbd_ctlreq.c \ diff --git a/ports/stm32/mboot/README.md b/ports/stm32/mboot/README.md index 49385047a4..936b587608 100644 --- a/ports/stm32/mboot/README.md +++ b/ports/stm32/mboot/README.md @@ -59,6 +59,13 @@ How to use second one use the same configuration names as above but with `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: #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 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 -------------------------------- diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 714b20ff09..976f0e54d2 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -37,6 +37,7 @@ #include "irq.h" #include "mboot.h" #include "powerctrl.h" +#include "sdcard.h" #include "dfu.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); } else #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 memcpy(buf, (void *)(uintptr_t)addr, len); @@ -1540,6 +1551,12 @@ enter_bootloader: mp_spiflash_init(MBOOT_SPIFLASH2_SPIFLASH); #endif + #if defined(MBOOT_SDCARD_ADDR) + sdcard_init(); + sdcard_select_sd(); + sdcard_power_on(); + #endif + #if MBOOT_ENABLE_PACKING mboot_pack_init(); #endif diff --git a/ports/stm32/mboot/sdcard.c b/ports/stm32/mboot/sdcard.c new file mode 100644 index 0000000000..caf3dbf3c0 --- /dev/null +++ b/ports/stm32/mboot/sdcard.c @@ -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 diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index 12c9eb4446..6f5892570b 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -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. +#if !BUILDING_MBOOT + // There are singleton SDCard/MMCard objects #if MICROPY_HW_ENABLE_SDCARD 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); } +#endif // !BUILDING_MBOOT + #endif // MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD diff --git a/tools/ci.sh b/tools/ci.sh index 4f6717fe93..5aed8a7dff 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -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/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=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 {