Guide to Porting MCUBOOT v2 to MCUXpresso

cancel
Showing results for 
Search instead for 
Did you mean: 

Guide to Porting MCUBOOT v2 to MCUXpresso

861 Views
Contributor III

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

  1.  Download the source package from MCU Bootloader|NXP 
  2. Create a new C project in MCUXpresso for your processor with the following drivers:
    • Required for core function:
      • clock
      • port
      • gpio
      • crc
    • Optional depending on configuration:
      • flexcan
      • uart
      • dspi
      • i2c
  3. Delete the template 'main' file that MCUXpresso creates for you.
  4. Delete the semihost_hardfault.c file that MCUXpresso creates for you.
  5. 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
  6. Unzip the bootloader source
  7. Copy the contents of the NXP_Kinetis_Bootloader_2_0_0/src directory to your new project's source directory.
  8. Copy the contents of the NXP_Kinetis_Bootloader_2_0_0/targets/common/src directory to your new project's source directory
  9. Refresh the project so MCUXpresso becomes aware of the new source
  10. Delete or filter out the following directories from the bootloader source:
    • source/blfwk
    • source/blsh
    • source/bm_usb
    • source/platform
    • source/usb
    • source/security
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. Add the following paths to the project "GNU C" includes:
    • source/include
    • source/drivers
  17. Define the following symbols
SymbolValue
__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

SymbolValue
CPU_IS_ARM_CORTEX_M71

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

Tags (1)
5 Replies

56 Views
Contributor III

I am using MCUXpresso 11.1.1 In step 2, I cannot  see an option to include crc under drivers tab(where the others are).

Am I misunderstanding something?

Best regards,

Baldur

0 Kudos

56 Views
Contributor IV

Hi,

Thanks for the procedure.

On my side, I use USB to communicate with bootloader.There are extra steps to get compiling sources.

I am working on it.

I currently get an elf but it is too big in size.

If someone has managed to get bootloader compiling with USB support, I'm interrested in the procedure.

Nicolas

0 Kudos

56 Views
Contributor IV

As I said in my previous message, the executable is too big.

I tried to compile the bootloader (V2.0) for MK22F51212 with KDS 3.0. I also get a too big executable.

By too big, I mean it is more than 0xA000 bytes in size.

Bootloader seeks for application information at address 0xA000 so bootloader size has to be lower than 0xA000 bytes.

This is the case with bootloader version 1.2 I has using till now with KDS.

Any pointers on how to get a correct bootloader size ?

0 Kudos

56 Views
Contributor IV

I finaly succeeded in reducing the executable size. I had to set "Optimise for size (-Os)" option in Properties/C/C++ Build/Settings/MCU C Compiler/Optimization/Optimization Level.

0 Kudos

56 Views
NXP TechSupport
NXP TechSupport

Hello Wilkins White

Thanks for your sharing.

BR

Alice

0 Kudos