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
    after further investigation I think the missing piece in my picture is MBR. Its source code is not available so I have to guess.
    The RESET vector points to the code in MBR. If the MBR code detects a bootloader it passes control to this bootloader. Otherwise it calls an application at 0x1000 (aka softdevice).

    Helpful: the blinky example comes in 2 flavours - blank and MBR. The difference between the linker files is

    $ diff blank/armgcc/blinky_gcc_nrf52.ld mbr/armgcc/blinky_gcc_nrf52.ld
    <   FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x100000
    <   RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x40000
    ---
    >   FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xff000
    >   RAM (rwx) :  ORIGIN = 0x20000008, LENGTH = 0x3fff8
    

    The MBR version puts blinky in the position of the softdevice (interesting and not yet understood: 8 bytes of RAM are skipped - why?)

    Now I guess my path to succes should be:
    a) move my application code to 0x1000 (reserving 8 bytes of RAM) to put it in place of the softdevice
    b) add MBR

    best regards, Peter

Reply
  • Hi
    after further investigation I think the missing piece in my picture is MBR. Its source code is not available so I have to guess.
    The RESET vector points to the code in MBR. If the MBR code detects a bootloader it passes control to this bootloader. Otherwise it calls an application at 0x1000 (aka softdevice).

    Helpful: the blinky example comes in 2 flavours - blank and MBR. The difference between the linker files is

    $ diff blank/armgcc/blinky_gcc_nrf52.ld mbr/armgcc/blinky_gcc_nrf52.ld
    <   FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x100000
    <   RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x40000
    ---
    >   FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xff000
    >   RAM (rwx) :  ORIGIN = 0x20000008, LENGTH = 0x3fff8
    

    The MBR version puts blinky in the position of the softdevice (interesting and not yet understood: 8 bytes of RAM are skipped - why?)

    Now I guess my path to succes should be:
    a) move my application code to 0x1000 (reserving 8 bytes of RAM) to put it in place of the softdevice
    b) add MBR

    best regards, Peter

Children
Related