This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

simple bootloader stopped working

Hi,

My application uses the nrf9160dk and I program 3 Zephyr images onto the 52840: (1) bootloader, (2) image1 and (3) image2. There is no SD or anything else on the device. The bootloader will boot either image1 or image2 based on the contents of the GPREGRET register upon boot. When one of the images is running and needs to reboot, it will set GPREGRET via sys_reboot(), if it matters.

The attached code works fine when using NCS v1.2, however when I build using NCS 1.4.1 it does not work. Working means that the subsequent image boots successfully. I have tried adding calls to the following, in various combinations, in launch_image():

  • nrf_cleanup_peripheral() (copied from mcuboot's nrf_cleanup.c)
  • cleanup_arm_nvic() (copied from mcuboot's arm_cleanup.c)

I also tried changing prj.conf which is:

CONFIG_BOOT_BANNER=n
CONFIG_ERRNO=n
CONFIG_MINIMAL_LIBC=n
CONFIG_SIZE_OPTIMIZATIONS=n
CONFIG_RUNTIME_ERROR_CHECKS=n
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_DEPRECATED_ZEPHYR_INT_TYPES=y
(original prj.conf only had the CONFIG_BOOT_BANNER=n, but these additional settings were just experiments and didn't seem to make a difference).
How do I make this work?
Mike

// register addresses per the nrf52 documentation
#define POWER_REG_BASE      0x40000000
#define GPREGRET            (POWER_REG_BASE + 0x51c)    // retention register
#define RESETREAS           (POWER_REG_BASE + 0x400)    // reset reason

typedef void *ADDR;

#define IMAGE1 ((ADDR)IMAGE1_OFFSET)   // 0x6000
#define IMAGE2 ((ADDR)IMAGE2_OFFSET)   // 0x14000

static __inline
void jump_to_addr( ADDR new_msp, ADDR new_lr, ADDR addr )
{
    __asm volatile ("MSR MSP, %[arg]" : : [arg] "r" (new_msp));
    __asm volatile ("MOV LR,  %[arg]" : : [arg] "r" (new_lr) : "lr");
    __asm volatile ("BX       %[arg]" : : [arg] "r" (addr));
}

void launch_image( ADDR *vector_table )
{
    ADDR new_msp         = vector_table[0];     // Stack Pointer
    ADDR reset_handler   = vector_table[1];     // Reset Handler
    ADDR new_lr          = (ADDR)0xFFFFFFFF;

    printk( "new_msp %08x\n", new_msp );
    printk( "new_lr %08x\n", new_lr );
    printk( "reset_handler %08x\n", reset_handler );
    jump_to_addr( new_msp, new_lr, reset_handler ); // Jump directly to the App's Reset Handler.
}

void main()
{   
    ADDR vector = NULL;
    uint32_t *reg = (uint32_t *)GPREGRET;

    if( *reg == 0 )
        vector = IMAGE1;
    else
        vector = IMAGE2;

    // reset the register
    *reg = 0;

    printk( "booting vector %p\n", vector );
    launch_image( vector );
}

Related