SoftDevice crash after custom bootloader handover – peripheral state conflict (USB/RTC/SPI)

Symptoms: 

  • When running Bootloader + SoftDevice + App (with SoftDevice enabled in the app), The bootloader runs correctly and starts SD. The app is started, but crashes on the first use of USB, RTC timer (used for logging), or SPI.
  • When running Bootloader + SoftDevice + App (with no SoftDevice use in the app, and manual VTOR overwrite), the system runs perfectly, except for the disabled BLE
  • When running SoftDevice + App (with SoftDevice enabled in the app, no bootloader), everything works, including BLE.

What we’ve tried:

  • Make the bootloader run straight to app (at 0x27000). That worked but initializing the Softdevice (present at 0x1000) made application crash. According to fora, this is not the way to go.
  • Make bootloader start the SD at default address, and have the app at default address. That gives the result listed in the symptoms.

I have noticed that our custom bootloader initializes some peripherals, that the stock BL does not use. RTC and USB for log (NOT NRF_LOG) and SPI for external flash. I have tried using the NRF_LOG, and not initialize the rtc, but that did not work.

We do not need DFU or Softdevice during boot, as the application handles copying incoming fw updates (over lte) to external flash, and the bootloader successfully copies the application to default address (0x27000) if necessary.

Summary:

  • The problem appears to be related to the state of peripherals left by the bootloader, which conflicts with the SoftDevice and app initialization.
  • Manual VTOR overwrite and not using the SoftDevice in the app avoids the issue, suggesting a handover/initialization conflict.
  • Deinitializing peripherals in the bootloader (to ensure a clean handover) causes a crash, so a safe deinit sequence is not yet found.
Parents
  • Hi,

    Are you able to provide a bit more detail about the nature of the crash? If you pause the debugger, can you see where the program ends up after it crashes? Since it happens when you start using these peripherals, I’m wondering if it could be related to interrupt forwarding.

    Make the bootloader run straight to app (at 0x27000). That worked but initializing the Softdevice (present at 0x1000) made application crash. According to fora, this is not the way to go.

    It is possible to jump branch directly to the app from the bootloader but that requires the bootloader to execute the Softdevice's reset handler prior to jumping. This will not make any practical difference.

    I have noticed that our custom bootloader initializes some peripherals, that the stock BL does not use. RTC and USB for log (NOT NRF_LOG) and SPI for external flash. I have tried using the NRF_LOG, and not initialize the rtc, but that did not work.

    It’s generally good practice for the bootloader to reconfigure any peripherals it uses back to their reset state before branching to the application to ensure that the app always boots into the same known state.

    Best regards,

    Vidar

  • Hey,

    Below is what I’m seeing regarding the crash behavior.

    With USB inserted:
    This is how it crashes when USB is connected.



    Without USB inserted:
    Here is the call stack at the point of the crash when the device runs without USB connected.



    I’ve also tried explicitly deinitializing the peripherals used by the bootloader before jumping on. I’m calling the deinit routines for CDC (USB) and I2C once the bootloader is done using them, so they should be re-initialized cleanly by the application after the jump.

    Despite this, the crash behavior remains the same.

    For completeness: I2C is not used or initialized in the bootloader at all, so it should already be in its reset state when the application starts.

  • Hi,

    Thanks. As you can see from the call stacks, the exception handlers are being executed at invalid addresses (0x1200400 and 0x20040000). The latter is the typical initial stack pointer value and is also the first entry in the Cortex-M vector table, which is suspicious. The issue is clearly related to interrupt handling.

    After reaching main() in the application, please read out the value at 0x20000000 and 0x20000004. These hold the interrupt forwarding address for the MBR and Softdevice respectively (expected values are: 0x1000 and 0x27000).



  • I’ve checked the values after reaching main() in the application.

    At:

    • 0x200000000x00001000

    • 0x200000040x00027000

    These match the expected interrupt forwarding addresses for the MBR and SoftDevice. I’ve attached a screenshot showing the memory view for reference.

    Please let me know if you’d like me to check anything else or perform additional diagnostics.

    Here is the linker script for the one with the softdevice:


    And for the one without:

  • Thank you. This wasn't the result I expected. Could you please read out the vector tables as well?

    nrfjprog --memrd 0x0 --n 0x104 > mbr.txt

    nrfjprog --memrd 0x1000 --n 0x104 > softdevice.txt

    nrfjprog --memrd 0x27000 --n 0x104 > app.txt

    And also just to confirm, the bootloader is not changing the VTOR register in this case?

  • I think you are onto something with you last comment. When making the bootloader initialy for another usecase (The one with the xflash setup you also helped with) - I added this VTOR change just before jumping to the application at 0x1000. 



    Without this the application wouldnt start. But when using the bootloader with softdevice, the softdevice might handle this??

    Now when testing the setup with the softdevice it seems to work when i remove the VTOR from the screenshot. Ill have to do some more testing, i will let you know.

  • You have likely found the root cause. The softdevice architecture requires that interrupts are routed through the MBR and Softdevice before they are forwarded to the application. But by setting VTOR to 0x1000 you are effectively bypassing the MBR causing the Softdevice to receive the interrupts directly without being pre-processed by the MBR. 

Reply Children
Related