Bootloaders are a fine thing. With them, I can load any applications I like. Power comes with some complexity, and a bootloader alone is a complex thing already. But this applies to the application part too. I need to link the application to a certain offset in the memory space so it can be loaded by the bootloader, plus the application typically needs to add some extra information to be used by the bootloader.
This article describes how to build a bootloader application with Eclipse (MCUXpresso IDE) using the MCUXpresso SDK. Let’s get started.
You may also like: Flash Resident USB-HID Bootloader With the NXP Kinetis K22 Microcontroller
I’m using the Eclipse-based MCUXpresso IDE V11.0.1. Instead of ‘hacking’ the linker file, I’m using the built-in managed linker script way to automatically relocate the application to an address. In this tutorial: Porting BLE+NRF Kinetis Design Studio Project to MCUXpresso IDE, I already used the FreeMarker mechanism, but here, I show how it can be used on a higher level.
The needed files are available on GitHub.
The idea is to switch between ‘no bootloader’ and ‘bootloader application at address’ using Eclipse Build Configurations. Create a new build configuration. Name it like “BL_<application offset>”, e.g. “BL_0xA000”:
The naming is important, because I’m going to recognize in a script if it is a bootloader application (starting with “BL_”) and at which address the application shall get linked too (Hexadecimal number).
The Bootloader needs configuration data. I have put it into a ‘bootloader_config.c‘ and ‘bootloader_config.h‘. Add them to the project:
The bootloader configuration is only used in bootloader applications, so just turn it on with the following define in the project settings:
The IDE is using FreeMarker scripts, which is a powerful way to generate linker script files. We are now going to extend and overwrite some of the default files. Create a folder named ‘linkscripts’ (Naming is important!) inside the project and create three files (you can copy them from GitHub):
- user.ldt: This contains user variables used in the other scripts
- crp.ldt: This contains placement of the bootloader configuration data
- memory.ldt: This defines the linker memory ranges
The user.ldt uses the build configuration name to generate linker variables for the application offset and the configuration offset:
This is how it looks in the generated linker file:
The crp.ldt is used to place the bootloader configuration data at the expected offset (0x340) inside the application memory after the vector table.
Inspecting the template files in <MCUXpresso IDE Installation Path>\ide\Wizards\linker, I see I could ‘misuse’ the ‘crp.ldt’ to place my bootloader descriptor after the vectors. Ideally, the IDE would provide a dedicated template or hook. Instead, I’m just making a copy of the existing crp.ldt and have it extended.
Below, we have the result in the linker file:
The correct placement can be verified, e.g. with EHEP:
Finally, the memory.ldt is building the memory map in the linker file with the application offset:
So, based on the Build Configuration name, it automatically links the application to the correct memory area!
Using FreeMarker custom scripts and Eclipse Build Configurations, I can automatically build and link an application to be used with a bootloader. And I can use a ‘normal’ debug configuration to build and debug the application without the need for a bootloader.