OTA DFU Softdevice 3.1.0 -> 7.0.1 is feasible?

Hi!

We have some legacy IoT devices currently running with s132 3.1.0 softdevice (yes... very old). We would like to push a major update of the fleet, with our latest firmware running on s132 7.0.1 

The DFU OTA is partially working: the first step is going well (SD + BL update) but then the procedure timeouts! The app update part is never reached. The device is then bricked.

I'm using the following command to generate the zip package:

nrfutil pkg generate --application "APP.hex" --application-version {app_ver} --softdevice "s132_nrf52_7.0.1_softdevice.hex" --bootloader "DFU.hex" --bootloader-version {bootloader_ver} --hw-version {hw_ver} --sd-req 0x91,0xCB --sd-id 0xCB --key-file "dfu_private_key.pem" DFU.zip'

This package is fully working on a 7.0.1 device, but it is unable to update a legacy 3.1.0 device.

I've also realized that the flash requirements are changing between the 2 soft devices... there is something that I'm missing?

Any help would be really appreciated! Thank you!

Parents
  • Hi,

    It should be possible to update the Softdevice from this version. The bootloader will change the flash layout dynamically to accomodate for the larger softdevice size.

    After the connection times out, can you try to start a scan and see if the device is advertising in DFU mode (as "DFUTarg" or similiar)? Alternatively, connect a debugger to your device and run "nrfjprog --readregs". This will read out the CPU registers from the chip, which may help us determine what state it is in.

    Best regards,

    Vidar

  • Hi Vidar,

    Nothing is advertising.

    $ nrfjprog.exe -f NRF52 --readregs
    R0: 0x00000004
    R1: 0xFFFFFFF9
    R2: 0x20000004
    R3: 0x000251CB
    R4: 0x00001000
    R5: 0x0007E080
    R6: 0x0007E000
    R7: 0x00000000
    R8: 0x00000000
    R9: 0x00000000
    R10: 0x00000000
    R11: 0x00000000
    R12: 0x0007E37F
    SP: 0x2F00E830
    LR: 0xFFFFFFF9
    PC: 0x000251D8
    xPSR: 0x61000003
    MSP: 0x2F00E830
    PSP: 0x00000000

    I've also dumped the memory with nrfjprog.exe -f NRF52 --readcode --readuicr DUMP_AFTER_DFU.hex and I see big chuncks of memory that match what we should expect, in particular after 0x1000 (SD) and 0x78000 (BL), so I might assume that the SD+BL transfer went well.

  • Sorry, I was not clear. The UICR will not be updated during a DFU. What I am wondering is if the bootloader start address stored at 0x10001014 is identical to the start address you built your new bootloader with. As you may know, it is not possible to relocate the bootloader through DFU.

    Bank code 0xAC corresponds to NRF_DFU_BANK_VALID_SD_BL, which is to be expected if the bootloader crashed after the SD+BL transfer was completed.

  • Hi Vidar,

    Dumping the UICR from the legacy HW I read this:

    :020000041000EA
    :10100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
    :10101000FFFFFFFF0080070000E00700FFFFFFFF6A

    As far I can tell this mean a bootloader address at 0x78000. Which matches the linker address FLASH_START=0x78000 in the DFU project (and output hex) of the newer FW.

    Is this answering your question or am I missing something?

    The only difference that I see is the .init section that happens to be in 0x78400 in the legacy FW, and 0x78200 in the new one (.vectors, on the other side, are well aligned on both at 0x78000).

  • Yes, this answers my question. Thanks. The key thing here is that the .vectors section is linked to the same start address in both builds. 

    After the failed DFU, can you please run 'nrfjprog --memrd 0x0 --n 0x80000 > flash.txt and upload the output here? Or the data between 0x78000 - 0x78400 if you are not able to share everything here in a public ticket.

  • Hello,

    I do not see anything that is obviously wrong in your memory dump. But the value @ 0x26000 is suspiciously close to the corrupt stack pointer value shown in your register readout earlier. Maybe the bootloader is trying to boot the application before it has been uploaded.

    I tried to perform a complete DFU from nRF5 SDK 12.3.0/s132 v3.0.0 to nRF5 16.0.0/s132 v.7.0.1 with the original bootloader projects here to see if I could reproduce, but I could not.

    Could you also do a 'memrd' after having programmed the new FW with the programmer, and then compare that to post-DFU-full.txt

    7282.dfu_sdk_12.3.0_SDK_16.0.0.zip

Reply
  • Hello,

    I do not see anything that is obviously wrong in your memory dump. But the value @ 0x26000 is suspiciously close to the corrupt stack pointer value shown in your register readout earlier. Maybe the bootloader is trying to boot the application before it has been uploaded.

    I tried to perform a complete DFU from nRF5 SDK 12.3.0/s132 v3.0.0 to nRF5 16.0.0/s132 v.7.0.1 with the original bootloader projects here to see if I could reproduce, but I could not.

    Could you also do a 'memrd' after having programmed the new FW with the programmer, and then compare that to post-DFU-full.txt

    7282.dfu_sdk_12.3.0_SDK_16.0.0.zip

Children
  • Here the dump from the same device updated with the programmer.

    SD and BL looks identical. MBR and Application are different. Also some minor differences in the MBR param area and BL param area (0x7E000/0x7F000).

    Also the memory just before the application (0x258C0 - 0x25FFF) is not 0xFF in the post-DFU one, which seems a little bit weird to me (I don't know what this data is...)

    What do you think? Thank you!

  • Could you try to start a debug session with the new bootloader project after the failed DFU attempt to see if you can figure out when hardfault is raised or why it does not enter DFU mode? I did go through the post-DFU-full.txt file again and compared it against REFLASHED.txt but nothing appears to be out of the ordinary. 

    Daino said:
    Also the memory just before the application (0x258C0 - 0x25FFF) is not 0xFF in the post-DFU one, which seems a little bit weird to me (I don't know what this data is...)

    I understand this looks suspicious, but it is just a padding area reserved by the Softdevice which has not been cleaned up by the bootloader. 

    The padding ensures the application starts on page aligned address (0x1000) and that we can make minor bug fix releases without changing the image size. 

  • Hi Vidar,

    running the code step-by-step it looks like the DFU executes successfully.

    From my limited understanding it seems like the DFU finds a valid application and tries to run it. Then probably the application fails because it does not find the good SD.

    EDIT:

    Deep diving why the app was executed, we found out that the line

    if (!app_is_valid(crc_on_valid_app_required())) inside dfu_enter_check()

    was commented out, to speed up the startup and save energy (our application runs with a very low duty cycle and every millisecond counts to reach year-long battery life)... So basically the app CRC is never verified by the DFU. This allows the unexpected execution of the old app just after the DFU/SD update.

    The good news: bringing back the CRC control, the OTA update is now successfully completed Slight smileThank you for your support all along the way!

    Just as a closing note: do you see any viable alternative to bringing back the full CRC calculation in the DFU? We would really like to keep the boot-up as fast as possible.

  • Hi,

    I am glad to hear that you found the issue Slight smile The problem with commenting out the line you mentioned is that you not only skip the CRC checksum validation, but also the .bank_code check here:

    This explains why the bootloader attempted to boot the application before it had been uploaded.

    To correctly disable CRC validation, you can use the '--app-boot-validation NO_VALIDATION' option when you generate your Bootloader settings page and DFU package with nrfutil. 

    From the nrfutil help menus:

    $ nrfutil pkg generate --help
    
    Usage: nrfutil pkg generate [OPTIONS] ZIPFILE
    
      Generate a zip package for distribution to apps that support Nordic DFU OTA.
      The application, bootloader, and SoftDevice files are converted to .bin if
      supplied as .hex files. For more information on the generated package, see:
      http://developer.nordicsemi.com/nRF5_SDK/doc/
    ...
    
      --app-boot-validation [NO_VALIDATION|VALIDATE_GENERATED_CRC|VALIDATE_GENERATED_SHA256|VALIDATE_ECDSA_P256_SHA256]
                                      The method of boot validation for
                                      application.
                                      
    $ nrfutil settings generate --help
    Usage: nrfutil settings generate [OPTIONS] HEX_FILE
    
    ...
    
      --app-boot-validation [NO_VALIDATION|VALIDATE_GENERATED_CRC|VALIDATE_GENERATED_SHA256|VALIDATE_ECDSA_P256_SHA256]
                                      The method of boot validation for
                                      application.
    

Related