Skip to content

Commit 61e2931

Browse files
victorallumedpgeorge
authored andcommitted
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 <[email protected]>
1 parent 931a768 commit 61e2931

File tree

5 files changed

+124
-2
lines changed

5 files changed

+124
-2
lines changed

ports/stm32/mboot/Makefile

+18-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ include $(BOARD_DIR)/mpconfigboard.mk
3636
# A board can set MBOOT_TEXT0_ADDR to a custom location where mboot should reside.
3737
MBOOT_TEXT0_ADDR ?= 0x08000000
3838

39+
# The string in MBOOT_VERSION (default defined in version.c if not defined by a
40+
# board) will be stored in the final MBOOT_VERSION_ALLOCATED_BYTES bytes of mboot flash.
41+
# A board can change the size of this region by defining MBOOT_VERSION_ALLOCATED_BYTES.
42+
MBOOT_VERSION_ALLOCATED_BYTES ?= 64
43+
MBOOT_VERSION_INCLUDE_OPTIONS ?= 1 # if set to 1, this will append build options to version string (see version.c)
44+
3945
USBDEV_DIR=usbdev
4046
DFU=$(TOP)/tools/dfu.py
4147
PYDFU ?= $(TOP)/tools/pydfu.py
@@ -78,9 +84,14 @@ CFLAGS += -DBUILDING_MBOOT=$(BUILDING_MBOOT)
7884
CFLAGS += -DMICROPY_HW_STM32WB_FLASH_SYNCRONISATION=0
7985
CFLAGS += -DUSBD_ENABLE_VENDOR_DEVICE_REQUESTS=1
8086
CFLAGS += -DBOOTLOADER_DFU_USB_VID=$(BOOTLOADER_DFU_USB_VID) -DBOOTLOADER_DFU_USB_PID=$(BOOTLOADER_DFU_USB_PID)
87+
ifdef MBOOT_VERSION
88+
CFLAGS += -DMBOOT_VERSION=\"$(MBOOT_VERSION)\"
89+
endif
90+
CFLAGS += -DMBOOT_VERSION_ALLOCATED_BYTES=$(MBOOT_VERSION_ALLOCATED_BYTES) -DMBOOT_VERSION_INCLUDE_OPTIONS=$(MBOOT_VERSION_INCLUDE_OPTIONS)
8191

8292
MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld
8393
LDFLAGS += -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref
94+
LDFLAGS += --defsym mboot_version_len=$(MBOOT_VERSION_ALLOCATED_BYTES)
8495
LIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
8596

8697
# Remove uncalled code from the final image.
@@ -121,6 +132,7 @@ SRC_C += \
121132
vfs_fat.c \
122133
vfs_lfs.c \
123134
vfs_raw.c \
135+
version.c \
124136
drivers/bus/softspi.c \
125137
drivers/bus/softqspi.c \
126138
drivers/memory/spiflash.c \
@@ -206,7 +218,7 @@ deploy-stlink: $(BUILD)/firmware.dfu
206218

207219
$(BUILD)/firmware.dfu: $(BUILD)/firmware.elf
208220
$(ECHO) "Create $@"
209-
$(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data $^ $(BUILD)/firmware.bin
221+
$(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data -j .mboot_version_text $^ $(BUILD)/firmware.bin
210222
$(Q)$(PYTHON) $(DFU) -b $(MBOOT_TEXT0_ADDR):$(BUILD)/firmware.bin $@
211223

212224
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
@@ -231,8 +243,9 @@ GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c
231243
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
232244
GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h
233245
GEN_PINS_AF_DEFS = $(HEADER_BUILD)/pins_af_defs.h
246+
GEN_MPVERSION = $(HEADER_BUILD)/mpversion.h
234247

235-
$(OBJ): $(GEN_QSTRDEFS_GENERATED) $(GEN_ROOT_POINTERS) $(GEN_PINS_AF_DEFS)
248+
$(OBJ): $(GEN_QSTRDEFS_GENERATED) $(GEN_ROOT_POINTERS) $(GEN_PINS_AF_DEFS) $(GEN_MPVERSION)
236249

237250
$(HEADER_BUILD):
238251
$(MKDIR) -p $(BUILD)/genhdr
@@ -250,6 +263,9 @@ $(GEN_PINS_AF_DEFS): $(BOARD_PINS) $(MAKE_PINS) ../$(AF_FILE) $(PREFIX_FILE) | $
250263
--output-af-const $(GEN_PINS_AF_CONST) --output-af-defs $(GEN_PINS_AF_DEFS) \
251264
--mboot-mode
252265

266+
$(GEN_MPVERSION): | $(HEADER_BUILD)
267+
$(PYTHON) ../../../py/makeversionhdr.py $@
268+
253269
#########################################
254270

255271
vpath %.S . $(TOP)

ports/stm32/mboot/README.md

+16
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ How to use
8989
the beginning of the chunk when the end is reached. Then use a split
9090
raw filesystem to inform mboot of this wrapping.
9191

92+
The version and config options that mboot was built with are stored in a
93+
small, fixed section of bytes at the end of the flash region allocated
94+
for mboot. The length of the fixed section defaults to 64 bytes, but can
95+
be overridden by setting MBOOT_VERSION_ALLOCATED_BYTES. If running
96+
low on flash for the mboot build, this can be reduced or even set to 0.
97+
The version string stored defaults to the micropython git version as
98+
generated by makeversionhdr.py. The default version string can be
99+
overridden by setting MBOOT_VERSION in a board's build files. The version
100+
string is appended with options mboot was built with - see version.c for
101+
details. This can be prevented by setting MBOOT_VERSION_INCLUDE_OPTIONS to 0.
102+
92103
2. Build the board's main application firmware as usual.
93104

94105
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
209220
internal filesystem (if `MBOOT_FSLOAD` is enabled). `firmware.dfu` is still unencrypted
210221
and can be directly flashed with jtag etc.
211222

223+
Retrieving the mboot version in micropython
224+
-------------------------------------------
225+
The function `get_mboot_version` in `fwupdate.py` returns the version mboot was built with,
226+
optionally with build options.
227+
212228
Example: Mboot on PYBv1.x
213229
-------------------------
214230

ports/stm32/mboot/fwupdate.py

+22
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,25 @@ def update_mpy(*args, **kwargs):
281281
elems = update_app_elements(*args, **kwargs)
282282
if elems:
283283
machine.bootloader(elems)
284+
285+
286+
def get_mboot_version(
287+
mboot_base=0x0800_0000, # address of start of mboot flash section
288+
mboot_len=0x8000, # length of mboot flash section
289+
mboot_ver_len=64, # length of mboot version section (defined in mboot/Makefile or in board dir)
290+
valid_prefix="mboot-", # prefix that the version string was defined with
291+
include_opts=True, # return the options mboot was built with (set False for just the version)
292+
):
293+
s = ""
294+
for i in range(mboot_ver_len):
295+
c = stm.mem8[mboot_base + mboot_len - mboot_ver_len + i]
296+
if c == 0x00 or c == 0xFF: # have hit padding or empty flash
297+
break
298+
s += chr(c)
299+
if s.startswith(valid_prefix):
300+
if include_opts:
301+
return s
302+
else:
303+
return s.split("+")[0] # optional mboot config info stored after "+"
304+
else: # version hasn't been set, so on the original mboot (i.e. mboot-v1.0.0)
305+
return None

ports/stm32/mboot/stm32_sections.ld

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ SECTIONS
4747
_edata = .;
4848
} >RAM AT> FLASH_BL
4949

50+
/* Final section of mboot flash reserved for mboot version */
51+
.mboot_version_text (ORIGIN(FLASH_BL) + LENGTH(FLASH_BL) - mboot_version_len) :
52+
{
53+
KEEP(*(.mboot_version));
54+
} >FLASH_BL
55+
5056
/* Zeroed-out data section */
5157
.bss :
5258
{

ports/stm32/mboot/version.c

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "mboot.h"
2+
#include "genhdr/mpversion.h"
3+
4+
#if defined(MBOOT_VERSION_ALLOCATED_BYTES) && MBOOT_VERSION_ALLOCATED_BYTES > 0
5+
6+
#ifndef MBOOT_VERSION
7+
#define MBOOT_VERSION "mboot-" MICROPY_GIT_TAG
8+
#endif
9+
10+
#if MBOOT_VERSION_INCLUDE_OPTIONS // if this is defined, append a list of build options e.g. fat.lfs2
11+
#define MBOOT_VERSION_USB MBOOT_VERSION "+usb" // USB is always included
12+
13+
#if defined(MBOOT_I2C_SCL)
14+
#define MBOOT_VERSION_I2C MBOOT_VERSION_USB ".i2c"
15+
#else
16+
#define MBOOT_VERSION_I2C MBOOT_VERSION_USB
17+
#endif
18+
19+
#if MBOOT_ADDRESS_SPACE_64BIT
20+
#define MBOOT_VERSION_64BIT MBOOT_VERSION_I2C ".64"
21+
#else
22+
#define MBOOT_VERSION_64BIT MBOOT_VERSION_I2C
23+
#endif
24+
25+
#if MBOOT_VFS_FAT
26+
#define MBOOT_VERSION_FAT MBOOT_VERSION_64BIT ".fat"
27+
#else
28+
#define MBOOT_VERSION_FAT MBOOT_VERSION_64BIT
29+
#endif
30+
31+
#if MBOOT_VFS_LFS1
32+
#define MBOOT_VERSION_LFS1 MBOOT_VERSION_FAT ".lfs1"
33+
#else
34+
#define MBOOT_VERSION_LFS1 MBOOT_VERSION_FAT
35+
#endif
36+
37+
#if MBOOT_VFS_LFS2
38+
#define MBOOT_VERSION_LFS2 MBOOT_VERSION_LFS1 ".lfs2"
39+
#else
40+
#define MBOOT_VERSION_LFS2 MBOOT_VERSION_LFS1
41+
#endif
42+
43+
#if MBOOT_VFS_RAW
44+
#define MBOOT_VERSION_RAW MBOOT_VERSION_LFS2 ".raw"
45+
#else
46+
#define MBOOT_VERSION_RAW MBOOT_VERSION_LFS2
47+
#endif
48+
49+
#define MBOOT_VERSION_FINAL MBOOT_VERSION_RAW
50+
51+
#else // MBOOT_VERSION_INCLUDE_OPTIONS
52+
53+
#define MBOOT_VERSION_FINAL MBOOT_VERSION
54+
55+
#endif // MBOOT_VERSION_INCLUDE_OPTIONS
56+
57+
// Ensure we don't overrun the allocated space
58+
_Static_assert(sizeof(MBOOT_VERSION_FINAL) <= MBOOT_VERSION_ALLOCATED_BYTES + 1, "mboot version string is too long");
59+
// Cuts off the null terminator
60+
const char mboot_version[sizeof(MBOOT_VERSION_FINAL) - 1] __attribute__((section(".mboot_version"))) __attribute__ ((__used__)) = MBOOT_VERSION_FINAL;
61+
62+
#endif

0 commit comments

Comments
 (0)