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

Unable to understand the steps to perform OTA DFU for ESB application on nRF52840

Dear DevZone,

I developed an application based on ESB wireless communication protocol for the nRF52840, and I would like to perform an OTA DFU with it.

I read in this ticket that a possible solution in this case is to leave the softdevice flashed, write your own transport layer for the ESB and use the bootloader provided from Nordic - which is transport agnostic (see also the figure below):

I have two questions about this:

  • Do you suggest me to proceed as mentioned there?
  • If yes, could you provide me some documentation or give me some hints about the steps to follow to perform this procedure?

Again, concerning the same issue, I have also another doubt:

  • Does the above mentioned approach coincide with the one described by Nordic here ('Extending your application to support the BLE DFU Service')? I can't understand if this last one is feasible only for BLE applications or not and, in case not, which approach is better and why.

Thank you very much in advance,

Best regards,

Gianluca

Parents
  • Hi,

    Do you suggest me to proceed as mentioned there?

    No. This post is quite old, and since then the bootloader has been updated to not rely on the SoftDevic (unless you need a BLE transport). You can refer to the serial bootloader examples to see to use the bootloader without a SoftDevice. Essentially there is no difference other than the transport since there are libraries that abstract away the difference with and without SoftDevice (most importantly fstorage). The MBR is needed, but that is available separately, and not just as part of a SoftDevice.

    If yes, could you provide me some documentation or give me some hints about the steps to follow to perform this procedure?

    There is no explicit guide for making a new transport, but you can refer to the existing implementations and the documentation for the DFU protocol.

    Does the above mentioned approach coincide with the one described by Nordic here ('Extending your application to support the BLE DFU Service')? I can't understand if this last one is feasible only for BLE applications or not and, in case not, which approach is better and why.

    This section described how to add support for buttonless DFU. Essentially a way to trigger DFU from the application instead of signaling it by for instance holding a button while resetting. In the BLE context, we provide an example using a BLE service, and the possibility to share BLE bonding information between the application and bootloader. For ESB this would probably be as simple as just writing to GPREGRET and performing a soft reset.

  • Ok thank you very much Einar, I will start following your suggestions.

    So, do you think I could start from the serial bootloader example as base for my bootloader, or is it the same also if I use the BLE one and then I proceed registering the ESB transport layer ?

  • Hi,

    It does not matter where you start really, as in the bootloader the only difference is the transport. The only difference is that the example with the BLE transport includes the SoftDevice and the serial bootloader examples only include the MBR. But that is just a matter of a few preprocessors defines, includes, flash layout, etc, but the code would be the same (and you can easily change later).

  • Dear Einar, 

    thank you very much for your answer, I am studying the material available in the InfoCenter.

    I also found this post in which a UART transport layer is added starting from the BLE bootloader example. 

    I saw that the tranport layer is registered through DFU_TRANSPORT_REGISTER within some specific files (nrf_dfu_ble.c for BLE and nrf_dfu_serial_uart for UART). Here, the uart and ble DFU transport initialization functions are defined (uart_dfu_transport_init for instance), see the figure below:

    I have a question:

    • could you help me in understanding which is the approach I have to follow to build the same function for ESB?
    • Is this needed for achieving my goal? Or is there a simpler way?

    Thank you very much in advance, 

    best regards,

    Gianluca

  • Gianluca,

    This is the correct approach, yes. I suggest you just refer to existing implementation (perhaps serial UART as that is simplest), and implement corresponding functionality for ESB. That men's that the following files are most relevant:

    • components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
    • components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c

    You will have to implement the same as these files, but using ESB instead of UART.

    Einar

  • Dear Einar,

    following your suggestions I started going through the nrf_dfu_serial_uart.c file.

    Looking line by line, I firstly tried to understand the main commands to be replicated, then I focused more on the details.

    The commands that I would start to bring to the new file for ESB are the following:

    • The call to the BALLOC_DEF function, which is present also in the BLE example and which in the UART example is given by the following line:

    NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS);
     

    • The call to the initialization functions for the dfu transport, here the lines for uart:

    static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer);
    static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception);

    • The call to the REGISTRATION MACRO:

    DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const uart_dfu_transport) =
    {
        .init_func  = uart_dfu_transport_init,
        .close_func = uart_dfu_transport_close,
    };

    • The definition of the transport initialization function in which I would put 
      • the call to the nrf_balloc_init
      • the call to the balloc_alloc
      • the call to the ESB init
    • the definition of the transport closing function similar to the uart one

    Questions

    Now, I still have some very important doubts:

    • which are the parameters that I have to choose for the BALLOC_DEF in the ESB case? Are the ones chosen for the UART ok? I saw that for BLE are different and defined through weird functions

    NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS);

    • I saw that the nrf_drv_uart_init, which initializes the uart driver:

       err_code =  nrf_drv_uart_init(&m_uart, &uart_config, uart_event_handler);

                 has some parameters such as the uart_event_handler and the uart_config which depend from structures that are specifically  designed for DFU, such as the m_serial (which is complex because composed by other functions). The question is: can I initialize the ESB transport without these complex parameters? If not, how is possible to understand how to translate these parameters for the nrf_esb_init?

    • Finally, I would like to ask you as expert if you could tell me an estimation on the effort needed to perform this task: initially I thought it could be an easy process having the support of the examples, but now I'm finding them a little bit cryptic.

  • Hi,

    Gianlucamilani said:
    which are the parameters that I have to choose for the BALLOC_DEF in the ESB case? Are the ones chosen for the UART ok? I saw that for BLE are different and defined through weird functions

    This is to allocate memory buffers for handling the incoming data. You probably need something similar, but it all depends on your implementation. There is nothing in the architecture that dictates that a transport layer must use NRF_BALLOC.

    Gianlucamilani said:
    The question is: can I initialize the ESB transport without these complex parameters? If not, how is possible to understand how to translate these parameters for the nrf_esb_init?

    Yes, you can. This is just a part of the internal transport layer implementation. Specifically, m_serial is nrf_dfu_serial_t, which is there because it is shared between the USB and UART transport. Most of this may not make sense in your ESB transport implementation. Perhaps you should refer to the BLE and ANT transports as well, to see alternative ways of doing it. Essentially the transport itself is all up to you, and the main thing you need to do is to provide the init and close functions to the bootloader, and handle the communication with the DFU master and call nrf_dfu_req_handler_on_req(), where you can use nrf_dfu_serial.c and other transports as reference. It is not straight-forward, but I think it is a good idea to spend some time with the existing transport layers to understand what is generic, and what is just transport-specific (or implementation-specific).

    Gianlucamilani said:
    if you could tell me an estimation on the effort needed to perform this task: initially I thought it could be an easy process having the support of the examples, but now I'm finding them a little bit cryptic.

    It is difficult to estimate. You have other backends to reference, but there is quite a bit you need to understand, and then do the implementation. You also need to implement the DFU master that will do the upgrade over ESB, so you don't have anything known good to start testing with. I cannot say how many days or weeks you need, though.

Reply
  • Hi,

    Gianlucamilani said:
    which are the parameters that I have to choose for the BALLOC_DEF in the ESB case? Are the ones chosen for the UART ok? I saw that for BLE are different and defined through weird functions

    This is to allocate memory buffers for handling the incoming data. You probably need something similar, but it all depends on your implementation. There is nothing in the architecture that dictates that a transport layer must use NRF_BALLOC.

    Gianlucamilani said:
    The question is: can I initialize the ESB transport without these complex parameters? If not, how is possible to understand how to translate these parameters for the nrf_esb_init?

    Yes, you can. This is just a part of the internal transport layer implementation. Specifically, m_serial is nrf_dfu_serial_t, which is there because it is shared between the USB and UART transport. Most of this may not make sense in your ESB transport implementation. Perhaps you should refer to the BLE and ANT transports as well, to see alternative ways of doing it. Essentially the transport itself is all up to you, and the main thing you need to do is to provide the init and close functions to the bootloader, and handle the communication with the DFU master and call nrf_dfu_req_handler_on_req(), where you can use nrf_dfu_serial.c and other transports as reference. It is not straight-forward, but I think it is a good idea to spend some time with the existing transport layers to understand what is generic, and what is just transport-specific (or implementation-specific).

    Gianlucamilani said:
    if you could tell me an estimation on the effort needed to perform this task: initially I thought it could be an easy process having the support of the examples, but now I'm finding them a little bit cryptic.

    It is difficult to estimate. You have other backends to reference, but there is quite a bit you need to understand, and then do the implementation. You also need to implement the DFU master that will do the upgrade over ESB, so you don't have anything known good to start testing with. I cannot say how many days or weeks you need, though.

Children
No Data
Related