After bootloading a program, how to automatically start it on reboot?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

After bootloading a program, how to automatically start it on reboot?

Jump to solution
733 Views
robertpoor
Senior Contributor I

Summary:

Once I've downloaded a program using the flash bootloader, how do I arrange things so on the next reboot, it launches the program (rather than the bootloader)?

Details:

I've adapted a flash bootloader for the KL27Z.  As far as I can tell, it has successfully downloaded a small test program:

[~]$ blhost -p /dev/cu.usbmodem219,115200 flash-image blinky.hex 1
Ping responded in 1 attempt(s)
Inject command 'flash-image'
Successful generic response to command 'flash-erase-region'
Successful generic response to command 'flash-erase-region'
Wrote 192 bytes to address 0x8000
Successful generic response to command 'write-memory'
(1/2)100% Completed!
Successful generic response to command 'write-memory'
Wrote 7756 bytes to address 0x8400
Successful generic response to command 'write-memory'
(2/2)100% Completed!
Successful generic response to command 'write-memory'
Response status = 0 (0x0) Success.

Note that blinky.hex has slightly non-standard memory map: I've modified the MKL27Z64xxx4_flash.ld so the code starts at 0x8000 rather than the normal 0x0000 so it doesn't overwrite the resident flash loader:

/* Specify the memory areas */
MEMORY
{
  m_interrupts          (RX)  : ORIGIN = 0x00008000, LENGTH = 0x00000200
  m_flash_config        (RX)  : ORIGIN = 0x00008400, LENGTH = 0x00000010
  m_text                (RX)  : ORIGIN = 0x00008410, LENGTH = 0x0000FBF0
  m_usb_sram            (RW)  : ORIGIN = 0x040FE000, LENGTH = 0x00000200
  m_data                (RW)  : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000
}

After loading the blinky.hex file, the flash boloader is still resident, and it gets started upon reboot.  It examines the valued stored for sp and pc to decide if there's a valid program to run:

    uint32_t *vectorTable = (uint32_t*)APPLICATION_BASE;
    uint32_t sp = vectorTable[0];
    uint32_t pc = vectorTable[1];

So I believe my real questions are:

  • How do I discover the proper values for sp and pc in order to launch blinky.hex?
  • How do I insert sp and pc into memory addresses APPLICATION_BASE[0] and APPLICATION_BASE[1] in the .hex file so they are properly set up after the .hex file is loaded?  Ideally this would be automatic, rather than a manual edit.

Or is this the wrong way to go about it?

Tags (1)
0 Kudos
1 Solution
498 Views
robertpoor
Senior Contributor I

I believe the answer posted in How to make KBOOT jump to main()? gives me the answer I need.  Although, upon reflection, I don't need it.

In my case, I realized that what I need is really to embed the bootloader directly into my application: After the system reboots, it waits for a preset amount of time (e.g. 10 seconds) for a valid bootloader command.   If received, it enters bootloader mode, and will stay there until the user (or blhost) issues a `reset` command.  If no valid bootloader command is received within the ten second window, it will simply call the main entry point of my code.

Since the bootloader is compiled along with my application code, the entry point is automatically known.

In short, the guts of the bootloader are unchanged.  Only the way is it invoked is non-standard.  This feels like a clean and simple approach.

View solution in original post

1 Reply
499 Views
robertpoor
Senior Contributor I

I believe the answer posted in How to make KBOOT jump to main()? gives me the answer I need.  Although, upon reflection, I don't need it.

In my case, I realized that what I need is really to embed the bootloader directly into my application: After the system reboots, it waits for a preset amount of time (e.g. 10 seconds) for a valid bootloader command.   If received, it enters bootloader mode, and will stay there until the user (or blhost) issues a `reset` command.  If no valid bootloader command is received within the ten second window, it will simply call the main entry point of my code.

Since the bootloader is compiled along with my application code, the entry point is automatically known.

In short, the guts of the bootloader are unchanged.  Only the way is it invoked is non-standard.  This feels like a clean and simple approach.