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

custom DFU in App

Hello,

I am developing DFU over a custom IEEE802.15.4 Protocol in our own embedded OS. I managed to write the new Firmware starting at bank1_start address. Now I need to tell the Bootloader (the BTL from SDK16) to do its magic (verifying and copying the Firmware to bank0). For now I fill the init_command in the nrf_dfu_settings_t at BOOTLOADER_SETTINGS_ADDRESS with the values I get from nrfutil and write it back to flash, but that doesn't impress the bootloader. What else do I need to do so the bootloader knows that there is a new Firmware it should take care of?

This is what I am doing right now:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> nrfutil settings generate --application ./Firmware.hex --application-version 0x0100 --family NRF52840 --bootloader-version 1 --bl-settings-version 2 Firmware_btl_settings.hex
Note: Generating a DFU settings page with backup page included.
This is only required for bootloaders from nRF5 SDK 15.1 and newer.
If you want to skip backup page generation, use --no-backup option.
Generated Bootloader DFU settings .hex file and stored it in: Firmware_btl_settings.hex
Bootloader DFU Settings:
* File: MPS_Master_btl_settings.hex
* Family: NRF52840
* Start Address: 0x000FF000
* CRC: 0x8800843F
* Settings Version: 0x00000002 (2)
* App Version: 0x00000100 (256)
* Bootloader Version: 0x00000001 (1)
* Bank Layout: 0x00000000
* Current Bank: 0x00000000
* Application Size: 0x00024C3C (150588 bytes)
* Application CRC: 0xF899D96C
* Bank0 Bank Code: 0x00000001
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hello,

    So you have basically already transferred the new image, and you need the bootloader to move it into the correct location and verify the signature, right?

    I suggest you look into how the bootloader does this when it receive the "object execute" command. I am using SDK17.0.2 and the serial(uart) bootloader as reference, as you may not be using the softdevice.

    nrf_dfu_req_handler.c -> nrf_dfu_command_req() -> case NRF_DFU_OP_OBJECT_EXECUTE -> on_cmd_obj_execute_request() -> 

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void on_cmd_obj_execute_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
    {
    ASSERT(p_req);
    ASSERT(p_res);
    NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (command)");
    nrf_dfu_result_t ret_val;
    ret_val = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
    p_res->result = ext_err_code_handle(ret_val);
    if (p_res->result == NRF_DFU_RES_CODE_SUCCESS)
    {
    if (nrf_dfu_settings_write_and_backup(NULL) == NRF_SUCCESS)
    {
    /* Setting DFU to initialized */
    NRF_LOG_DEBUG("Writing valid init command to flash.");
    }
    else
    {
    p_res->result = NRF_DFU_RES_CODE_OPERATION_FAILED;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    particularly the line containing nrf_dfu_validation_init_cmd_execute().

    This will validate the firmware. If it is successful, it will continue to write new settings:

    nrf_dfu_settings_write_and_backup()

    I don't remember the complete application flow, but this should eventually reset the bootloader, and the next time it runs, it will run into main() -> nrf_bootloader_init() -> nrf_bootloader_fw_activate() case ACTIVATION_SUCCESS, which will reset it again, and then your application will start.

    Best regards,

    Edvin

  • Hello Edvin,

    I set up a DFU_IN_APP project with SDK17.0.2. The verification of the new Firmware fails with error 0x8512 (NRF_ERROR_CRYPTO_INPUT_LOCATION). I tracked it down to cc310_backend_hash_sha256_update(). There it verifies if p_data is in RAM

    Fullscreen
    1
    VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    But obviously the updated firmware is located in flash. What am I doing wrong here?

    dfu_in_app.zip

  • So that is the cc310_bl_backend_hash_sha256_update() (with "_bl_", right?)

    Remember that at this point, even if the DFU was performed from the bootloader (and not from the DFU_IN_APP), the new application would have been stored in the Flash of the nRF52840 as well.

    Line 168 and 172in cc310_bl_backend_hash.c in sdk17.0.2 says:

    168: // Copy a block from FLASH to RAM for use in CC310
    172: // Copy from FLASH to ram

    Is there a particular reason why you have set the define in sdk_config.h:

    NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED

    to 0? It is 1 by default. When this is set to 1, it will copy the data from flash to RAM, and in fact, the lines 164 -> 182 will be replacing line 183 -> 199 in cc310_bl_backend_hash.c.

    Try setting it (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED) back to 1. If that is not an option, I guess you need to manually pull each buffer with size "NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE" from flash before you run the VERIFY_TRUE() macro.

    Best regards,

    Edvin

  • as I said, it's cc310_backend_hash_sha256_update() without _bl_. Here is the call stack:

    NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED is set to 1 as you can see in the project files I attached to my earlier post, but that wasn't on purpose. If my NRF_CRYPTO_* setup is wrong, could you please help me setting it up right.

    The new application is stored in bank1, but fw_hash_ok() fails in postvalidate(), so s_dfu_settings.bank_current isn't set to NRF_DFU_CURRENT_BANK_1.

  • MeisterBob said:
    NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED is set to 1 as you can see in the project files I attached to my earlier post,

     I can't see that it is.

    Try starting with an unmodified version of the bootloader and go from there. Please try to keep NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED  set to 1.

    BR,

    Edvin

1 2