Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Firmware Update over UART Interface

Hello,

Background: I have a custom board that contains nRF52832 module and exposes UART pins (RX, TX, RTS, CTS). I have developed an application using nRF5 SDK v17.0.2. The application does not use any so -called SoftDevice.

Objective: I want to develop a mechanism to update the application firmware of on the nRF52832 module over the UART interface from another micro-controller.

Seeking Help: After searching through the SDK and the forum, it looks like I have to use libraries under Bootloader and DFU modules But I am still confused which components to use and in what order. On the nRF52832 module, do I need to program, as part of my application, routines to receive and process DFU commands/data packets. I am also using the same UART port to exchange application data (from sensors attached sensors )  with the other micro-controller.

I would appreciate any help that can get me started on the right path to achieve the objective.

Parents
  • Hi Jatala, 

    I would suggest you to get started with our uart bootloader located inside examples\dfu folder. There are 2 options, secured DFU and open DFU. It depends on your need you can choose to use one. 

    The DFU example allow you to do DFU via UART from either PC (nrfutil.exe on PC) or from external MCU (official example is not included). 

    I have made an example of doing DFU from one MCU to another MCU here.

    I would suggest to get familiar with these resource first, so that you can do DFU from one MCU to another MCU. 

    What's missing here is to combine that to your application. What you want to achieve may be accomplished by implementing a command to switch from your application to the bootloader and from there the bootloader can receive the image and update the application. The limitation is that your application will be stopped when the bootloader receiving the image. But the advantage is that you only need to switch to the bootloader, and don't need to modify anything. 
    Another option is to implement background DFU where your application will receive the image and then only switch to the bootloader to swap the image. This would require some implement on your application code to receive image that we don't have example code for now. 

    Note that the bootloader, when not to be used with the softdevice would need the MBR to be flashed to run. Please refer to the bootloader documentation. 

  • Hi Hung,

    Thanks for the insight. I will go though the sources that you have pointed out and will come back to this thread if stumbled upon any issue.

    The first approach seems simpler to implement. "...implementing a command to switch from your application to the bootloader and from there the bootloader can receive the image and update the application", so in this case, the bootloader will be responsible to receive the application over the UART. But how the configuration and registration of the UART will be handled. I suppose it has to done from my application, right?

  • I meant just do a DFU update, without trying to implement switching to DFU from application. 

  • That is clear. To 'increase the allocated flash for bootloader', I need to change of the start address of the bootloader, but I do not see such a parameter in the project flash_placement.xml file.  I also do not see any option in the SEGGER project options.  Any idea how to go about it.

  • Hi Jatala, 

    You can follow what we have in the _debug bootloader. For example here you have the project setting with 100kB of flash reserved for the bootloader: 

  • Hi Hung,

    Thanks. I tested the bootloader in debug mode and apparently the bootloader throws an error from the UART port, please see attached call-stack trace where I have marked the code lines in respective functions where failure is occurring.  

    I noticed that in sdk_config.h both UARTE and UART drivers are enabled, not sure if this is causing the error.

  • Hi, 

    Please show the log you have on RTT viewer. Basically we need to know which function throwed the error and which error code. 

    Please try to test the secure bootloader debug project with no modification and list the steps you did for testing. 

Reply Children
  • I tested the secure bootloader debug project. It seems to work fine. But the bootloader program crashes when I change the UART pin assignment in pca10040.h  as follows.

    Original Changed
    #define RX_PIN_NUMBER  8
    #define TX_PIN_NUMBER  6
    #define CTS_PIN_NUMBER 7
    #define RTS_PIN_NUMBER 5
    #define RX_PIN_NUMBER  11
    #define TX_PIN_NUMBER  5
    #define CTS_PIN_NUMBER 7
    #define RTS_PIN_NUMBER 6

    Following is the RTT viewer log:

    <info> app: Inside main
    00> <debug> app: In nrf_bootloader_init
    00> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00> <debug> nrf_dfu_settings: Using settings page.
    00> <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00> <debug> app: Enter nrf_bootloader_fw_activate
    00> <info> app: No firmware to activate.
    00> <info> app: Boot validation failed. No valid app to boot.
    00> <debug> app: DFU mode because app is not valid.
    00> <info> nrf_bootloader_wdt: WDT is not enabled
    00> <debug> app: in weak nrf_dfu_init_user
    00> <debug> app: timer_stop (0x20000024)
    00> <debug> app: timer_activate (0x20000024)
    00> <info> app: Entering DFU mode.
    00> <debug> app: Initializing transports (found: 1)
    00> <debug> nrf_dfu_serial_uart: serial_dfu_transport_init()
    00> <debug> nrf_dfu_serial_uart: serial_dfu_transport_init() completed
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00> <debug> app: Enter main loop
    00> <error> app: Received an error: 0x00000004!

    I did a few more tests where I changed  RX_PIN_NUMBER to 8, 9, 10, 11, 12, 13. The same error occurs for pin 9, 10, 11 but not for the others. My challenge is in my board the pin 11 is used as RX and is interfaced with another board (cannot change this pin assignment). So either the same pin number is used for some other purpose in the bootloader program, although I do not see that in the code. Or some special configuration has to be applied to configure this pin as UART_RX.

  • Hi, 

    Error 4 you see is most likely the UART FRAMING error. Please check the ERRORSRC in the UART peripheral in the nRF52 spec. 

    If you add a breakpoint inside uart_event_handler() in nrf_dfu_serial_uart.c you may catch the error. 

    I would suggest to test with normal UART example and make sure it works first. 

    If normal application works but not the bootloader, you may want to hook a logic analyzer to check if the communication would work properly. 
    I don't see any reason why RX pin doesn't work with pin 9 10 11. 

  • Hi,

    - Error 4 value in  ERRORSRC register corresponds to TX buffer over-read... what link UART RX pin has with the TX buffer?

    - Captured the error in the uart_event_handler() and it shows error_mask = 0x0000000C.  Could not find in the SDK any description of this error-mask!

    - In normal application program I am using the same UART port (to send and receive data, but without hardware flow-control) and never faced any problem. 

    I would appreciate any thought that could be helpful.

  • Hi Jatala, 
    In your screenshot it's chapter 34 are you sure it's about UART ? UARTE and UART is on chapter 35 and 50. 

    What you showed in the screenshot is for TWI. 

    0x0C in the error mask meant both FRAMING and BREAK got error. 

  • Thanks for the correction. I am wondering why with the Rx pin, such an error is thrown. 

Related