This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF51822: secure DFU over BLE

Hello there!

We are using nRF51822_xxac SoC with nRF5 SDK v12.3.0 and S130 Softdevice. We are kind of obliged to stick with nRF51822 because nRF52840 SoCs were out of stock at the moment we wanted to place the order.

We are currently finalizing the application code but also want to have the ability to update our application with DFU over the BLE transport link. I was following this Nordic's step-by-step guide that explains how to implement secure DFU and here is what happens on my side:

  1. I was able to generate a public/private key pair with the nrfutil.exe tool.
    1. dfu_public_key.c file stored in the examples/dfu/bootloader_secure folder is replaced with the public key generated in step 1.
  2. micro-ecc external library is successfully compiled. As a consequence, micro_ecc_lib_nrf51.a static library file is generated in external/micro-ecc/nrf51_armgcc/armgcc folder.
  3. The bootloader is built by using the Makefile from examples/dfu/bootloader_secure/pca10028/armgcc. As a consequence, nrf51822_xxac_s130.hex file is generated.
  4. DFU .zip packet that contains only the application is successfully generated with the following script command:
    nrfutil pkg generate --hw-version 51 --application-version 1 --application <path_to_the_app.hex file> --sd-req 0x87 --key-file <path_to_the private.key file> app_dfu_package.zip
     
    --sd-req 0x87 is used to signalize that our application runs with s130 v2.0.1 Softdevice
  5. Now, when the time has come to actually do DFU, I flash
    1. Softdevice.
    2. Bootloader. As a consequence, my nRF51822 SoC starts advertising as DfuTarg
  6. Using the nRFConnect app and iPhone 11, OTA DFU is performed using the .zip file generated in step 4. The process finishes successfully but my nRF51822 SoC does not start advertising as Nordic_HRM (the Nordic HRM example is used for the application). It's kind of stuck because it neither advertises as DfuTarg.

I used the Programmer tool from nRF Connect for Desktop suite to verify the memory layout after each step and here is what I find:

  • Memory content after flashing Softdevice:

There is an MBR region of ~2KB + Softdevice region of about 106KB which is, to the best of my understanding, correct.

  • Memory content after flashing bootloader:

  • Memory content after performing DFU (sending .zip package over BLE):

As you can see, the Softdevice region increased from ~106KB to ~157KB (for about ~51KB which is the size of the application). It should not be like this, to the best of my understanding. We should have an application region on the top of the Softdevice region which is ~51KB in size.

As I said earlier, after OTA DFU update, nRF51822 SoC does not advertise at all. Once I press Reset button on Programmer window, device start advertising again as DfuTarg. Here is the memory content after the second DFU update with the same .zip package:

There is an application region of ~51KB on the top of increased Softdevice but, again, nRF51822 SoC does not advertise.

Do you have any idea about what I am missing here?

I feel the issue has something with how memory is partitioned but have no idea where exactly this should be fixed. I would really appreciate your help. Perhaps I should use mergehex tool to merge all .hex files (Softdevice + bootloader + application) into a single .hex file?

Thanks in advance for your time and efforts!

Sincerely,

Bojan.

Parents
  • Hi Bojan, 

    Could you check if you have any error log on the device when  you do DFU update ? 

    Which hardware did you test your bootloader on ? Please be note that by default the DFU bootloader is always entered if a button (BOOTLOADER_BUTTON = BSP_BUTTON_3 = Pin P0.20) is pressed (connect to ground). Check function nrf_dfu_enter_check(). I suspect that the button was not connected to VDD and causing the bootloader to enter DFU all the time. 

    For testing I would suggest to try doing DFU a very simple project, for example the \peripheral\blinky\pca10028\s130 

    I don't think merge the bootloader and application and softdevice would make any different here. 

    I would suggest to test using the debug version of the bootloader. With that you can step into the code and check why the bootloader doesn't want to jump to the application. Please focus on nrf_dfu_init() function in nrf_dfu.c , in that function you can find out why the bootloader stay in DFU mode instead of jumping application, focus on nrf_dfu_enter_check() and nrf_dfu_app_is_valid()

  • Hello, .

    Thanks for your feedback.

    We are using our custom-designed board with nRF51822 SoC on it. Pin P0.20 is physically connected to the interrupt output of the accelerometer. We don't have any external pull-up resistor that will tie the P0.20 to VDD.

    Is something like this necessary?

    Can we configure P0.20 GPIO as input with the internal pull-up resistor? We are interested in buttonless DFU in our use case.

    Sincerely,

    Bojan.

Reply
  • Hello, .

    Thanks for your feedback.

    We are using our custom-designed board with nRF51822 SoC on it. Pin P0.20 is physically connected to the interrupt output of the accelerometer. We don't have any external pull-up resistor that will tie the P0.20 to VDD.

    Is something like this necessary?

    Can we configure P0.20 GPIO as input with the internal pull-up resistor? We are interested in buttonless DFU in our use case.

    Sincerely,

    Bojan.

Children
  • Hi Bojan, 
    In that case you can just remove the check: 


    if (nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0)
    {
    return true;
    }

    in nrf_dfu_enter_check() function to not having the button involved.

    Or you can declare your own nrf_dfu_enter_check() to overwrite it, since the original nrf_dfu_enter_check() function in nrf_dfu.c is defined as WEAK.

  • Hello, .

    We disabled checking the state of P0.20 pin in nrf_dfu_enter_check() function. It seems that this had a positive impact and we were able to go one step further.

    What is happening now is that our custom board does not start with the new application code until we press the Reset button on Programmer window.

    On the other hand, when we use the nRF51DK instead of our custom board and apply the very same set of steps, the new application starts running properly after we transfer the DFU package over BLE.

    Do you have any idea about what might be the issue?

    Here is the part of our custom board schematic that contains nRF51 and program/debug interface:

    Sincerely,

    Bojan.

  • Hi Bojan, 

    Have you tried to test without the programmer/debugger connected ? 

    After the DFU process is finished the bootloader will reset the chip in this function: on_dfu_complete()

    The function is called in the flash call back after the bootloader setting write is finished. See this call
    // Store the settings to flash and reset after that
    if( nrf_dfu_settings_write(on_dfu_complete) != NRF_SUCCESS)

    In dfu_reg_handling.c file. 

    Please try to test using some logging to see why it hang and couldn't reset. 

Related