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

DFU by app using MTP

Hi
my application will be based on nRF52820 and has only USB connection (no BLE).
I'm developping with nRF5_SDK_17.0.2_d674dde and a nRF52840 devkit.

The end user should be able to update the firmware without any tools.
Thus I implemented Media Transfer Protocol to copy the new image to the device.

First I used
nrfutil pkg generate ...
to create and sign the new application and I wrote a script to unzip the result and combine bootloader data and firmware image to single file which can be copied to the device using MTP.
On the device I receive the combined file and I first check the bootloader data
After I've written the firmware to bank 1 the check with   nrf_dfu_validation_prevalidate() returns  NRF_DFU_RES_CODE_SUCCESS

The I took a copy from
nRF5_SDK_17.0.2_d674dde/examples/dfu/secure_bootloader/pca10056_uart/
and removed DFU completely (I just want the activation part, but no transport at all)

Now I think I have to write valid bootloader settings and reboot.
After many days of reading examples, bootloader code and trial/error I think I miserably fail because of some conceptual misunderstanding or wrong expectation.

I try to prepare bootloader settings following the procedures I find in the examples.

settings_forbidden_parts_copy_from_backup()
detects unacceptable changes compared to the backup settings in MBR parameter page

OK - I did not do any DFU before, the backup can not contain reasonable data yet - this makes sense.

Lets "invent" reasonable bootloader settings reflecting the current app (very nasty hack) at startup and write them to the backup too.

nrfutil says about my fake...
Bootloader DFU Settings:
* File:                 fakeBootloaderSettings.hex
* Family:               NRF52840
* CRC:                  0xF36F5B3B
* Settings Version:     0x00000001 (1)
* App Version:          0x00000001 (1)
* Bootloader Version:   0x00000002 (2)
* Bank Layout:          0x00000000
* Current Bank:         0x00000000
* Application Size:     0x0007AFFC (503804 bytes)
* Application CRC:      0xEC72A580
* Bank0 Bank Code:      0x00000001

Looking at the flash memory I see my dummy settings, but the newly created settings are never written to flash.

I tried
nrf_dfu_validation_activation_prepare()
nrf_dfu_validation_post_data_execute()
and other variants

when I follow the execution in Segger Studio and it comes to reboot I have the strong feeling to get started in the app again.
I think I never hit the bootloader. So I checked the UICR 0x10001014 and 0x10001018 and I think they point to the correct location
I use
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_RESET);

I have 3 problems:
a) how to correctly prepare bootloader settings in the app?
b) how to shutdown/reboot the system correctly?
c) how can I know if Segger reboots into the bootloader or the app?

I'd appreciate a comment how solve problem a) because here I'm definitely stuck

best regards
Peter

Parents
  • Hi,

    Are you using an image that will fit in the flash of the device?

    The "Fake Bootloader settings" you posted shows an application size of 0x0007AFFC (503804 bytes), while the nRF52820 only have 256 kB of flash available.

    The initial bootloader settings should either be generated by the bootloader when you perform the first DFU, or be generated by nrfutil and merged with the initial flashed application.

    It sounds like what you are trying to achieve is very similar to how the Background DFU solution in previous SDKs work. Have you configured the bootloader to allow updates from the application (NRF_BL_DFU_ALLOW_UPDATE_FROM_APP)? I assume this is where you try to write the bootloader settings from?

    Best regards,
    Jørgen

  • Hi,

    Is it correct that you have set "#define NRF_DFU_IN_APP 1" in the bootloader? This should normally be set in the "Background DFU application" to prevent it from writing the parts that bootloader will handle. If you set this in the bootloader, it may not work properly.

    Would you be able to provide minimal examples/instructions that can be used to reproduce/debug this issue?

    Can you enable and provide logs (preferably debug level) from the bootloader?

    Best regards,
    Jørgen

  • Hi

    > Is it correct that you have set "#define NRF_DFU_IN_APP 1" in the bootloader?
    no this was wrong - thanks for the hint!

    and also wrong in my fake bootloader settings for the very first DFU - I should have added:

        // copied from boot_validation_crc(nrf_dfu_settings_t const * p_settings) in nrf_dfu_settings.c
        dummySettings.boot_validation_crc = crc32_compute((const uint8_t *)&(dummySettings.boot_validation_softdevice),
                              (3 * sizeof(boot_validation_t)), NULL);
    

    Providing debug output from the bootloader requires adding a lot of library code which leads to much bigger bootloader - it won't fit anymore to 0xF8000 - 0xFDFFF
    It isn't working yet but I feel like making progress again - I'll provide feedback - hopefully I'll tell you that it works.

    thanks a lot
    Peter

  • Hi

    after checking my DFU for days I find that everything would work - except booting. The application prepares bank1, the bootloader settings and reboots. But the CPU does definitely NOT execute the bootloader but restarts the application instead.

    On the other hand: all is in place and I step through the bootloader in Segger Studio. It perfectly recognizes the new image, copies bank1 to bank0, updates bootloader settings and MBR (settings backup), restarts the bootloader, detects there^s nothing left to do...
            case ACTIVATION_NONE:
                nrf_bootloader_app_start();
                break;
    and nrf_bootloader_app_start() ends up somewhere in Nirwana but not in the app.

    Yes, UICR settings are correct and checked (snippet from bootloader hex):
    :02 0000 04 1000  EA
    :04 1014 00 00800F00  49
    :04 1018 00 00E00F00  E5

    I have the bootloader and a valid app in place and do a power up:
    the app starts - no trace from the bootloader.

    Now I compiled the blinky example to check what pointer is set at VTOR address 0x00000000
    The hex file says in the first line
    :10 0000 00 00000420 B5020000 DD020000 DF020000 55
    does this really mean VTOR Reset vector points to 0x20040000, the very first non-existing address in RAM? I do definitely not understand what's going on here :-(
    Does this address intentionally provoke a hard fault which is then handled?
    Or is VTOR not at address 0x00000000 as I expect? What vector is used at power up?

    I need some pat on the shoulder (a hint, a pointer to docs, whatever):
    how the heck does BOOT work???

    best regards, Peter

    PS -  EDIT:
    gcc_startup_nrf52840.S reveals
    0x00000000  __StackTop
    0x00000004  Reset_Handler
    (so I was wrong to expect the RESET vector at address 0x00000000)

Reply
  • Hi

    after checking my DFU for days I find that everything would work - except booting. The application prepares bank1, the bootloader settings and reboots. But the CPU does definitely NOT execute the bootloader but restarts the application instead.

    On the other hand: all is in place and I step through the bootloader in Segger Studio. It perfectly recognizes the new image, copies bank1 to bank0, updates bootloader settings and MBR (settings backup), restarts the bootloader, detects there^s nothing left to do...
            case ACTIVATION_NONE:
                nrf_bootloader_app_start();
                break;
    and nrf_bootloader_app_start() ends up somewhere in Nirwana but not in the app.

    Yes, UICR settings are correct and checked (snippet from bootloader hex):
    :02 0000 04 1000  EA
    :04 1014 00 00800F00  49
    :04 1018 00 00E00F00  E5

    I have the bootloader and a valid app in place and do a power up:
    the app starts - no trace from the bootloader.

    Now I compiled the blinky example to check what pointer is set at VTOR address 0x00000000
    The hex file says in the first line
    :10 0000 00 00000420 B5020000 DD020000 DF020000 55
    does this really mean VTOR Reset vector points to 0x20040000, the very first non-existing address in RAM? I do definitely not understand what's going on here :-(
    Does this address intentionally provoke a hard fault which is then handled?
    Or is VTOR not at address 0x00000000 as I expect? What vector is used at power up?

    I need some pat on the shoulder (a hint, a pointer to docs, whatever):
    how the heck does BOOT work???

    best regards, Peter

    PS -  EDIT:
    gcc_startup_nrf52840.S reveals
    0x00000000  __StackTop
    0x00000004  Reset_Handler
    (so I was wrong to expect the RESET vector at address 0x00000000)

Children
No Data
Related