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

How to use external app firmware update

Hi,

I would like to use external app firmware to update over BLE a secondary microncontroler behind a NRF52832. I read that it's an experimental feature but it's very intersting because this avoids to implement an other mecanism in mobile application to update the other MCU.

I already developped the DFU over BLE for application, bootloader and soft device. I now try to make work the external app update.

SDK 17.0.2, SoftDevice s112

The process I imagine :

  • Run the NRF52 in DFU mode
  • Upload the external firmware (in Bank 1 to preserve app in Bank 0)
  • Once done, run boot the secondary MCU by driving GPIO (nReset/Boot)
  • Send the firmware over UART
  • Restart in normal mode

I already created a zip package using nrfutil : nrfutil pkg generate --hw-version 52 --application-version-string 1.0.0 --application XYZ_Project.hex --external-app --key-file private.key XYZ_Project.zip

where XYZ_Project.hex is a STM32 hex file.

I succeed in downloading the zip file in the NRF52 and I check the internal memory of the MCU. Everythong looks good in Bank 1 ;)

Now, I want to push the Bank 1 data to the other MCU. Searhing the code, I saw I have to implement this method :

nrf_dfu_result_t nrf_dfu_validation_post_external_app_execute(dfu_init_command_t const * p_init, bool is_trusted)

However, it's never called; I ran the code in debbuger mode and saw this code section in postvalidate function nrf_dfu_validation.c but don't really understand how it works :

#if NRF_DFU_SUPPORTS_EXTERNAL_APP
        else if (p_init->type == DFU_FW_TYPE_EXTERNAL_APPLICATION)
        {
            if (!is_trusted)
            {
                // This function must be implemented externally
                ret_val = nrf_dfu_validation_post_external_app_execute(p_init, is_trusted);
            }
            else
            {
                s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_EXT_APP;
            }
        }
#endif // NRF_DFU_SUPPORTS_EXTERNAL_APP

The method nrf_dfu_validation_post_external_app_execute is never executed (in debugger mode, I put a breakpoint on the function).

Help is welcome Smiley

Parents
  • Hi,

    The nrf_dfu_validation_post_external_app_execute() that you implement is called if the update is for an external app, and that is enabled in the bootloader and the whole firmware is received and the command is NRF_DFU_OP_OBJECT_EXECUTE. Generally, what the external app feature gives you is a way to transfer the image to the nRF, and then call your nrf_dfu_validation_post_external_app_execute(). From then you are responsible for all the rest.

    Regarding the code snippet you refer to, NRF_DFU_SUPPORTS_EXTERNAL_APP is an sdk_config.h macro that must be enabled. The is_trusted parameter is used to signal if the function can make permanent changes on the nRF state (has been validated etc.). You can see how it is used in the various post_validate functions etc.

    I think to understand the issue here it would be good if you enable debug logging so that we can see what happens in the bootloader, and compare that with what you would expected to happen. 

  • Hi,

    Sorry for the delay, I had some diffculties to compile with the debug logging options.

    For the next one, if the following error occurs :

    1> Linking diego_isp4520_bl.elf
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: error: .rodata is too large to fit in FLASH memory segment
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: error: .data is too large to fit in FLASH memory segment
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: error: section .tdata overlaps absolute placed section .mbr_params_page
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: Output/Release/Obj/diego_isp4520_bl/main.o: in function `main':
    1> C:\TRO\DevE\DIEGO\diego_isp4520_bl/main.c:154: undefined reference to `nrf_log_default_backends_init'
    Build failed

    It's necessary to modify the Section Placement Maccro to enlarge Flash Size

    I went from :

    FLASH_START=0x78000
    FLASH_SIZE=0x6000

    To :

    FLASH_START=0x72000
    FLASH_SIZE=0x12000

    This the log when I upload the external app (no application in Bank 0 so I think data goes to this bank) :

    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00025D58, src=0x20006620, len=244 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00025D58, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 244 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00025E4C, src=0x20006620, len=244 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00025E4C, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 192 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00025F40, src=0x20006620, len=192 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00025F40, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
    <debug> nrf_dfu_req_handler: Offset:53248, CRC:0x672E882D
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> app: timer_stop (0x20005984)
    <debug> app: timer_activate (0x20005984)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00026000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_req_handler: Creating object with size: 424. Offset: 0x0000D000, CRC: 0x672E882D
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x00026000, pending 1
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 244 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00026000, src=0x20006620, len=244 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00026000, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 180 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000260F4, src=0x20006620, len=180 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000260F4, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
    <debug> nrf_dfu_req_handler: Offset:53672, CRC:0x37073ED7
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
    <debug> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
    <debug> nrf_dfu_validation: Hash verification. start address: 0x19000, size: 0xD1A8
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0E000.
    0x1
    <debug> app: timer_stop (0x20005984)
    <debug> app: timer_activate (0x20005984)
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 4
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 3
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 2
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 1
    <debug> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
    <debug> app: Shutting down transports (found: 1)
    <debug> nrf_dfu_ble: Shutting down BLE transport.
    <debug> nrf<info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_settings: Using settings page.
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    <debug> nrf_dfu_settings: Destination settings are identical to <info> app: Entering DFU mode.

    It seems that some messages are fragmented. I try to produce a better log in the afternoon.

    Thanks again.

    Thib

Reply
  • Hi,

    Sorry for the delay, I had some diffculties to compile with the debug logging options.

    For the next one, if the following error occurs :

    1> Linking diego_isp4520_bl.elf
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: error: .rodata is too large to fit in FLASH memory segment
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: error: .data is too large to fit in FLASH memory segment
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: error: section .tdata overlaps absolute placed section .mbr_params_page
    1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.10/gcc/arm-none-eabi/bin/ld: Output/Release/Obj/diego_isp4520_bl/main.o: in function `main':
    1> C:\TRO\DevE\DIEGO\diego_isp4520_bl/main.c:154: undefined reference to `nrf_log_default_backends_init'
    Build failed

    It's necessary to modify the Section Placement Maccro to enlarge Flash Size

    I went from :

    FLASH_START=0x78000
    FLASH_SIZE=0x6000

    To :

    FLASH_START=0x72000
    FLASH_SIZE=0x12000

    This the log when I upload the external app (no application in Bank 0 so I think data goes to this bank) :

    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00025D58, src=0x20006620, len=244 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00025D58, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 244 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00025E4C, src=0x20006620, len=244 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00025E4C, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 192 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00025F40, src=0x20006620, len=192 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00025F40, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
    <debug> nrf_dfu_req_handler: Offset:53248, CRC:0x672E882D
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> app: timer_stop (0x20005984)
    <debug> app: timer_activate (0x20005984)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00026000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_req_handler: Creating object with size: 424. Offset: 0x0000D000, CRC: 0x672E882D
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x00026000, pending 1
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 244 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00026000, src=0x20006620, len=244 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x00026000, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_ble: Buffer 0x20006620 acquired, len 180 (244)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000260F4, src=0x20006620, len=180 bytes), queue usage: 1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000260F4, pending 1
    <debug> nrf_dfu_ble: Freeing buffer 0x20006620
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
    <debug> nrf_dfu_req_handler: Offset:53672, CRC:0x37073ED7
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
    <debug> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
    <debug> nrf_dfu_validation: Hash verification. start address: 0x19000, size: 0xD1A8
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0E000.
    0x1
    <debug> app: timer_stop (0x20005984)
    <debug> app: timer_activate (0x20005984)
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 4
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 3
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 2
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 1
    <debug> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
    <debug> app: Shutting down transports (found: 1)
    <debug> nrf_dfu_ble: Shutting down BLE transport.
    <debug> nrf<info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_settings: Using settings page.
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    <debug> nrf_dfu_settings: Destination settings are identical to <info> app: Entering DFU mode.

    It seems that some messages are fragmented. I try to produce a better log in the afternoon.

    Thanks again.

    Thib

Children
No Data
Related