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 Jørgen

    yes, my image is just a proof of concept and small enough to fit (<100k)
    the 'fake bootloader settings' are calculated to eat up the first half of the available flash and to place bank 1 in the second half. Then I calculate CRC of whatever is currently in the first half (bank0).
    I'm aware of the 52820 having just a quarter of the flash and I want to make it work with the DevKit before I move to my own hardware.

    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.

    I do not have a "first DFU" and integrating MTP as transport into the bootloader would a nightmare and a waste of flash. Generating settings with nrfutil is both uncomfortable while developing and an (unwanted) additional step for production. IMHO it's quite simple to create these initial settings for the very first DFU on the fly.

    I like to separate my settings in app_config.h and for the bootloader it contains the following:

    #define NRF_BL_DFU_ALLOW_UPDATE_FROM_APP 1
    #define NRF_DFU_REQUIRE_SIGNED_APP_UPDATE 1
    #define NRF_DFU_APP_DOWNGRADE_PREVENTION 0
    #define NRF_DFU_EXTERNAL_APP_VERSIONING 0
    #define NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES 1
    #define NRF_DFU_SINGLE_BANK_APP_UPDATES 0
    
    #define NRF_BL_DFU_ENTER_METHOD_BUTTON 0
    #define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 0
    
    #define NRF_DFU_HW_VERSION 52
    
    
    // <i> Enable this to disable writing to areas of the settings that are protected
    // <i> by the bootlader. If this is not enabled in the app, certain settings write
    // <i> operations will cause HardFaults or will be ignored. Enabling this option
    // <i> also causes postvalidation to be disabled since this is meant to be done
    // <i> in the bootloader. NRF_BL_DFU_ALLOW_UPDATE_FROM_APP must be enabled in the bootloader.
    #define NRF_DFU_IN_APP 1
    
    
    // NRF_DFU_APP_DATA_AREA_SIZE - The size (in bytes) of the flash area reserved for application data. 
    // This area is found at the end of the application area, next to the start of
    // the bootloader. This area will not be erased by the bootloader during a
    // firmware upgrade. The size must be a multiple of the flash page size.
    #define NRF_DFU_APP_DATA_AREA_SIZE 12288
    
    
    // <i> External apps are apps that will not be activated. They can 
    // <i> e.g. be apps to be sent to a third party. External app updates 
    // <i> are verified upon reception, but will remain in bank 1, and 
    // <i> will never be booted. An external app will be overwritten if 
    // <i> a new DFU procedure is performed. Note: This functionality is 
    // <i> experimental and not yet used in any examples.
    #define NRF_DFU_SUPPORTS_EXTERNAL_APP 0
    
    
    
    #define NRF_LOG_ENABLED 0
    #define NRF_LOG_BACKEND_RTT 0
    #define NRF_LOG_DEFERRED 0
    #define NRF_LOG_DEFAULT_LEVEL 4
    
    #define NRF_LOG_BACKEND_RTT_ENABLED 1
    #define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64
    #define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4096
    #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
    #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
    #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
    #define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
    

    thank you very much for your support :-))

    Peter

Reply
  • Hi Jørgen

    yes, my image is just a proof of concept and small enough to fit (<100k)
    the 'fake bootloader settings' are calculated to eat up the first half of the available flash and to place bank 1 in the second half. Then I calculate CRC of whatever is currently in the first half (bank0).
    I'm aware of the 52820 having just a quarter of the flash and I want to make it work with the DevKit before I move to my own hardware.

    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.

    I do not have a "first DFU" and integrating MTP as transport into the bootloader would a nightmare and a waste of flash. Generating settings with nrfutil is both uncomfortable while developing and an (unwanted) additional step for production. IMHO it's quite simple to create these initial settings for the very first DFU on the fly.

    I like to separate my settings in app_config.h and for the bootloader it contains the following:

    #define NRF_BL_DFU_ALLOW_UPDATE_FROM_APP 1
    #define NRF_DFU_REQUIRE_SIGNED_APP_UPDATE 1
    #define NRF_DFU_APP_DOWNGRADE_PREVENTION 0
    #define NRF_DFU_EXTERNAL_APP_VERSIONING 0
    #define NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES 1
    #define NRF_DFU_SINGLE_BANK_APP_UPDATES 0
    
    #define NRF_BL_DFU_ENTER_METHOD_BUTTON 0
    #define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 0
    
    #define NRF_DFU_HW_VERSION 52
    
    
    // <i> Enable this to disable writing to areas of the settings that are protected
    // <i> by the bootlader. If this is not enabled in the app, certain settings write
    // <i> operations will cause HardFaults or will be ignored. Enabling this option
    // <i> also causes postvalidation to be disabled since this is meant to be done
    // <i> in the bootloader. NRF_BL_DFU_ALLOW_UPDATE_FROM_APP must be enabled in the bootloader.
    #define NRF_DFU_IN_APP 1
    
    
    // NRF_DFU_APP_DATA_AREA_SIZE - The size (in bytes) of the flash area reserved for application data. 
    // This area is found at the end of the application area, next to the start of
    // the bootloader. This area will not be erased by the bootloader during a
    // firmware upgrade. The size must be a multiple of the flash page size.
    #define NRF_DFU_APP_DATA_AREA_SIZE 12288
    
    
    // <i> External apps are apps that will not be activated. They can 
    // <i> e.g. be apps to be sent to a third party. External app updates 
    // <i> are verified upon reception, but will remain in bank 1, and 
    // <i> will never be booted. An external app will be overwritten if 
    // <i> a new DFU procedure is performed. Note: This functionality is 
    // <i> experimental and not yet used in any examples.
    #define NRF_DFU_SUPPORTS_EXTERNAL_APP 0
    
    
    
    #define NRF_LOG_ENABLED 0
    #define NRF_LOG_BACKEND_RTT 0
    #define NRF_LOG_DEFERRED 0
    #define NRF_LOG_DEFAULT_LEVEL 4
    
    #define NRF_LOG_BACKEND_RTT_ENABLED 1
    #define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64
    #define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4096
    #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
    #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
    #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
    #define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
    

    thank you very much for your support :-))

    Peter

Children
No Data
Related