stm32/mboot: Add mboot version string.
Adds a configurable version string to a known location at the end of mboot flash section. Also stores the options mboot was built with, eg usb and which filesystems are supported. A board can override the defaults, or disable the version string entirely by setting MBOOT_VERSION_ALLOCATED_BYTES=0. Signed-off-by: Victor Rajewski <victor@allumeenergy.com.au>
This commit is contained in:
committed by
Damien George
parent
931a768f55
commit
61e2931f86
@@ -36,6 +36,12 @@ include $(BOARD_DIR)/mpconfigboard.mk
|
|||||||
# A board can set MBOOT_TEXT0_ADDR to a custom location where mboot should reside.
|
# A board can set MBOOT_TEXT0_ADDR to a custom location where mboot should reside.
|
||||||
MBOOT_TEXT0_ADDR ?= 0x08000000
|
MBOOT_TEXT0_ADDR ?= 0x08000000
|
||||||
|
|
||||||
|
# The string in MBOOT_VERSION (default defined in version.c if not defined by a
|
||||||
|
# board) will be stored in the final MBOOT_VERSION_ALLOCATED_BYTES bytes of mboot flash.
|
||||||
|
# A board can change the size of this region by defining MBOOT_VERSION_ALLOCATED_BYTES.
|
||||||
|
MBOOT_VERSION_ALLOCATED_BYTES ?= 64
|
||||||
|
MBOOT_VERSION_INCLUDE_OPTIONS ?= 1 # if set to 1, this will append build options to version string (see version.c)
|
||||||
|
|
||||||
USBDEV_DIR=usbdev
|
USBDEV_DIR=usbdev
|
||||||
DFU=$(TOP)/tools/dfu.py
|
DFU=$(TOP)/tools/dfu.py
|
||||||
PYDFU ?= $(TOP)/tools/pydfu.py
|
PYDFU ?= $(TOP)/tools/pydfu.py
|
||||||
@@ -78,9 +84,14 @@ CFLAGS += -DBUILDING_MBOOT=$(BUILDING_MBOOT)
|
|||||||
CFLAGS += -DMICROPY_HW_STM32WB_FLASH_SYNCRONISATION=0
|
CFLAGS += -DMICROPY_HW_STM32WB_FLASH_SYNCRONISATION=0
|
||||||
CFLAGS += -DUSBD_ENABLE_VENDOR_DEVICE_REQUESTS=1
|
CFLAGS += -DUSBD_ENABLE_VENDOR_DEVICE_REQUESTS=1
|
||||||
CFLAGS += -DBOOTLOADER_DFU_USB_VID=$(BOOTLOADER_DFU_USB_VID) -DBOOTLOADER_DFU_USB_PID=$(BOOTLOADER_DFU_USB_PID)
|
CFLAGS += -DBOOTLOADER_DFU_USB_VID=$(BOOTLOADER_DFU_USB_VID) -DBOOTLOADER_DFU_USB_PID=$(BOOTLOADER_DFU_USB_PID)
|
||||||
|
ifdef MBOOT_VERSION
|
||||||
|
CFLAGS += -DMBOOT_VERSION=\"$(MBOOT_VERSION)\"
|
||||||
|
endif
|
||||||
|
CFLAGS += -DMBOOT_VERSION_ALLOCATED_BYTES=$(MBOOT_VERSION_ALLOCATED_BYTES) -DMBOOT_VERSION_INCLUDE_OPTIONS=$(MBOOT_VERSION_INCLUDE_OPTIONS)
|
||||||
|
|
||||||
MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld
|
MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld
|
||||||
LDFLAGS += -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref
|
LDFLAGS += -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref
|
||||||
|
LDFLAGS += --defsym mboot_version_len=$(MBOOT_VERSION_ALLOCATED_BYTES)
|
||||||
LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||||
|
|
||||||
# Remove uncalled code from the final image.
|
# Remove uncalled code from the final image.
|
||||||
@@ -121,6 +132,7 @@ SRC_C += \
|
|||||||
vfs_fat.c \
|
vfs_fat.c \
|
||||||
vfs_lfs.c \
|
vfs_lfs.c \
|
||||||
vfs_raw.c \
|
vfs_raw.c \
|
||||||
|
version.c \
|
||||||
drivers/bus/softspi.c \
|
drivers/bus/softspi.c \
|
||||||
drivers/bus/softqspi.c \
|
drivers/bus/softqspi.c \
|
||||||
drivers/memory/spiflash.c \
|
drivers/memory/spiflash.c \
|
||||||
@@ -206,7 +218,7 @@ deploy-stlink: $(BUILD)/firmware.dfu
|
|||||||
|
|
||||||
$(BUILD)/firmware.dfu: $(BUILD)/firmware.elf
|
$(BUILD)/firmware.dfu: $(BUILD)/firmware.elf
|
||||||
$(ECHO) "Create $@"
|
$(ECHO) "Create $@"
|
||||||
$(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data $^ $(BUILD)/firmware.bin
|
$(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data -j .mboot_version_text $^ $(BUILD)/firmware.bin
|
||||||
$(Q)$(PYTHON) $(DFU) -b $(MBOOT_TEXT0_ADDR):$(BUILD)/firmware.bin $@
|
$(Q)$(PYTHON) $(DFU) -b $(MBOOT_TEXT0_ADDR):$(BUILD)/firmware.bin $@
|
||||||
|
|
||||||
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
|
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
|
||||||
@@ -231,8 +243,9 @@ GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c
|
|||||||
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
|
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
|
||||||
GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h
|
GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h
|
||||||
GEN_PINS_AF_DEFS = $(HEADER_BUILD)/pins_af_defs.h
|
GEN_PINS_AF_DEFS = $(HEADER_BUILD)/pins_af_defs.h
|
||||||
|
GEN_MPVERSION = $(HEADER_BUILD)/mpversion.h
|
||||||
|
|
||||||
$(OBJ): $(GEN_QSTRDEFS_GENERATED) $(GEN_ROOT_POINTERS) $(GEN_PINS_AF_DEFS)
|
$(OBJ): $(GEN_QSTRDEFS_GENERATED) $(GEN_ROOT_POINTERS) $(GEN_PINS_AF_DEFS) $(GEN_MPVERSION)
|
||||||
|
|
||||||
$(HEADER_BUILD):
|
$(HEADER_BUILD):
|
||||||
$(MKDIR) -p $(BUILD)/genhdr
|
$(MKDIR) -p $(BUILD)/genhdr
|
||||||
@@ -250,6 +263,9 @@ $(GEN_PINS_AF_DEFS): $(BOARD_PINS) $(MAKE_PINS) ../$(AF_FILE) $(PREFIX_FILE) | $
|
|||||||
--output-af-const $(GEN_PINS_AF_CONST) --output-af-defs $(GEN_PINS_AF_DEFS) \
|
--output-af-const $(GEN_PINS_AF_CONST) --output-af-defs $(GEN_PINS_AF_DEFS) \
|
||||||
--mboot-mode
|
--mboot-mode
|
||||||
|
|
||||||
|
$(GEN_MPVERSION): | $(HEADER_BUILD)
|
||||||
|
$(PYTHON) ../../../py/makeversionhdr.py $@
|
||||||
|
|
||||||
#########################################
|
#########################################
|
||||||
|
|
||||||
vpath %.S . $(TOP)
|
vpath %.S . $(TOP)
|
||||||
|
|||||||
@@ -89,6 +89,17 @@ How to use
|
|||||||
the beginning of the chunk when the end is reached. Then use a split
|
the beginning of the chunk when the end is reached. Then use a split
|
||||||
raw filesystem to inform mboot of this wrapping.
|
raw filesystem to inform mboot of this wrapping.
|
||||||
|
|
||||||
|
The version and config options that mboot was built with are stored in a
|
||||||
|
small, fixed section of bytes at the end of the flash region allocated
|
||||||
|
for mboot. The length of the fixed section defaults to 64 bytes, but can
|
||||||
|
be overridden by setting MBOOT_VERSION_ALLOCATED_BYTES. If running
|
||||||
|
low on flash for the mboot build, this can be reduced or even set to 0.
|
||||||
|
The version string stored defaults to the micropython git version as
|
||||||
|
generated by makeversionhdr.py. The default version string can be
|
||||||
|
overridden by setting MBOOT_VERSION in a board's build files. The version
|
||||||
|
string is appended with options mboot was built with - see version.c for
|
||||||
|
details. This can be prevented by setting MBOOT_VERSION_INCLUDE_OPTIONS to 0.
|
||||||
|
|
||||||
2. Build the board's main application firmware as usual.
|
2. Build the board's main application firmware as usual.
|
||||||
|
|
||||||
3. Build mboot via:
|
3. Build mboot via:
|
||||||
@@ -209,6 +220,11 @@ and signed firmware, and can be deployed via USB DFU, or by copying it to the de
|
|||||||
internal filesystem (if `MBOOT_FSLOAD` is enabled). `firmware.dfu` is still unencrypted
|
internal filesystem (if `MBOOT_FSLOAD` is enabled). `firmware.dfu` is still unencrypted
|
||||||
and can be directly flashed with jtag etc.
|
and can be directly flashed with jtag etc.
|
||||||
|
|
||||||
|
Retrieving the mboot version in micropython
|
||||||
|
-------------------------------------------
|
||||||
|
The function `get_mboot_version` in `fwupdate.py` returns the version mboot was built with,
|
||||||
|
optionally with build options.
|
||||||
|
|
||||||
Example: Mboot on PYBv1.x
|
Example: Mboot on PYBv1.x
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -281,3 +281,25 @@ def update_mpy(*args, **kwargs):
|
|||||||
elems = update_app_elements(*args, **kwargs)
|
elems = update_app_elements(*args, **kwargs)
|
||||||
if elems:
|
if elems:
|
||||||
machine.bootloader(elems)
|
machine.bootloader(elems)
|
||||||
|
|
||||||
|
|
||||||
|
def get_mboot_version(
|
||||||
|
mboot_base=0x0800_0000, # address of start of mboot flash section
|
||||||
|
mboot_len=0x8000, # length of mboot flash section
|
||||||
|
mboot_ver_len=64, # length of mboot version section (defined in mboot/Makefile or in board dir)
|
||||||
|
valid_prefix="mboot-", # prefix that the version string was defined with
|
||||||
|
include_opts=True, # return the options mboot was built with (set False for just the version)
|
||||||
|
):
|
||||||
|
s = ""
|
||||||
|
for i in range(mboot_ver_len):
|
||||||
|
c = stm.mem8[mboot_base + mboot_len - mboot_ver_len + i]
|
||||||
|
if c == 0x00 or c == 0xFF: # have hit padding or empty flash
|
||||||
|
break
|
||||||
|
s += chr(c)
|
||||||
|
if s.startswith(valid_prefix):
|
||||||
|
if include_opts:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return s.split("+")[0] # optional mboot config info stored after "+"
|
||||||
|
else: # version hasn't been set, so on the original mboot (i.e. mboot-v1.0.0)
|
||||||
|
return None
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ SECTIONS
|
|||||||
_edata = .;
|
_edata = .;
|
||||||
} >RAM AT> FLASH_BL
|
} >RAM AT> FLASH_BL
|
||||||
|
|
||||||
|
/* Final section of mboot flash reserved for mboot version */
|
||||||
|
.mboot_version_text (ORIGIN(FLASH_BL) + LENGTH(FLASH_BL) - mboot_version_len) :
|
||||||
|
{
|
||||||
|
KEEP(*(.mboot_version));
|
||||||
|
} >FLASH_BL
|
||||||
|
|
||||||
/* Zeroed-out data section */
|
/* Zeroed-out data section */
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
|
|||||||
62
ports/stm32/mboot/version.c
Normal file
62
ports/stm32/mboot/version.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#include "mboot.h"
|
||||||
|
#include "genhdr/mpversion.h"
|
||||||
|
|
||||||
|
#if defined(MBOOT_VERSION_ALLOCATED_BYTES) && MBOOT_VERSION_ALLOCATED_BYTES > 0
|
||||||
|
|
||||||
|
#ifndef MBOOT_VERSION
|
||||||
|
#define MBOOT_VERSION "mboot-" MICROPY_GIT_TAG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MBOOT_VERSION_INCLUDE_OPTIONS // if this is defined, append a list of build options e.g. fat.lfs2
|
||||||
|
#define MBOOT_VERSION_USB MBOOT_VERSION "+usb" // USB is always included
|
||||||
|
|
||||||
|
#if defined(MBOOT_I2C_SCL)
|
||||||
|
#define MBOOT_VERSION_I2C MBOOT_VERSION_USB ".i2c"
|
||||||
|
#else
|
||||||
|
#define MBOOT_VERSION_I2C MBOOT_VERSION_USB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MBOOT_ADDRESS_SPACE_64BIT
|
||||||
|
#define MBOOT_VERSION_64BIT MBOOT_VERSION_I2C ".64"
|
||||||
|
#else
|
||||||
|
#define MBOOT_VERSION_64BIT MBOOT_VERSION_I2C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MBOOT_VFS_FAT
|
||||||
|
#define MBOOT_VERSION_FAT MBOOT_VERSION_64BIT ".fat"
|
||||||
|
#else
|
||||||
|
#define MBOOT_VERSION_FAT MBOOT_VERSION_64BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MBOOT_VFS_LFS1
|
||||||
|
#define MBOOT_VERSION_LFS1 MBOOT_VERSION_FAT ".lfs1"
|
||||||
|
#else
|
||||||
|
#define MBOOT_VERSION_LFS1 MBOOT_VERSION_FAT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MBOOT_VFS_LFS2
|
||||||
|
#define MBOOT_VERSION_LFS2 MBOOT_VERSION_LFS1 ".lfs2"
|
||||||
|
#else
|
||||||
|
#define MBOOT_VERSION_LFS2 MBOOT_VERSION_LFS1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MBOOT_VFS_RAW
|
||||||
|
#define MBOOT_VERSION_RAW MBOOT_VERSION_LFS2 ".raw"
|
||||||
|
#else
|
||||||
|
#define MBOOT_VERSION_RAW MBOOT_VERSION_LFS2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MBOOT_VERSION_FINAL MBOOT_VERSION_RAW
|
||||||
|
|
||||||
|
#else // MBOOT_VERSION_INCLUDE_OPTIONS
|
||||||
|
|
||||||
|
#define MBOOT_VERSION_FINAL MBOOT_VERSION
|
||||||
|
|
||||||
|
#endif // MBOOT_VERSION_INCLUDE_OPTIONS
|
||||||
|
|
||||||
|
// Ensure we don't overrun the allocated space
|
||||||
|
_Static_assert(sizeof(MBOOT_VERSION_FINAL) <= MBOOT_VERSION_ALLOCATED_BYTES + 1, "mboot version string is too long");
|
||||||
|
// Cuts off the null terminator
|
||||||
|
const char mboot_version[sizeof(MBOOT_VERSION_FINAL) - 1] __attribute__((section(".mboot_version"))) __attribute__ ((__used__)) = MBOOT_VERSION_FINAL;
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user