USB MSD Bootloader Implementation

Document created by jeremyzhou Employee on Aug 12, 2016
Version 1Show Document
  • View in full screen mode

Overview

         KBOOT v2.0 had been released in the Q2 of the 2016 and it has a lot of new features versus the previous version. For instance, the USB peripheral can work as Mass Storage Class device mode now, not just only supports the HID interface. And in following, USB MSD Bootloader implementation will be illustrated.

Preparation

  1. FRDM-K64F board

Fig1 FRDM-K64F

 

  1. KBOOT v2.0 downloading: KBOOT v2.0
  2. IDE: IAR v7.50
  3. Application demo: KSDK v2.0

  Flash-resident bootloader

          The K64_120 doesn’t contain the ROM-based bootloader, so the flash-resident bootloader need to be programmed in the K64 and the flash-resident bootloader can be used to download and program an initial application image into a blank area on the flash, and to later update the application.

        I. Open the the bootloader project, for instance, using the IAR and select the freedom_bootloader demo

        The Fig 2 illustrates the bootloader project for K64 which resides in ~\NXP_Kinetis_Bootloader_2_0_0\NXP_Kinetis_Bootloade
r_2_0_0\targets\MK64F12.

Fig 2

     II. After compiles the demo, then clicks the  button to program the demo to the K64

Linker file modification

      According to the freedom_bootloader demo, the vector table relocation address of the application demo has been adapted to the 0xa000 (Table 1), however the default start address of the application is 0x0000_0000. So it’s necessary to modify the linker file to fit the freedom_bootloader and the Table 2 illustrates what the modifications are.

                                                    Table 1

// The bootloader will check this address for the application vector table upon startup.

#if !defined(BL_APP_VECTOR_TABLE_ADDRESS)

#define BL_APP_VECTOR_TABLE_ADDRESS 0xa000

#endif

 

                                                  Table 2

define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;

define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;

 

//define symbol m_interrupts_start       = 0x00000000;

//define symbol m_interrupts_end         = 0x000003FF;

 

define symbol m_interrupts_start       = 0x0000a000;

define symbol m_interrupts_end         = 0x0000a3FF;

 

//define symbol m_flash_config_start     = 0x00000400;

//define symbol m_flash_config_end       = 0x0000040F;

 

define symbol m_flash_config_start     = 0x0000a400;

define symbol m_flash_config_end       = 0x0000a40F;

 

//define symbol m_text_start             = 0x00000410;

 

define symbol m_text_start             = 0x0000a410;

define symbol m_text_end               = 0x000FFFFF;

 

define symbol m_interrupts_ram_start   = 0x1FFF0000;

define symbol m_interrupts_ram_end     = 0x1FFF0000 + __ram_vector_table_offset__;

 

define symbol m_data_start             = m_interrupts_ram_start + __ram_vector_table_size__;

define symbol m_data_end               = 0x1FFFFFFF;

 

define symbol m_data_2_start           = 0x20000000;

define symbol m_data_2_end             = 0x2002FFFF;

 

/* Sizes */

if (isdefinedsymbol(__stack_size__)) {

  define symbol __size_cstack__        = __stack_size__;

} else {

  define symbol __size_cstack__        = 0x0400;

}

 

if (isdefinedsymbol(__heap_size__)) {

  define symbol __size_heap__          = __heap_size__;

} else {

  define symbol __size_heap__          = 0x0400;

}

 

define exported symbol __VECTOR_TABLE  = m_interrupts_start;

define exported symbol __VECTOR_RAM    = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;

define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;

 

define memory mem with size = 4G;

define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end];

define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]

                          | mem:[from m_text_start to m_text_end];

define region DATA_region = mem:[from m_data_start to m_data_end]

                          | mem:[from m_data_2_start to m_data_2_end-__size_cstack__];

define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end];

define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end];

 

define block CSTACK    with alignment = 8, size = __size_cstack__   { };

define block HEAP      with alignment = 8, size = __size_heap__     { };

define block RW        { readwrite };

define block ZI        { zi };

 

initialize by copy { readwrite, section .textrw };

do not initialize  { section .noinit };

 

place at address mem: m_interrupts_start    { readonly section .intvec };

place in m_flash_config_region              { section FlashConfig };

place in TEXT_region                        { readonly };

place in DATA_region                        { block RW };

place in DATA_region                        { block ZI };

place in DATA_region                        { last block HEAP };

place in CSTACK_region                      { block CSTACK };

place in m_interrupts_ram_region            { section m_interrupts_ram };

 

SB file generation

    I. Brief introduction of SB file

        The Kinetis bootloader supports loading of the SB files. The SB file is a Freescale-defined boot file format designed to ease the boot process. The file is generated using the Freescale elftosb tool. The format supports loading of elf or srec files in a controlled manner, using boot commands such as load, jump, fill, erase, and so on. The boot commands are prescribed in the input command file (boot descriptor .bd) to the elftosb tool. The format also supports encryption of the boot image using AES-128 input key.

         And right now, the USB MSD bootloader only support SB file drag and drop.

   II. Generate the BIN file

        After open the hello_world demo in the IAR, using project options dialog select the "Output Converter" and change the output format to "binary" for outputting .BIN format image (Fig 3). Next, build the application demo, then the .BIN file will be generated after the building completes.

Fig 3

 

     III. Create BD file

There is a template BD file which resides in the ~\NXP_Kinetis_Bootloader_2_0_0\NXP_Kinetis_Bootloader_2_0_0\apps\led_demo\src. Next, adapt the BD file by referring to the Kinetis Elftosb User's Guide, the following table shows the BD file content.

                                                   Table 3

sources {

        # BIN File path

        myBINFile = "hello_world.bin";

}

 

section (0) {

        #1. Erase the internal flash

        erase 0x0000a000..0x0010000;

        #2. Load BIN File to internal flash

        load myBINFile > 0xa000;

        #3. Reset target.

        reset;

}

     IV.  SB file generation

         After creating the BD file shown in the following figure, copy the "hello_world.bin", elftosb.exe, and the BD file into the same directory. Then, open the window with command prompt and invoke
elftosb such as “elftosb –V –c FRDM-K64F.bd –o image.sb”. The elftosb processes the FRDM-K64F.bd file and generates an
image.sb file. Elftosb also outputs the commands list as shown in Fig 4.

Fig 4

    V. Application code updating

      Plug a USB cable from the PC to the USB connector J26 to power the board , then keep holding the button SW2 down until press and release the Reset button SW1, it can force the K64_120 enter the BOOTLOADER mode. Next, plug another USB cable from the PC to the USB connector J22 (Fig 5), the FSL Loader will come out after completes the enumeration and it will appear as a removable storage driver (Fig 6).  Copy & paste or drag & drop the image.sb to the FSL Loader drive to update the application code, and the Fig 7 illustrates the result of application code runs.

Fig 5

Fig 6

Fig 7

 

 

 

 

 

 

 

 

 

 

 

 

 

1 person found this helpful

Attachments

Outcomes