Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DFU secure bootloader fails on nRF52832-QFAB

Hello,

I am new to DFU OTA on Nordic's chips and I am currently trying to implement it on a custom board with an nRF52832-QFAB chip.

This will be a long issue since I have been trying a lot of different things, but as a summary: I have been able to compile and upload the secure DFU bootloader on the chip, and I am able to successfully upload a new application using nRF connect for desktop. The problem I have is that the application never starts and the chip is stuck on DFU Mode even though nRF connect tells me that the new app has been successfully downloaded. Everything seems to point out to the fact that the QFAB version of the chip has only 256kb of FLASH and 32kb of RAM causing a memory mapping problem since the DFU bootloader SES project is designed for the QFAA version with 512kb of FLASH and 64kb of RAM. I have been trying to modify the DFU bootloader SES project to work with the QFAB version of the chip without success.

Let's go with the detailed explanation:

SDK version: 17.1.0

Softdevice s132 and s140 versions: 7.2.0

1. What it works 

I have a PCA10056 dev board with the nRF52840 chip (at first the custom board was going to use the nRF52840 chip, but later we changed to the nRF52832 chip). So I successfully used this dev kit as a first approach to DFU OTA following this guide .

1. Generated private and public keys with 

nrfutil keys generate private.key
nrfutil keys display --key pk --format code private.key --out_file public_key.c

2. Opened <nRF5 SDK Folder>/examples/dfu/secure_bootloader/pca10056_s140_ble_debug/ses/secure_bootloader_ble_s140_pca10056_debug.emProject

3. Replaced the default public key with the new public key

4. Build the bootloader successfully

5. Flashed the bootloader (Connect to J-Link, Erase All, Download secure_bootlader_ble_s140_pca10056)

6. Devkit is now running on DFU Mode, showing LED1 & LED2 On, and advertising on nRF Connect Desktop as "DfuTarg".

7. Opened the BLE Blinky project in <nRF5 SDK Folder>/examples/ble_peripheral/ble_app_blinky/pca10056/s140/ses/ble_app_blinky_pca10056_s140.emProject

8. Build the project successfully

9. Copied the ble_app_blinky_pca10056_s140.hex to the private key folder and changed its name to ble_blinky.hex

10. Generated the .zip package with the ble blinky app by running: 

nrfutil pkg generate --hw-version 52 --application-version 1 --application ble_blinky.hex --sd-req 0x0100 --sd-id 0x0100 --key-file private.key ble_blinky_dfu_package.zip

(0x0100 corresponds to s140 v7.2)

11. Connect to "DfuTarg" on nRF Connect, and uploaded ble_blinky_dfu_package.zip.   nRF Connect logs "DFU completed successfully." message

12. Dev Kit now is visible on nRF Connect advertising as Nordic_Blinky. 

13. If Devkit resets while pressing button 4, devkit enters DFU mode and advertises as "DfuTarg".

So everything is working as is supposed to on the nRF52840 chip.

2. Replicating nRF52840 devkit success on nRF52832-QFAB custom board... (and failing).

I tried to replicate everything I did on the nRF52840 chip to the nRF52832-QFAB custom board and this is what happened.

1. Generated private and public keys with 

nrfutil keys generate private.key
nrfutil keys display --key pk --format code private.key --out_file public_key.c

2. Opened <nRF5 SDK Folder>/examples/dfu/secure_bootloader/pca10040_s132_ble_debug/ses/secure_bootloader_ble_s132_pca10040_debug.emProject

3. Replaced the default public key with the new public key

4. Build the bootloader successfully

5. Flashed the bootloader (Connect to J-Link, Erase All, Download secure_bootlader_ble_s132_pca10040) ( I use the PCA10056 devkit as a programmer to the custom board)

6. Custom board starts advertising on nRF Connect Desktop as "DfuTarg".

7. Opened the BLE Blinky project in <nRF5 SDK Folder>/examples/ble_peripheral/ble_app_blinky/pca10040/s132/ses/ble_app_blinky_pca10040_s132.emProject

8. Build the project successfully

9. Copied the ble_app_blinky_pca10040_s132.hex to the private key folder and changed its name to ble_blinky.hex

10. Generated the .zip package with the ble blinky app by running: 

nrfutil pkg generate --hw-version 52 --application-version 1 --application ble_blinky.hex --sd-req 0x0101 --sd-id 0x0101 --key-file private.key ble_blinky_dfu_package.zip

(0x0101 corresponds to s132 v7.2)

11. Connect to "DfuTarg" on nRF Connect, and uploaded ble_blinky_dfu_package.zip.   nRF Connect logs "DFU completed successfully." message

(this is where the problem starts)

12. Customboard is stuck on DFU Mode advertising as  "DfuTarg" even after reset and power cycle

13. Changed SDK_config NRF_BL_DFU_ENTER_METHOD_BUTTON  to 0. So I am sure that is not the hardware that is triggering the DFU mode.

14. Repeated the process but the custom board is still stuck on DFU mode after successfully uploading the new ble blinky app.

15. Checked the Debug log when uploading the app: 

<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
<debug> nrf_dfu_req_handler: Whole firmware image receiv<info> app: Inside main
<debug> app: In nrf_bootloader_init
<debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
<debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
<debug> nrf_dfu_settings: Using settings page.
<debug> nrf_dfu_settings: Copying forbidden parts from backup page.
<debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
<info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
<debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
<debug> app: Enter nrf_bootloader_fw_activate
<info> app: No firmware to activate.
<info> app: Boot validation failed. No valid app to boot.
<debug> app: DFU mode because app is not valid.
<info> nrf_bootloader_wdt: WDT is not enabled
<debug> app: in weak nrf_dfu_init_user
<debug> app: timer_stop (0x20005984)
<debug> app: timer_activate (0x20005984)
<info> app: Entering DFU mode.

So even though the app is uploaded successfully, the bootloader is not able to find it on the starting process so it defaults to DFU Mode. This queued me on a memory mapping problem, so I started looking for answers on the DEV Zone.

3. Spotting the problem

On the Dev Zone I ran into This Post that suggested that the problem was that my custom board uses the nRF52832-QFAB chip and no the QFAA version. The QFAA chip has 512kb of FLASH and 64kb of RAM, but the QFAB chip has 256kb of FLASH and 32kb of RAM. This suggests that the chip is running out of memory and the memory mapping configurations are wrong so the bootloader can't find the app on the initialization process.

If I look at the bootloader project build result it shows: 

So the bootloader is using more FLASH (507.8kb) and more RAM (42.4KB) than is available on the  QFAB chip.

Also the memory mapping that the project uses by default are:

1. Common/Code/Linker/Memory Segments: 

FLASH1 RX 0x0 0x80000;RAM1 RWX 0x20000000 0x10000;mbr_params_page RX 0x0007E000 0x1000;bootloader_settings_page RX 0x0007F000 0x1000;uicr_bootloader_start_address RX 0x10001014 0x4;uicr_mbr_params_page RX 0x10001018 0x4

2. Common/Code/Linker/Section Placement Macros: 

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x80000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x10000
FLASH_START=0x71000
FLASH_SIZE=0xd000
RAM_START=0x20005968
RAM_SIZE=0xa698

3. Common/Code/Preprocessor/ Preprocessor Definitions: 

BLE_STACK_SUPPORT_REQD
BOARD_PCA10040
CONFIG_GPIO_AS_PINRESET
DEBUG_NRF
FLOAT_ABI_HARD
INITIALIZE_USER_SECTIONS
NO_VTOR_CONFIG
NRF52
NRF52832_XXAA
NRF52_PAN_74
NRF_DFU_DEBUG_VERSION
NRF_DFU_SETTINGS_VERSION=2
NRF_DFU_SVCI_ENABLED
NRF_SD_BLE_API_VERSION=7
S132
SOFTDEVICE_PRESENT
SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION
uECC_ENABLE_VLI_API=0
uECC_OPTIMIZATION_LEVEL=3
uECC_SQUARE_FUNC=0
uECC_SUPPORT_COMPRESSED_POINT=0
uECC_VLI_NATIVE_LITTLE_ENDIAN=1

4. Trying Solutions (without success).

As This Post suggests, I changed the project configuration.

1. Changed  Common/Code/Linker/Memory Segments to : 

FLASH1 RX 0x0 0x40000;RAM1 RWX 0x20000000 0x8000;mbr_params_page RX 0x0003E000 0x1000;bootloader_settings_page RX 0x0003F000 0x1000;uicr_bootloader_start_address RX 0x10001014 0x4;uicr_mbr_params_page RX 0x10001018 0x4

2. Changed Common/Code/Linker/Section Placement Macros to : 

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x40000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x8000
FLASH_START=0x38000
FLASH_SIZE=0x6000
RAM_START=0x20005968
RAM_SIZE=0x2698

3. Changed Common/Code/Preprocessor/ Preprocessor Definitions NRF52832_XXAA to NRF52832_XXAB:

Also, as suggested by This Post I added these lines to the/components/libraries/bootloader/dfu/nrf_dfu_types.h file: 

#elif defined( NRF52832_XXAB )
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x0003F000UL)
    
...


#elif defined(NRF52832_XXAB)
    #define NRF_MBR_PARAMS_PAGE_ADDRESS         (0x0003E000UL)

I also added these lines at the beginning of main.c (just after all the #cludes)  to make sure that the configuration is correct: 

#define BOOTLOADER_START_ADDR (0x00038000UL)
#define BOOTLOADER_SETTINGS_ADDRESS (0x0003F000UL)
#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0003E000UL)

Now I ran into this problem: I try to build the project but I cant. I get this error: 

Building ‘secure_bootloader_ble_s132_pca10040_debug’ from solution ‘secure_bootloader_ble_s132_pca10040_debug’ in configuration ‘Release’
  Compiling ‘main.c’
  Linking secure_bootloader_ble_s132_pca10040_debug.elf
    .text is too large to fit in FLASH1 memory segment
    .dfu_trans is too large to fit in FLASH1 memory segment
    .svc_data is too large to fit in FLASH1 memory segment
    .log_const_data is too large to fit in FLASH1 memory segment
    .nrf_balloc is too large to fit in FLASH1 memory segment
    .log_backends is too large to fit in FLASH1 memory segment
    .sdh_ble_observers is too large to fit in FLASH1 memory segment
    .sdh_req_observers is too large to fit in FLASH1 memory segment
    .sdh_state_observers is too large to fit in FLASH1 memory segment
    .sdh_stack_observers is too large to fit in FLASH1 memory segment
    .sdh_soc_observers is too large to fit in FLASH1 memory segment
    .fs_data is too large to fit in FLASH1 memory segment
    .rodata is too large to fit in FLASH1 memory segment
    .data is too large to fit in FLASH1 memory segment
    .bss is too large to fit in RAM1 memory segment
    section .heap overlaps absolute placed section .stack
    .mbr_params_page is too large to fit in FLASH1 memory segment
    .bootloader_settings_page is too large to fit in FLASH1 memory segment
    section .stack VMA [0000000020007800,0000000020007fff] overlaps section .bss VMA [00000000200059d0,000000002000a1d7]
Build failed

So it seems that I am still running out of FLASH and that the project is using 507.8kb of Flash which is more than the 256kb of FLASH available on the QFAB version of the chip.

I also tried memory mappings from This post 1This Post 2 and, This Post 3 without success, all the mappings are similar but slightly different. And the error is always FLASH shortage.

So, In synthesis, I cannot build the project with what I think are the correct memory mapping configurations for the nRF52832-QFAB chip

5. Possible solutions and final questions.

I noticed that both the project for the nRF52840 and nRF52832 try to use all the FLASH on purpose (the nRF52840 project uses almost all the 1024kb of the available flash on the chip and the nRF52832 project uses almost all the 512kb of the available flash on the chip). I looked at other chips projects and this always repeats. I don't understand why the bootloader tries to use all the flash, but there must be some part of the project or some file that tells the compiler to use it all. The problem is that the QFAB chip has 256kb of FLASH and no 512kb of FLASH but I can't find any file or configuration where I can tell the project that my chip has only 256kb of FLASH.

Also, for the moment it seems that I have no problems with the RAM even though the QFAB chip has 32kb and the bootloader seem to need 42.4kb, but this will probably become a problem if I solve the FLASH problem.

So my final questions are:

1. Is it the nRF52832-QFAB having half the memory of the QFAA version and the memory mapping the real cause of my custom board being stuck on DFU mode and not finding any app even if the app was successfully uploaded by nRF connect? (It seems odd that with the wrong memory mapping configurations the bootloader builds, uploads, runs and downloads new apps successfully and just fails at initiating the loaded app)

2. What are the correct memory mapping configurations for the Secure DFU project that I need to change for it to work with the nRF52832-QFAB chip? This includes the (1) memory segments macros, (2) Section Placement Macros, (3) Preprocessor Definitions, (4) BOOTLOADER_START_ADDR, (5) BOOTLOADER_SETTINGS_ADDRESS, (6) NRF_MBR_PARAMS_PAGE_ADDRESS. ( I have found slightly different configurations on different posts and I don't know which one is the correct one.)

3. Are there other settings or macros that need to be modified that I am missing?

4. Was it correct for me to modify nrf_dfu_types,h?

5. Where can I tell the project to use 256kb of FLASH instead of 512kb of FLASH?

6. How can I solve the RAM shortage problem that will probably appear when the FLASH problem is solved?

 

6. My post resumed on one question: How can I make the secure DFU bootloader work on the nRF52832-QFAB chip work?

(I hope that the answer is not "change to the nRF52832-QFAA chip")

I hope somebody can help me with this issue. I would gladly give more information if needed and I hope the description is detailed enough.

Thanks,

Parents
  • Hi Agustin, 

    Could you send us the project you created, both the bootloader and the ble_app_blinky ?
    What you did in 4.3 seems to be correct. However at 4.1 I think the correct address should be :  

    FLASH_PH_START=0x0
    FLASH_PH_SIZE=0x40000
    RAM_PH_START=0x20000000
    RAM_PH_SIZE=0x8000
    FLASH_START=0x31000
    FLASH_SIZE=0xd000
    RAM_START=0x20005968
    RAM_SIZE=0x2698

    The reason for that is that you were building the secure_bootloader\pca10040_s132_ble_debug variant. If you build the secure_bootloader\pca10040_s132_ble you can use what you used. This explain why you get the "too large to fit in flash" error. 

    In the ble_app_blinky , you should also change the FLASH SIZE and RAM SIZE accordingly. 

    I would suggest to stick to the bootloader _debug variant  so that you can debug it. You can add a breakpoint inside dfu_enter_check() and check why it doesn't enter the app.

    There could be a chance that NRF_BL_DFU_ENTER_METHOD_BUTTON was enabled and the NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN (by default P0.16) was in active level causing the bootloader to stay in DFU mode. 

Reply
  • Hi Agustin, 

    Could you send us the project you created, both the bootloader and the ble_app_blinky ?
    What you did in 4.3 seems to be correct. However at 4.1 I think the correct address should be :  

    FLASH_PH_START=0x0
    FLASH_PH_SIZE=0x40000
    RAM_PH_START=0x20000000
    RAM_PH_SIZE=0x8000
    FLASH_START=0x31000
    FLASH_SIZE=0xd000
    RAM_START=0x20005968
    RAM_SIZE=0x2698

    The reason for that is that you were building the secure_bootloader\pca10040_s132_ble_debug variant. If you build the secure_bootloader\pca10040_s132_ble you can use what you used. This explain why you get the "too large to fit in flash" error. 

    In the ble_app_blinky , you should also change the FLASH SIZE and RAM SIZE accordingly. 

    I would suggest to stick to the bootloader _debug variant  so that you can debug it. You can add a breakpoint inside dfu_enter_check() and check why it doesn't enter the app.

    There could be a chance that NRF_BL_DFU_ENTER_METHOD_BUTTON was enabled and the NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN (by default P0.16) was in active level causing the bootloader to stay in DFU mode. 

Children
  • Hung,

    I changed the Section Placement Macros in the _debug project version as you suggested. I still can't build the project, but the errors were reduced to:

     

    Linking secure_bootloader_ble_s132_pca10040_debug.elf
        .bss is too large to fit in RAM1 memory segment
        section .heap overlaps absolute placed section .stack
        .mbr_params_page is too large to fit in FLASH1 memory segment
        .bootloader_settings_page is too large to fit in FLASH1 memory segment
        section .stack VMA [0000000020007800,0000000020007fff] overlaps section .bss VMA [00000000200059d0,000000002000a1d7]
    Build failed

    This suggests that there is still a FLASH shortage problem and a RAM Shortage Problem.

    For the non-debug project (and my original Section Placement MAcros suggestion) the build errors are:

      Linking secure_bootloader_ble_s132_pca10040.elf
        section .heap overlaps absolute placed section .stack
        .mbr_params_page is too large to fit in FLASH1 memory segment
        .bootloader_settings_page is too large to fit in FLASH1 memory segment
        section .stack VMA [0000000020007800,0000000020007fff] overlaps section .bss VMA [00000000200059b4,0000000020007f63]
    Build failed

    In this case there is only a FLASH shortage.

    I have NRF_BL_DFU_ENTER_METHOD_BUTTON defined as "0" so there is no pin activating the DFU mode on the custom board. Also, as a redundancy, I have defined NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN as "4" since P0.4 is a button on my custom board that I can easily control.

    I have adjusted FLASH size and RAM size accordingly on the ble_app_blinky project. The project builds without any errors and I can run it without problems on my custom board by uploading it using SES (I can not use DFU since the bootloader does not build).

    Finally, here I attach the ble_app_blinky project, the pca10040_s132_ble project, and the pca10040_s132_ble_debug project that I am using.

    0131.files.zip

Related