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

FreeRTOS, SVC Handler and Buttonless DFU

I am trying to get the application to enter DFU via the buttonless DFU service using SDK 15.2. It appears to be stuck because of an SVC call not returning. Both application and bootloader have NRF_DFU_BLE_REQUIRES_BONDS set to 1. Initially it hung at the call to nrf_dfu_set_peer_data() in ble_dfu_bonded.c. On looking at documentation from a previous SDK, it looks like I have to call  ble_dfu_buttonless_async_svci_init(); before ble_dfu_buttonless_init(). So I did and now, it hangs at nrf_dfu_set_peer_data_init().  

I am using FreeRTOS. Could it have to do with the SVC handler in port.c being different from the one in nrf_svc_handler.c? 

  • Any ideas? 

    Just following up on this, if I compile with the SVCALL_INDIRECT_AS_NORMAL_FUNCTION flag, I get compilation issues:

    Error pasting "(" and "nrf_dfu_set_peer_data_svci_async_t" does not give a valid preprocessing token app *\components\libraries\svc\nrf_svci.h 251
    Error unknown type name 'p_async' app *\components\libraries\svc\nrf_svci_async_function.h 159


  • For SVC calls to work, you'll need a boot loader installed which handles the SVC calls specific to the boot loader.

    Assuming you do have a functioning boot loader, have a look at the following question which highlights one issue with the use of SVC calls into the boot loader in the presence of interrupts, https://devzone.nordicsemi.com/f/nordic-q-a/38139/dfu-svci-initialisation-missing-critical-section.  You may need to add a critical section around boot loader SVC calls.

  • Thanks Austin. That is helpful to know about the interrupts. 

    I think the problem though is with the SVC handler. I just recompiled the bootloader with the nrf_svc_handler.c (initially it was using the freertos port.c) and all looks good: the ble_dfu_buttonless_async_svci_init() and all the other svci calls are running as expected. Does that mean I can't use freertos for the bootloader?

    Also as a side, my understanding is that there is only one SVC handler shared between applications (?). How do the application's freertos port.c implementation of the SVC handler work (or not work) alongside the bootloader's nrf_svc_handler? 

  • From what you've written, I get the impression that you're compiling both the boot load and application into a single binary.  This is not the expected mechanism to isolate the boot loader from the application.  Normally you would have one binary for the boot loader, and one for the application.

    Nordic's boot loader doesn't use FreeRTOS, it uses their own event loop.  You can look at the Makefile for examples/dfu/secure_bootloader in the SDK for the files which files are required to compile the boot loader.

    Your application can choose to use FreeRTOS even though the boot loader does not.  The SVC call is a mechanism to provide an interface between the application and other components in the system such as the boot loader or SoftDevice.  There's a page on Nordic info center which explains the call flow.

    From memory it works like this.  When an SVC call is made, the MBR first handles the call (this is where the vector table is stored).  The call is then passed on to the bootloader (if installed), then on to the SoftDevice, then on to the application.  Each component in the chain checks to see if the SVC call is targeted for that component and if not, looks up the vector table for the next component and calls its handler.

    There is no problem using FreeRTOS for the application and no RTOS for the bootloader, each component has its own SVC handler which makes up part of the SVC call chain.

  • No, the application and bootloader are separate binaries. I merge them (and the bl settings and softdevice) into a single hex for the initial "factory" flash. 

    Each component implementing its own SVC handler makes sense, thanks for that!


    I understand that Nordic's bootloader does not use FreeRTOS. However, I want to use FreeRTOS for the bootloader to use a particular freertos based library (the application also uses FreeRTOS). My issue is that port.c implements an SVC Handler that does not appear to work with the DFU service. There might be more issues too like managing the event loop as you mentioned so if it sounds like it'll complicate things, I can reconsider using that FreeRTOS library. Any thoughts on freertos based DFU bootloader?


Related