This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF51822 Bootloader with GCC - Code for starting the Application

While trying to get the SDK's bootloader working with gcc, I have to replace some ARMCC-speific code found in bootloader_util_arm.c:

__asm void StartApplication(uint32_t start_addr)
{
    ; Get App MSP.
    LDR   R2, [R0]
    ; Set the main stack pointer to the applications MSP.
    MSR   MSP, R2
    ; Get application reset vector address.
    LDR   R3, [R0, #0x00000004]
    ; No return - stack code is now activated only
    ; through SVC and plain interrupts.
    BX    R3
    ALIGN
}
void bootloader_util_app_start(uint32_t start_addr)
{
    StartApplication(start_addr);
}

After trying some approaches I found 2 apparently working solutions to substitute that for gcc. The 1st one is based on some code I found in Ole Mortens early bootloader implementation:


typedef void (*main_t)();
void bootloader_util_app_start(uint32_t start_addr)
{
    main_t app_main =*(main_t*)(start_addr+4);
    app_main();
}

The 2nd solution uses inline assembler:

void bootloader_util_app_start(uint32_t start_addr)
{
    // Assign app code address
    asm volatile(" LDR   R0, =0x14000          \n\t"
    // Get App MSP
                 " LDR   R2, [R0]              \n\t"
    // Set the main stack pointer to the applications MSP
                 " MSR   MSP, R2               \n\t"
    // Get application reset vector address
                 " LDR   R3, [R0, #0x00000004] \n\t"
    // No return - stack code is now activated only
    // through SVC and plain interrupts
                 " BX    R3                    \n\t"
                 " .ALIGN                    ");
}

Both solutions are working (on my desktop) but are they safe? Don't know if MSP is set right in the 1st approach.

All tested with gcc-arm-none-eabi-4_7-2013q3 and gcc-arm-none-eabi-4_8-2013q4 compiled on a linux host (kubuntu 12.04 with backports) using both Ole Mortons pure-gcc and also the original sdk gcc setup (makefiles, linkerscripts and startup code).

Parents
  • It seems that you ended up just supplying both in your other post (great work by the way!), but for completeness I can try answering this as well.

    I'd recommend you to use the latter approach, that includes manual setting of the MSP. The reason is that unless you set the MSP explicitly, the application will inherit the bootloader's stack usage at the point of starting the application, and never be able to regain this part of the RAM. This is hence just waste, and is avoided by manually setting the stack pointer to whichever value the application expects.

    When the chip resets, setting the SP to the value at address 0 is done by the CPU core, but this can obviously not be done automatically when the bootloader is just jumping to the other application, which to the CPU looks like any other function call.

    (This should be fixed in my old bootloader as well, but I haven't really looked a lot at it lately...)

Reply Children
No Data
Related