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?

  • Correct, that should be handled by the bootloader. It's already implemented like that in our current serial bootloader in  examples\dfu. 

  • Thanks. There are two examples pca10040_uart and pca10040e_uart  in ../examples/dfu/secure_bootloader.  I assume they both are exactly same except that the latter use easy DMA. Could you please confirm.

  • The PCA10040e is for nRF52810 emulation on PCA10040, you can have a look here.

  • That is new information for me, thanks.

    It appears that the UART port pin assignment, configuration and registration as DFU transport are handled in ../components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c.

  • I would suggest to test the bootloader with nRFutil on PC first to get familiar to it before you move to other tasks. 

Reply Children
  • Hi Hung,

    For switching to the bootloader, the APIs (sd_power_gpregret_clr, sd_power_gpregret_set) to write to the retention register GPREGRET are part of the SoftDevice library.  That means I must flash SoftDevice in my board. Alternative is to use NRF_POWER->GPREGRET available in nrf52.h that will not require me to use the SoftDevice. Seems I am on the right track?

  • Yes you are correct. After you write to GPREGRET, you just need to trigger a reset to enter bootloader. 

  • Hi Hung,

    I made some progress but not enough.

    - I successfully compiled the secure uart bootloader  nRF5_SDK_17_0_2_d674dde/examples/dfu/secure_bootloader/pca10040_uart by following the exact same procedure as outlined in your tutorial.

    - Adapted my application code such that at the push of a button (on my device) the application set the first bit in GPREGRET and do soft power switching of the nRF52832. I have verified, the setting of bit and power switching are happening as expected.

    I flashed the .hex file of the bootloader and the application using the Programmer tool that is a part of the nRF Connect v3.6.1 application.

    My application works correctly. However, when I push the button to switch to bootloader, the device does not enter into the bootloader (although the application captures the push button event, set the bit and successfully do soft power reset) but again launch the application. I must be doing something wrong, or have missed a critical step. Could you please see.

    Kind regards

  • Please try debugging the bootloader, you can put a breakpoint in dfu_enter_check() in nrf_bootloader.c It's where the bootloader check if it would need to enter DFU mode or not. 

    You may need to compile the bootloader in debug mode (no optimization) to be able to put breakpoint and step in the code of the bootloader. 

    I assume that you have tested the functionality of the bootloader (DFU update) and also know how to create bootloader settting etc. 

    Please also try testing that you can enter the bootloader by holding a button when you reset. 

  • - When I set the optimization level to zero, for debugging the bootloader,  I get the following errors:

    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: .text is too large to fit in FLASH memory segment
    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: .dfu_trans is too large to fit in FLASH memory segment
    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: .nrf_balloc is too large to fit in FLASH memory segment
    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: .fs_data is too large to fit in FLASH memory segment
    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: .rodata is too large to fit in FLASH memory segment
    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: .data is too large to fit in FLASH memory segment
    ../SEGGER Embedded Studio for ARM 4.52c/gcc/arm-none-eabi/bin/ld: error: section .tdata overlaps absolute placed section .mbr_params_page

    For  optimization level > 0, some break points show message no code for breakpoint. Anyway I noticed that the bootloader repeatedly enters and exits the main() function. Not sure if it is normal behavior?

    - From your tutorial, I know how to create the bootloader setttings file. But I must say I still struggling to comprehend the complete sequence to flash the bootloader, and the application.

Related