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

View File

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

View File

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

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.
#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

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/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 {