• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..01-Sep-2021-

MakefileH A D01-Sep-20218.8 KiB285206

Particle.hH A D01-Sep-2021351 115

README.mdH A D01-Sep-20218.9 KiB226157

dfu.hH A D01-Sep-20214.4 KiB12074

elem.cH A D01-Sep-20211.7 KiB4513

ffconf.hH A D01-Sep-20212.2 KiB6634

fsload.cH A D01-Sep-20218.9 KiB298206

fwupdate.pyH A D01-Sep-20215.3 KiB199144

gzstream.cH A D01-Sep-20213.4 KiB11163

gzstream.hH A D01-Sep-20211.9 KiB4716

main.cH A D01-Sep-202151.7 KiB1,6661,256

mboot.hH A D01-Sep-20213.3 KiB10559

mboot.pyH A D01-Sep-20215.8 KiB182147

mboot_pack_dfu.pyH A D01-Sep-20219.8 KiB294192

mphalport.hH A D01-Sep-20218.5 KiB240196

pack.cH A D01-Sep-202110.7 KiB293178

pack.hH A D01-Sep-20212.9 KiB8332

stm32_memory.ldH A D01-Sep-2021252 119

stm32_sections.ldH A D01-Sep-20211.7 KiB7966

vfs.hH A D01-Sep-20212.8 KiB9749

vfs_fat.cH A D01-Sep-20213.5 KiB12378

vfs_lfs.cH A D01-Sep-20215.4 KiB163109

README.md

1Mboot - MicroPython boot loader
2===============================
3
4Mboot is a custom bootloader for STM32 MCUs, and currently supports the
5STM32F4xx, STM32F7xx and STM32WBxx families.  It can provide a standard USB DFU
6interface on either the FS or HS peripherals, as well as a sophisticated, custom I2C
7interface.  It can also load and program firmware in .dfu.gz format from a
8filesystem, either FAT, littlefs 1 or littlfs 2.
9It can fit in 16k of flash space, but all features enabled requires 32k.
10
11How to use
12----------
13
141. Configure your board to use a boot loader by editing the mpconfigboard.mk
15   and mpconfigboard.h files.  For example, for an F767 be sure to have these
16   lines in mpconfigboard.mk:
17
18    LD_FILES = boards/stm32f767.ld boards/common_bl.ld
19    TEXT0_ADDR = 0x08008000
20
21   And this in mpconfigboard.h (recommended to put at the end of the file):
22
23    // Bootloader configuration
24    #define MBOOT_I2C_PERIPH_ID 1
25    #define MBOOT_I2C_SCL (pin_B8)
26    #define MBOOT_I2C_SDA (pin_B9)
27    #define MBOOT_I2C_ALTFUNC (4)
28
29   To configure a pin to force entry into the boot loader the following
30   options can be used (with example configuration):
31
32    #define MBOOT_BOOTPIN_PIN (pin_A0)
33    #define MBOOT_BOOTPIN_PULL (MP_HAL_PIN_PULL_UP)
34    #define MBOOT_BOOTPIN_ACTIVE (0)
35
36   Mboot supports programming external SPI flash via the DFU and I2C
37   interfaces.  SPI flash will be mapped to an address range.  To
38   configure it use the following options (edit as needed):
39
40    #define MBOOT_SPIFLASH_ADDR (0x80000000)
41    #define MBOOT_SPIFLASH_BYTE_SIZE (2 * 1024 * 1024)
42    #define MBOOT_SPIFLASH_LAYOUT "/0x80000000/64*32Kg"
43    #define MBOOT_SPIFLASH_ERASE_BLOCKS_PER_PAGE (32 / 4)
44    #define MBOOT_SPIFLASH_SPIFLASH (&spi_bdev.spiflash)
45    #define MBOOT_SPIFLASH_CONFIG (&spiflash_config)
46
47   This assumes that the board declares and defines the relevant SPI flash
48   configuration structs, eg in the board-specific bdev.c file.  The
49   `MBOOT_SPIFLASH_LAYOUT` string will be seen by the USB DFU utility and
50   must describe the SPI flash layout.  Note that the number of pages in
51   this layout description (the `64` above) cannot be larger than 99 (it
52   must fit in two digits) so the reported page size (the `32Kg` above)
53   must be made large enough so the number of pages fits in two digits.
54   Alternatively the layout can specify multiple sections like
55   `32*16Kg,32*16Kg`, in which case `MBOOT_SPIFLASH_ERASE_BLOCKS_PER_PAGE`
56   must be changed to `16 / 4` to match the `16Kg` value.
57
58   Mboot supports up to two external SPI flash devices.  To configure the
59   second one use the same configuration names as above but with
60   `SPIFLASH2`, ie `MBOOT_SPIFLASH2_ADDR` etc.
61
62   To enable loading firmware from a filesystem use:
63
64    #define MBOOT_FSLOAD (1)
65
66   and then enable one or more of the following depending on what filesystem
67   support is required in Mboot (note that the FAT driver is read-only and
68   quite compact, but littlefs supports both read and write so is rather
69   large):
70
71    #define MBOOT_VFS_FAT (1)
72    #define MBOOT_VFS_LFS1 (1)
73    #define MBOOT_VFS_LFS2 (1)
74
752. Build the board's main application firmware as usual.
76
773. Build mboot via:
78
79    $ cd mboot
80    $ make BOARD=<board-id>
81
82   That should produce a DFU file for mboot.  It can be deployed using
83   USB DFU programming via (it will be placed at location 0x08000000):
84
85    $ make BOARD=<board-id> deploy
86
874. Reset the board while holding USR until all 3 LEDs are lit (the 4th option in
88   the cycle) and then release USR.  LED0 will then blink once per second to
89   indicate that it's in mboot
90
915. Use either USB DFU or I2C to download firmware.  The script mboot.py shows how
92   to communicate with the I2C boot loader interface.  It should be run on a
93   pyboard connected via I2C to the target board.
94
95Entering Mboot from application code
96------------------------------------
97
98To enter Mboot from a running application do the following:
99
1001. Make sure I and D caches are disabled.
101
1022. Load register r0 with the value 0x70ad0000.  The lower 7 bits can be
103   optionally or'd with the desired I2C address.
104
1053. Load the MSP with the value held at 0x08000000.
106
1074. Jump to the value held at 0x08000004.
108
109Additional data can be passed to Mboot from application code by storing this
110data in a special region of RAM.  This region begins at the address held at
111location 0x08000000 (which will point to just after Mboot's stack).  A
112maximum of 1024 bytes can be stored here.  To indicate to Mboot that this
113region is valid load register r0 with 0x70ad0080 (instead of step 2 above),
114optionally or'd with the desired I2C address.
115
116Data in this region is a sequence of elements.  Each element has the form:
117
118    <type:u8> <len:u8> <payload...>
119
120where `type` and `len` are bytes (designated by `u8`) and `payload` is 0 or
121more bytes.  `len` must be the number of bytes in `payload`.
122
123The last element in the data sequence must be the end element:
124
125* END: type=1, len=0
126
127Note: MicroPython's `machine.bootloader()` function performs steps 1-4
128above, and also accepts an optional bytes argument as additional data to
129pass through to Mboot.
130
131Loading firmware from a filesystem
132----------------------------------
133
134To get Mboot to load firmware from a filesystem and automatically program it
135requires passing data elements (see above) which tell where the filesystems
136are located and what filename to program.  The elements to use are:
137
138* MOUNT: type=2, len=10, payload=(<mount-point:u8> <fs-type:u8> <base-addr:u32> <byte-len:u32>)
139
140* FSLOAD: type=3, len=1+n, payload=(<mount-point:u8> <filename...>)
141
142`u32` means unsigned 32-bit little-endian integer.
143
144The firmware to load must be a gzip'd DfuSe file (.dfu.gz) and stored within a
145FAT or littlefs formatted partition.
146
147The provided fwupdate.py script contains helper functions to call into Mboot
148with the correct data, and also to update Mboot itself.  For example on PYBD
149the following will update the main MicroPython firmware from the file
150firmware.dfu.gz stored on the default FAT filesystem:
151
152    import fwupdate
153    fwupdate.update_mpy('firmware.dfu.gz', 0x80000000, 2 * 1024 * 1024)
154
155The 0x80000000 value is the address understood by Mboot as the location of
156the external SPI flash, configured via `MBOOT_SPIFLASH_ADDR`.
157
158Signed and encrypted DFU support
159--------------------------------
160
161Mboot optionally supports signing and encrypting the binary firmware in the DFU file.
162In general this is referred to as a packed DFU file.  This requires additional settings
163in the board config and requires the `pyhy` Python module to be installed for `python3`
164to be used when building packed firmware, eg:
165
166    $ pip3 install pyhy
167
168In addition to the changes made to mpconfigboard.mk earlier, for encrypted
169support you also need to add:
170
171    MBOOT_ENABLE_PACKING = 1
172
173You will also need to generate signing and encryption keys which will be built into
174mboot and used for all subsequent installations of firmware.  This can be done via:
175
176    $ python3 ports/stm32/mboot/mboot_pack_dfu.py generate-keys
177
178This command generates a `mboot_keys.h` file which should be stored in the board
179definition folder (next to mpconfigboard.mk).
180
181Once you build the firmware, the `firmware.pack.dfu` file will contain the encrypted
182and signed firmware, and can be deployed via USB DFU, or by copying it to the device's
183internal filesystem (if `MBOOT_FSLOAD` is enabled). `firmware.dfu` is still unencrypted
184and can be directly flashed with jtag etc.
185
186Example: Mboot on PYBv1.x
187-------------------------
188
189By default mboot is not used on PYBv1.x, but full mboot configuration is provided
190for these boards to demonstrate how it works and for testing.  To build and
191deploy mboot on these pyboards the only difference from the normal build process
192is to pass `USE_MBOOT=1` to make, so that the mboot configuration is used instead
193of the non-mboot configuration.
194
195In detail for PYBv1.0 (for PYBv1.1 use PYBV11 instead of PYBV10):
196
1971. Make sure the pyboard is in factory DFU mode (power up with BOOT0 connected to
198   3V3), then build mboot and deploy it (from the stm32/mboot/ directory):
199
200    $ make BOARD=PYBV10 USE_MBOOT=1 clean all deploy
201
202   This will put mboot on the pyboard.
203
2042. Now put the pyboard in mboot mode by holding down USR, pressing RST, and
205   continue to hold down USR until the blue LED is lit (the 4th option in the
206   cycle) and then release USR.  The red LED will blink once per second to
207   indicate that it's in mboot.  Then build the MicroPython firmware and deploy
208   it (from the stm32/ directory):
209
210    $ make BOARD=PYBV10 USE_MBOOT=1 clean all deploy
211
212   MicroPython will now be on the device and should boot straightaway.
213
214On PYBv1.x without mboot the flash layout is as follows:
215
216    0x08000000  0x08004000      0x08020000
217    | ISR text  | filesystem    | rest of MicroPython firmware
218
219On PYBv1.x with mboot the flash layout is as follows:
220
221    0x08000000  0x08004000      0x08020000
222    | mboot     | filesystem    | ISR and full MicroPython firmware
223
224Note that the filesystem remains intact when going to/from an mboot configuration
225so its contents will be preserved.
226