Skip to content

Commit 5ee6794

Browse files
authored
Merge pull request #3 from mbed-ce/dev/add-mimxrt1060-evk
Add config for MIMXRT1060_EVK, add section to README detailing how to configure the project for a new target
2 parents 852d70e + d545caf commit 5ee6794

File tree

6 files changed

+177
-8
lines changed

6 files changed

+177
-8
lines changed

.github/workflows/compile.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobs:
1515
# Change the below to match the target(s) you want to compile the project for.
1616
- NUCLEO_H743ZI2
1717
- K64F
18+
- MIMXRT1060_EVK
1819

1920
steps:
2021
- name: Checkout
@@ -37,5 +38,5 @@ jobs:
3738
- name: Build project for ${{ matrix.mbed_target }}
3839
run: |
3940
mkdir build && cd build
40-
cmake .. -GNinja -DMBED_TARGET=${{ matrix.mbed_target }} -DMCUBOOT_SIGNING_KEY=signing-keys.pem
41+
cmake .. -GNinja -DMBED_TARGET=${{ matrix.mbed_target }} -DUPLOAD_METHOD=NONE -DMCUBOOT_SIGNING_KEY=signing-keys.pem
4142
ninja

README.md

+139-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ If configured as such, mcuboot can perform a "swap" update where it will copy th
6060

6161
To perform this kind of swap update, mcuboot requires a non-volatile "scratch" space in memory to store pieces of application code and update status information. This enables mcuboot to safely continue an update/revert procedure in the event of a power loss.
6262

63+
While the scratch region can be as small as one erase sector, making the scratch region larger will reduce wear on the scratch flash sectors when installing updates (because the entire image is swapped via the scratch sector as an intermediary).
64+
6365
The scratch region starting address may be specified with the configuration parameter, `mcuboot.scratch-address`. The size of the scratch space can be configured using `mcuboot.scratch-size` -- this value **must** be erase-sector aligned (ie: a multiple of the internal flash's eraseable size).
6466

6567
For more advanced information about configuring the scratch space region, see the [mcuboot documentation on Image Slots](https://github.com/mcu-tools/mcuboot/blob/master/docs/design.md#image-slots). For more information on swap updates, see the [mcuboot documentation on Swap Updates](https://github.com/mcu-tools/mcuboot/blob/master/docs/design.md#image-swapping)
@@ -119,7 +121,7 @@ $ git clone --recursive https://github.com/mbed-ce/mbed-mcuboot-bootloader.git
119121

120122
Then, set up the GNU ARM toolchain (and other programs) on your machine using [the toolchain setup guide](https://github.com/mbed-ce/mbed-os/wiki/Toolchain-Setup-Guide).
121123

122-
Now, set up the CMake project for editing as you would normally. Make sure to configure an upload method. We have three ways to do this:
124+
Now, set up the CMake project for editing as you would normally. Make sure to configure an upload method other than MBED, as that upload method does not allow flashing specific regions of memory by address. We have three ways to do this:
123125
- On the [command line](https://github.com/mbed-ce/mbed-os/wiki/Project-Setup:-Command-Line)
124126
- Using the [CLion IDE](https://github.com/mbed-ce/mbed-os/wiki/Project-Setup:-CLion)
125127
- Using the [VS Code IDE](https://github.com/mbed-ce/mbed-os/wiki/Project-Setup:-VS-Code)
@@ -289,6 +291,142 @@ The simple application will do this when you press the button. If you reboot wi
289291

290292
In real world situations, your application should run a self test routine to ensure it can receive updates in the future (eg: the UART software works as expected, the BLE stack initializes successfully, etc).
291293

294+
## Porting to New Devices
295+
Currently, mcuboot only has existing configurations for a few Mbed targets. If you need to run mcuboot on a different target, you will need to create the appropriate configs.
296+
297+
### Understanding your Target Memory Config
298+
In order to create the memory bank config for your target, you will need to understand the layout of its flash bank(s). The easiest way to get this information is to watch the output from the first configure of Mbed. For example, on MIMXRT1060_EVK, I see this:
299+
```
300+
Summary of available memory banks:
301+
Target RAM banks: -----------------------------------------------------------
302+
0. SDRAM, start addr 0x80000000, size 256.0 MiB
303+
1. SRAM_DTC, start addr 0x20000000, size 256.0 KiB
304+
2. SRAM_ITC, start addr 0x00000000, size 128.0 KiB
305+
3. SRAM_OC, start addr 0x20280000, size 128.0 KiB
306+
4. SRAM_OC2, start addr 0x20200000, size 512.0 KiB
307+
308+
Target ROM banks: -----------------------------------------------------------
309+
0. EXT_FLASH, start addr 0x60000000, size 8.0 MiB
310+
```
311+
312+
We can see that there is exactly one ROM bank called EXT_FLASH, and its size is 8.0 MiB. If you see multiple ROM banks instead of one, you will need to consult your target MCU's manual and linker script to determine which one is used for the main application.
313+
314+
The other piece of information that you need is the page and sector size of your ROM bank, and of the secondary block device if not using XIP mode. This will require a trip to your MCU datasheet, or the datasheet for the external flash for chips that don't have internal flash like the MIMXRT1060. Note that mcuboot *can* handle flashes with non-uniform sector sizes, but you will have to be extra careful about assigning things to sectors correctly.
315+
316+
### Allocating Memory
317+
318+
Now we need to decide what slot size we're going to use and allocate the space into regions. On the MIMXRT1060_EVK we have 8MiB of flash available (quite a lot!), split into 4k erase sectors and 256 byte programmable pages. We need to use that flash to store both the primary slot and the secondary slot. Let's say we also want to reserve a bit of space for using KVStore to store data in flash. So, let's go with:
319+
- 128kiB (offset 0 - offset 0x20000) for the bootloader
320+
- 3MiB for primary slot (offset 0x20000 - offset 0x320000)
321+
- 3MiB for secondary slot (offset 0x320000 - offset 0x620000)
322+
- 128kiB scratch space (offset 0x620000 - offset 0x640000)
323+
- Remaining space (2MiB - 256k) for FlashIAPBlockDevice (offset 0x640000 - offset 0x800000)
324+
325+
### Checking the Linker Script
326+
Before building the project, you will need to check that your device linker script has been ported to use memory banks. Unfortunately, memory bank support is a more recent feature of Mbed and the majority of devices have not had their linker scripts updated to support it yet.
327+
328+
To find the linker script for your target, you can watch the build output. You should see a line like this:
329+
```
330+
Preprocess linker script: MIMXRT1052xxxxx.ld -> mbed-mimxrt1060-evk.link_script.ld
331+
```
332+
This means the linker script for your target is called `MIMXRT1052xxxxx.ld`. Search for this file in the mbed-os source tree and open it. Look for a block like this:
333+
```
334+
MEMORY
335+
{
336+
<snip>
337+
m_text (RX) : ORIGIN = MBED_CONFIGURED_ROM_BANK_EXT_FLASH_START, LENGTH = MBED_CONFIGURED_ROM_BANK_EXT_FLASH_SIZE
338+
<snip>
339+
```
340+
341+
You want the entry in MEMORY called `m_text` or `m_flash` or `m_rom` -- wherever the code for your device is stored.
342+
343+
If the entry is defined in terms of `MBED_CONFIGURED_ROM_BANK` constants, this linker script has already been upgraded. If not, and it references `MBED_APP_START` and `MBED_APP_SIZE`, or it just uses constant addresses, then this target still needs to be upgraded.
344+
345+
Please file a PR with mbed-ce/mbed-os asking for the linker script to be updated, or, if you are feeling adventurous, you can update the linker script yourself. Updates can be as simple as defining the text section in terms of the `MBED_CONFIGURED_ROM_BANK` constants, though there are also a number of other fixes that are useful for older linker scripts.
346+
347+
### Setting Up Bootloader mbed_app.json
348+
349+
Based on what we've learned, we would add a new entry in mbed_app.json like:
350+
```js
351+
"MIMXRT1060_EVK": {
352+
"target.memory_bank_config": {
353+
"EXT_FLASH": {
354+
"size": 0x20000
355+
}
356+
},
357+
358+
// Primary slot is 3MiB and begins right after the bootloader
359+
"mcuboot.primary-slot-address": "0x60020000",
360+
"mcuboot.slot-size": "0x300000",
361+
362+
// Use flash for secondary slot as well
363+
"secondary-slot-in-flash": true,
364+
"secondary-slot-flash-start-addr": "0x60320000",
365+
366+
// Store the scratch space at the end of flash
367+
"mcuboot.scratch-address": "0x60620000",
368+
"mcuboot.scratch-size": "0x20000",
369+
370+
"mcuboot.read-granularity": 1, // Flash is byte addressable
371+
372+
"mcuboot.max-img-sectors": 768, // Maximum flash sectors per slot. 3MiB/4kiB = 768.
373+
"mcuboot.flash-block-size": 256
374+
},
375+
```
376+
Keep in mind that on MIMXRT, the flash base address in memory is 0x60000000, so we have to add that to all the offsets to get absolute addresses.
377+
378+
Note: Be careful of the mcuboot.max-img-sectors setting! This needs to be the maximum number of sectors per slot in either the primary or secondary slot, whichever is greater. This means you need to check the sector size of your secondary block device too.
379+
380+
Note: mcuboot defaults to a flash block size of 8, i.e. it will try to program flash in chunks as small as 8 bytes. The block size on this board is much larger, so we need to increase that constant.
381+
382+
Now, you can flash the bootloader to your device using the steps above. Make sure that it boots and you see some activity on the serial port before continuing. You should see something like:
383+
```
384+
[INFO][BL]: Starting MCUboot
385+
[INFO][MCUb]: Primary image: magic=bad, swap_type=0x0, copy_done=0x2, image_ok=0x2
386+
[INFO][MCUb]: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
387+
[INFO][MCUb]: Boot source: none
388+
[INFO][MCUb]: Image index: 0, Swap type: none
389+
[ERR ][BL]: Failed to locate firmware image, error: -1
390+
```
391+
392+
### Setting Up Application mbed_app.json
393+
Now we can set up the demo app. Its mbed_app.json should look the same as the bootloader, *except* the `target.memory_bank_config` section. We want this application to go into the application region of the primary slot. So, we must set the start address to `mcuboot.primary-slot-address` + `mcuboot.header-size` (which defaults to 0x1000). Meanwhile, the size should be set to extend to the end of the primary slot (yes there are some TLVs after there, but the image tool will warn if there isn't enough space).
394+
395+
So we'd add the following block:
396+
```js
397+
"MIMXRT1060_EVK": {
398+
"target.memory_bank_config": {
399+
"EXT_FLASH": {
400+
"start": 0x60021000, // mcuboot.primary-slot-address + mcuboot.header-size
401+
"size": 0x2FF000 // mcuboot.slot-size - mcuboot.header-size
402+
}
403+
},
404+
405+
// Primary slot is 3MiB and begins right after the bootloader
406+
"mcuboot.primary-slot-address": "0x60020000",
407+
"mcuboot.slot-size": "0x300000",
408+
409+
// Use flash for secondary slot as well
410+
"secondary-slot-in-flash": true,
411+
"secondary-slot-flash-start-addr": "0x60320000",
412+
413+
// Store the scratch space at the end of flash
414+
"mcuboot.scratch-address": "0x60620000",
415+
"mcuboot.scratch-size": "0x20000",
416+
417+
"mcuboot.read-granularity": 1, // Flash is byte addressable
418+
419+
"mcuboot.max-img-sectors": 768, // Maximum flash sectors per slot. 3MiB/4kiB = 768.
420+
"mcuboot.flash-block-size": 256,
421+
422+
"demo-button-active-low": true
423+
}
424+
```
425+
426+
Note that we also need to add `"demo-button-active-low": true` because the user button on this board is low when pressed.
427+
428+
NOTE: Changes to the configured start address of flash generally require a CMake delete cache and reconfigure operation so that the MBED_UPLOAD_BASE_ADDR variable can be initialized with the right value. So, you will need to do that if you had previously configured the project.
429+
292430
## Additional Features
293431

294432
MCUboot integrates a number of additional features that are commonly used in bootloader situations. More details of these features can be found in the mcuboot documentation/code.

mbed-os

Submodule mbed-os updated 59 files

mbed_app.json5

+31-1
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77
"secondary-slot-in-flash": {
88
"help": "If enabled, store the secondary slot in the application flash immediately after the primary slot.",
99
"value": false
10+
},
11+
"secondary-slot-flash-start-addr": {
12+
"help": "If secondary-slot-in-flash is enabled, this sets the start address of the secondary slot.",
13+
"value": null
1014
}
1115
},
1216
"target_overrides": {
1317
"*": {
1418
"platform.stdio-baud-rate": 115200,
1519
"target.c_lib": "small",
1620
"mcuboot.log-enable": true,
17-
"mcuboot.log-level": "MCUBOOT_LOG_LEVEL_INFO",
21+
"mcuboot.log-level": "MCUBOOT_LOG_LEVEL_INFO", // Change DEBUG to INFO for debug prints
1822
"mbed-trace.enable": true,
1923
"mbed-trace.max-level": "TRACE_LEVEL_DEBUG",
2024
"mbed-trace.fea-ipv6": false,
@@ -85,6 +89,31 @@
8589
"mcuboot.max-img-sectors": "1536" // External SD card has smaller sector size, so divide slot size by read granularity
8690
},
8791

92+
"MIMXRT1060_EVK": {
93+
"target.memory_bank_config": {
94+
"EXT_FLASH": {
95+
"size": 0x20000
96+
}
97+
},
98+
99+
// Primary slot is 3MiB and begins right after the bootloader
100+
"mcuboot.primary-slot-address": "0x60020000",
101+
"mcuboot.slot-size": "0x300000",
102+
103+
// Use flash for secondary slot as well
104+
"secondary-slot-in-flash": true,
105+
"secondary-slot-flash-start-addr": "0x60320000",
106+
107+
// Store the scratch space at the end of flash
108+
"mcuboot.scratch-address": "0x60620000",
109+
"mcuboot.scratch-size": "0x20000",
110+
111+
"mcuboot.read-granularity": 1, // Flash is byte addressable
112+
113+
"mcuboot.max-img-sectors": 768, // Maximum flash sectors per slot. 3MiB/4kiB = 768.
114+
"mcuboot.flash-block-size": 256
115+
},
116+
88117
"MCU_STM32H743xI": {
89118
// Configure bootloader to live in the first sector of flash
90119
"target.memory_bank_config": {
@@ -95,6 +124,7 @@
95124

96125
// Since STM32H743 boards have no external block device, keep everything in the MCU flash.
97126
"app.secondary-slot-in-flash": true,
127+
"app.secondary-slot-flash-start-addr": "0x100000",
98128

99129
// Slot size can be as big as 896k, since we need to reserve the first flash sector for the bootloader
100130
// and the last flash sector for scratch space

secondary_bd.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
mbed::BlockDevice* get_secondary_bd(void) {
1717

18-
// Use a section of FlashIAP immediately after the secondary slot
19-
static FlashIAPBlockDevice flashBD(MCUBOOT_PRIMARY_SLOT_START_ADDR + MCUBOOT_SLOT_SIZE, MCUBOOT_SLOT_SIZE);
18+
// Use FlashIAP for the secondary BD.
19+
static FlashIAPBlockDevice flashBD(MBED_CONF_APP_SECONDARY_SLOT_FLASH_START_ADDR, MCUBOOT_SLOT_SIZE);
2020
return &flashBD;
2121
}
2222

@@ -33,7 +33,7 @@ mbed::BlockDevice* get_secondary_bd(void) {
3333
// Otherwise it will return the flash IAP block device.
3434
mbed::BlockDevice* default_bd = mbed::BlockDevice::get_default_instance();
3535

36-
// If this assert fails, there is no block def
36+
// If this assert fails, there is no default block device defined for your board.
3737
MBED_ASSERT(default_bd != nullptr);
3838

3939
// mcuboot assumes that the read size of the secondary block device is the same as the read size

0 commit comments

Comments
 (0)