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

softdevice doesn't call app callback when the app is called from bootloader.

I am writing one bootloader to decide two apps resided in 0x14000 to 0x40000 with nrf51822 to run. Two apps works fine when starting running itself. But when bootloader switch to one app by using similar method with the sample codes of bootloader in nrf6300 experiment, like

m_nrf_start_address = 0x18000;
   (void)sd_softdevice_forward_to_application();
    StartApplication();

I can see it always enter into the app and advertising and connection already done by using Master Control Panel. But when Master Control Panel sends service discovery req, the app return nothing, i.e. the softdevice doesn't call the callback defined in the app.

If I switch the app from another app using same methods, it works fine. But the bootloader is just a very simple app, don't use any softdevice. It seems the softdevice doesn't hookup with the GATT service callback in app when using bootloader. Do I miss some steps to bind the callback into softdevice when bootloader switch to the app?

thanks,

  • I'm not quite sure I understand how you do this, but to make the softdevice function correctly, you must make sure that the interrupts are forwarded to the correct place.

    What will happen on startup is that the softdevice will check the value in the (NRF_UICR_BASE + 0x14), i.e. 0x10001014, and if that is != 0xFFFFFFFF, it will jump to this address (+4). This is where a bootloader would normally reside. When the bootloader runs, all interrupts that occur will be forwarded from the softdevice to the bootloader, i.e. to the handler located in the vector table in the bootloader. Normally, the bootloader will evaluate whether there is currently an application at the regular place, i.e. NRF_UICR->CLENR0, normally 0x14000, on start. If there is, it will call sd_softdevice_forward_to_application(), and then jump to the application at 0x14000's Reset_Handler (i.e. the address at 0x14000+4).

    Having 3 applications on the nRF51822 isn't really easily doable, but as you can see from the above, you can have one applciation that can switch to another under certain circumstances. If the applications are small it would also be possible to have to images located in flash, at addresses different from both the bootloader and the normal application space, and then make the bootloader copy the one you currently want to run to 0x14000. This should be doable if you don't need to switch very often, as switching will wear the flash, but we don't have any examples of it. As given in the PS, the flash is guaranteed to last 20000 cycles.

  • Thanks Ole,

    I set the boot loader address to the NRF_UICR register and find the SoftDevice do pass all the interrupts to boot loader. It works now.

    But I still feel a little bit confuse, why I put one app image at the address of 0x14000, but not set the NRF_UICR, the app works, even I load another app at 0x2b000, the first app can jump to second app with sd_softdevice_forward_to_application(), second app can get all interrupts from softdevice? But if I put my bootloader at 0x14000, the bootload can't get the interrupts passed by softdevice paasing to the app at 0x2b000? It looks SoftDevice pass the interrupts in two ways: 1. when nrf_uicr is not oxfffffff, it forward interrupts to the app; 2. the app can register its ISRs into SoftDevice. is it right? thanks,

  • Thanks Ole,

    I set the boot loader address to the NRF_UICR register and find the SoftDevice do pass all the interrupts to boot loader. It works now.

    But I still feel a little bit confuse, why I put one app image at the address of 0x14000, but not set the NRF_UICR, the app works, even I load another app at 0x2b000, the first app can jump to second app with sd_softdevice_forward_to_application(), second app can get all interrupts from softdevice? But if I put my bootloader at 0x14000, the bootload can't get the interrupts passed by softdevice paasing to the app at 0x2b000? It looks SoftDevice pass the interrupts in two ways: 1. when nrf_uicr is not oxfffffff, it forward interrupts to the app; 2. the app can register its ISRs into SoftDevice. is it right? thanks,

  • When (NRF_UICR_BASE + 0x14) is not 0xFFFFFFFF, all interrupts will by default be forwarded to the address written there. When this application then does a call to sd_softdevice_forward_to_application(), all interrupts will be forwarded to the application at address NRF_UICR->CLENR0.

  • Actually, I see now that my previous answer is not quite correct. When you call forward_to_application(), all interrupts will be forwarded to the application at 0x14000, no matter what CLENR0 is. I'm sorry for the misunderstanding.

Related