README: MCUboot is now available from the SDK builder. This guide is no longer relevant.
Introduction
This post will describe the process for building and using the NXP Kinetis Bootloader version 2.0.0 with the MCUXpresso IDE and SDK. This guide assumes you are familiar with creating and running projects using MCUXpresso and have installed the SDK for your target processor. This procedure is tested and working with the MKV56F24.
Project Setup
- Download the source package from MCU Bootloader|NXP
- Create a new C project in MCUXpresso for your processor with the following drivers:
- Required for core function:
- Optional depending on configuration:
- Delete the template 'main' file that MCUXpresso creates for you.
- Delete the semihost_hardfault.c file that MCUXpresso creates for you.
- Create driver sub-folders and move the driver source into them
- move fsl_port.c/h into drivers/port
- move fsl_gpio.c/h into drivers/gpio
- move fsl_crc.c/h into drivers/crc
- move fsl_dspi.c/h into drivers/dspi
- move fsl_flexcan.c/h into drivers/flexcan
- move fsl_i2c.c/h into drivers/i2c
- move fsl_uart.c/h into drivers/uart
- Unzip the bootloader source
- Copy the contents of the NXP_Kinetis_Bootloader_2_0_0/src directory to your new project's source directory.
- Copy the contents of the NXP_Kinetis_Bootloader_2_0_0/targets/common/src directory to your new project's source directory
- Refresh the project so MCUXpresso becomes aware of the new source
- Delete or filter out the following directories from the bootloader source:
- source/blfwk
- source/blsh
- source/bm_usb
- source/platform
- source/usb
- source/security
- Delete or filter out the following sources
- source/startup/boot.s
- source/startup/crt0.s
- source/startup/ar_handlers_cm0p.S
- source/memory/src/pattern_fill.s
- source/memory/src/qspi_memory.c
- source/memory/src/qspi_memory.h
- source/utilities/src/bootloader_tree_stub.c
- source/bootloader/src/bl_flashloader.c
- source/bootloader/src/bl_misc_rom.c
- source/bl_lpi2c_irq_config_common.c
- source/bl_lpspi_irq_config_common.c
- source/bl_spuart_irq_config_common.c
- source/bl_intmux_irq.c
- source/clock_common_scg.c
- Delete or filter out the following interfaces
- source/bootloader/src/lpspi_peripheral_interface.c
- source/bootloader/src/lpi2c_peripheral_interface.c
- source/bootloader/src/lpuart_peripheral_interface.c
- source/bootloader/src/spi_peripheral_interface.c
- source/bootloader/src/usb_hid_msc_peripheral_interface.c
- source/bootloader/src/usb_hid_peripheral_interface.c
- source/bootloader/src/usb_hs_hid_peripheral_interface.c
- source/bootloader/src/uart0_peripheral_interface.c
- Choose an sram initialization based on your processor and filter/delete the other two:
- source/memory/src/sram_init_cm0plus.c
- source/memory/src/sram_init_cm4.c
- source/memory/src/sram_init_cm7.c
- Delete or filter out the following drivers in favor of the SDK versions
- source/drivers/common
- source/drivers/crc
- source/drivers/dspi
- source/drivers/flexcan
- source/drivers/gpio
- source/drivers/i2c
- source/drivers/intmux
- source/drivers/lpi2c
- source/drivers/lpsci
- source/drivers/lpspi
- source/drivers/lpuart
- source/drivers/ltc
- source/drivers/mmcau
- source/drivers/otfad
- source/drivers/port
- source/drivers/qspi
- source/drivers/spi
- source/drivers/uart
- source/drivers/watchdog
- source/drivers/wdog32
- Choose the microseconds back-end appropriate for your processor and delete the other:
- source/drivers/microseconds/src/microseconds_pit.c
- source/drivers/microseconds/src/microseconds_sysclk.c
- Add the following paths to the project "GNU C" includes:
- source/include
- source/drivers
- Define the following symbols
| Symbol | Value |
|---|
| __DATA_RAM | _data |
| __DATA_ROM | _etext |
| __START_BSS | _bss |
| __END_BSS | _ebss |
| __STACK_TOP | _vStackTop |
| __VECTOR_RAM | __vectors_start__ |
| __VECTOR_TABLE | __vectors_start__ |
If the processor is a Cortex M7 you should additionally define
| Symbol | Value |
|---|
| CPU_IS_ARM_CORTEX_M7 | 1 |
Source Modification
Now that the source has been pruned we need to apply a few modifications to account for the new memory layout and linker files in MCUXpresso.
source/startup/crt0_gcc.S
@@ -43,10 +43,10 @@
.extern SystemInit
.extern init_data_bss
.extern main
- .extern __StackTop
+ .extern _vStackTop
.extern init_interrupts
- .extern __isr_vector
+ .extern g_pfnVectors
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
@@ -59,7 +59,7 @@ Reset_Handler:
cpsid i
// Set VTOR register in SCB first thing we do.
- ldr r0,=__isr_vector
+ ldr r0,=g_pfnVectors
ldr r1,=SCB_BASE
str r0,[r1, #SCB_VTOR_OFFSET]
@@ -77,7 +77,7 @@ Reset_Handler:
mov r12,r7
// Initialize the stack pointer
- ldr r0,=__StackTop
+ ldr r0,=_vStackTop
mov r13,r0
source/startup/startup.c
@@ -97,10 +97,10 @@ void init_data_bss(void)
#if defined(__GNUC__)
extern uint32_t __DATA_ROM[];
extern uint32_t __DATA_RAM[];
- extern char __DATA_END[];
+ extern uint32_t _edata[];
data_ram = (uint8_t *)__DATA_RAM;
data_rom = (uint8_t *)__DATA_ROM;
- data_rom_end = (uint8_t *)__DATA_END; // This is actually a RAM address in CodeWarrior
+ data_rom_end = (uint8_t *)(__DATA_ROM + (_edata - __DATA_RAM));
n = data_rom_end - data_rom;
#elif(defined(__ICCARM__))
data_ram = __section_begin(".data");source/property/src/property.c
@@ -75,14 +75,16 @@ extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
#define __ROM_START ((uint32_t)Image$$VECTOR_ROM$$Base)
#define __ROM_END ((uint32_t)Image$$ER_m_text$$Limit)
#elif(defined(__GNUC__)) // GCC
-extern uint32_t __VECTOR_RAM[];
extern uint32_t __VECTOR_TABLE[];
-extern char __DATA_END[];
+extern uint32_t __DATA_ROM[];
+extern uint32_t __DATA_RAM[];
+extern uint32_t _edata[];
extern uint32_t __STACK_TOP[];
-#define __RAM_START ((uint32_t)__VECTOR_RAM)
-#define __RAM_END ((uint32_t)__STACK_TOP - 1)
+extern uint32_t __top_RAM[];
+#define __RAM_START ((uint32_t)__STACK_TOP - 1)
+#define __RAM_END ((uint32_t)__top_RAM)
#define __ROM_START ((uint32_t)__VECTOR_TABLE)
-#define __ROM_END ((uint32_t)__DATA_END)
+#define __ROM_END ((uint32_t)(__DATA_ROM + (_edata - __DATA_RAM)))
#else
#error Unknown toolchain!
#endif // __ICCARM__
Configuration
Now we need to add the processor specific configuration. Create/import the following files for your device according to section 10 of the MCU Bootloader Reference Manual:
- bootloader_config.h
- target_config.h
- peripherals_pinmux.h
- memory_map_<device>.c
- hardware_init_<device>.c
- peripherals_<device>.c
- clock_config_<device>.c
Additionally, if you are using FlexCAN, you may need to define a "const flexcan_timing_config_t bit_rate_table[]" in source/bootloader/src/flexcan_peripheral_interface.c