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

nRF52840 BLE Buttonless DFU SDK 15.3.0 example memory issue

Hello



File: secure_bootloader_ble_s140_pca10056.emProject

File: ble_app_buttonless_dfu_pca10056_s140.emProject

Board: nRF52840-DK

SDK Version: 15.3.0

Soft Device: s140_nrf52_6.1.1

OS: Ubuntu 18.04.3

Intent: Add buttonless dfu feature to our existing ble project.

Issue 1: Buttonless example is successful when uploading the package.zip using the DFU. When uploading Buttonless example with J-Link through SES, we get an err_code = 4, resulting in NRF_BREAKPOINT_COND.

When uploading with SES/J-Link the 0x1000 (4096) page is being written to and this is causing the uicr_bootloader_start_address @ 0xff8 location to be erased, and is reading 0xffff-ffff. We are expecting the uicr_bootloader_start_address @ 0xff8 to be 0xF8000.

I believe the reason the DFU transfer of the buttonless example works, is because the bootloader is protecting the flash from being overwritten (Line 32 of secure bootloader main.c). While the SES upload is not protecting that space.

Question 1: Can this issue be recreated with the BLE Buttonless DFU example?

Question 2: Why is the project writing to 0x0 – 0xfff?


Modifications made to our application: We have an existing BLE application we are developing, and are adding the buttonless dfu feature to our application. I will list the settings I have modified in my attempt to get the buttonless dfu feature working on our application.

After making these changes our application does not work with both upload methods, SES/J-Link or, DFU. The 0xff8 memory issue described above is also seen with our application.

    Modified main.c to include buttonless features
    Include several SDK files into the project
        nRF_DFU folder
            ble_dfu_bonded
            ble_dfu
            ble_dfu_unbonded
        nRF_SVC folder
            nrf_dfu_svci
        Add user include directories
            ../nRF5-SDK/components/libraries/bootloader/ble_dfu
            ../nRF5-SDK/components/libraries/bootloader/dfu
            ../nRF5-SDK/components/libraries/bootloader
            ../nRF5-SDK/components/libraries/svc
        Add Preprocessor Defines Code>>Preprocessor>>Preprocessor Definitions (Common)
            BL_SETTINGS_ACCESS_ONLY
            NRF_DFU_SVCI_ENABLED
            NRF_DFU_TRANSPORT_BLE=1
        Modified sdk_config.h
            Note: These were the only defines different in our app vs the buttonless example. These are the values I kept in our app.
            BLE_DFU_ENABLED 1
            NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 1
            NRF_LOG_BACKEND_RTT_ENABLED 1
        flash_placement xml
            added "uicr_bootloader_start_address" section
        Added bootloader address to Build>>Memory Segments (Common) "uicr_bootloader_start_address RX 0x00000FF8 0x4"

Question 3: Have I left out settings or properties from this list for the BLE Buttonless DFU to work?

(EDIT) Additionally I have discovered the SoftDevice.hex included in the Project Options>>Loader>> Additional Load File[0]

../nRF5-SDK/components/softdevice/s140/hex/s140_nrf52_6.1.1_softdevice.hex

Was programming the softdevice before the application, this was writing to the MBR Page

MyApplication with s140, MRB page is written to

Preparing target for download
Executing Reset script TargetInterface.resetAndStop()
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading 's140_nrf52_6.1.1_softdevice.hex' to J-Link
Programming 2.7 KB of addresses 00000000 -- 00000aff
Programming 147.4 KB of addresses 00001000 -- 00025de7
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (4096 bytes)
J-Link: Flash download: Total time needed: 0.619s (Prepare: 0.165s, Compare: 0.159s, Erase: 0.088s, Program: 0.098s, Verify: 0.003s, Restore: 0.104s)
Download successful
Downloading 'myApplication.elf' to J-Link
Programming 78.8 KB of addresses 00026200 -- 00039d3b
Programming 0.0 KB of addresses 00039d3c -- 00039d4f
Programming 14.8 KB of .rodata addresses 00039d50 -- 0003d8b3
Programming 0.1 KB of addresses 0003d8b4 -- 0003d97b
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (98304 bytes)
J-Link: Flash download: Total time needed: 2.615s (Prepare: 0.160s, Compare: 0.022s, Erase: 0.000s, Program: 2.315s, Verify: 0.004s, Restore: 0.113s)
Download successful

MyApplication without s140 Included MRB page is not written to

Preparing target for download
Executing Reset script TargetInterface.resetAndStop()
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading 'myApplication.elf' to J-Link
Programming 79.3 KB of addresses 00026000 -- 00039d3b
Programming 0.0 KB of addresses 00039d3c -- 00039d4f
Programming 14.8 KB of .rodata addresses 00039d50 -- 0003d8b3
Programming 0.1 KB of addresses 0003d8b4 -- 0003d97b
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (4096 bytes)
J-Link: Flash download: Total time needed: 0.391s (Prepare: 0.083s, Compare: 0.090s, Erase: 0.088s, Program: 0.104s, Verify: 0.002s, Restore: 0.020s)
Download successful

I have been following the documentation and the process of uploading Softdevice, then Bootloader, the Application. I have noticed the Bootloader and Application examples include the s140 softdevice within the project.

Question 4: Why is the recommended order to programming softDevice>>BootLoader>>Application, if the bootloader includes the softDevice, and the application includes the softDevice?

Source: https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.3.0/ble_sdk_app_buttonless_dfu.html

I should be able to upload softdevice >> bootloader (without softdevice) >> application (without softdevice) and this should work?

Alternatively I should be able to load bootloader (with softdevice) and application (without softdevice)

To be clear our application is a ble application.

Thank you,

  • Hi,

    1. Yes, that could be. If you program the MBR/SoftDevice after programming the bootloader, this would include a sector erase of the MBR page, which would then erase the bootloader start address at the end of the MBR page. Note that this is only a problem with SDK 15.3, since that is the only SDK where the bootloader start address is only placed in the MBR page.

    2. Erase happens on a page basis (0x1000 bytes), and before writing to a page it is normally erased. It is possible to program without an initial erase, though, but that only works if the region you write to is already erased since programming can only flip 1's to 0's (the physical property of flash memory).

    3. In what way does it not work? Please elaborate.

    4. The order does not matter much, except for what I described in 1, since you risk erasing the bootloader start address if you program the SoftDevice (including the MBR) after the bootloader.

  • I was able to fix the 0x1000 page being erased by removing the the softdevice from the additional load files in project settings.

    3. To elaborate, our BLE application initially was able to advertise, as a benchmark. The current state is the BLE application does not advertise after modifying the application to include the BLE Buttonless DFU template properties, but instead of the application advertising, the  DFUTarg is advertising. This leads me to believe that the bootloader is being run instead of the application.

    It is not clear to me what in the process of including the buttonless DFU feature in our application that could have prevented the application from booting?

    My guess is the application start address did not get loaded, or the flag that says an application is loaded, boot application was not set. I am not aware of any other potential causes.

    Thank you,

  • Hi,

    Including buttonless DFU in the application should not prevent the bootloader from starting the application. However, a typical mistake is forgetting to update the bootloader settings page if you update the application via a debugger instead of via DFU. In that case, you must also update the bootloader settings page, which you generate with nrfutil. If not, the bootloader will see the application as corrupted, and enter DFU mode instead of starting the application.

  • What would the workflow look like if we are updating the application via debugger and DFU interchangeably?

    am I correct to assume when generating the software_package.zip (nrfutil pkg generate) for the DFU transfer that the bootloader settings page is generated within that command?

    When uploading with a debugger, once I generate a bootloader_settings.hex, how do I include that in the SES project for upload? is that the Project Options>>Loader>>Additional Load File? I think the workflow for debugger upload looks like this: Build project, nrfutil settings generate with app.hex from project, include settings.hex output in Additional Load Files in SES, Upload the project. For future uploads the settings file will already be included in the Additional Load Files, therefore generating the process would be build, generate settings.hex, build again? That seems odd to be honest, What are the settings.hex upload options?

    Is there a way to combine the bootloader, softdevice, application, and bootloader settings page all into the SES project/ toolchain so these operations are handled in the background?

    Ultimately I would like to add the DFU feature, but also allow further debug of other features being added in the future, and have a stable process to handle the two methods.

    Additionally what is not clear to me is where to confirm/set the version numbers? are the commands/settings below comparing to something in the bootloader.hex, or application.hex that I have to match, or am I setting the version values here, and the bootloader settings values only have to match the package settings?

    nrfutil settings generate:

    --application-version

    --bootloader-version

    nrfutil pkg generate:

    --application-version

    --bootloader-version

  • Hi,

    The DFU package you generate with nrfutil does not include a bootloader settings page (though it includes a hash of the image), but the bootloader settings page is updated by the bootloader when you perform a DFU upgrade. So you only need to update it manually if you program the application by another means than DFU.

    You could add the bootloader settings as an additional load file, but you also need a script to generate it every time, based on the updated application .hex. It may be possible to do that in SES, but I don't know how (if possible). Alternatively, you could make a separate script that you run on the side which does this for you.  The typical way to handle this in a develop-test-develop cycle is to test your application without a bootloader during development, or modify the bootloader to not check the application before booting, for instance by making crc_on_valid_app_required() always return false.

    I am not aware of any way to combine everything in a single SES project.

    The version numbers are used to prevent downgrades. The exact number does not matter, just make sure that the number is always increasing.

Related