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

Linking for nRF52832-QFAB and SDK11

Hi!

We are using nRF52832-QFAB (B0 variant) in one of our projects, and it works fine and well.

We are now in the process of using the nRF52832-QFAB-E0 in the same build, but then we run into problems.

We are aware of the "problem" with B0 variant, which have 512 kB flash and 64 kB RAM, while the E0 only have 256/32.
This should not be a problem since the code is small enough and will fit with not problem.

Since the memory is only half in the E0 variant, the bootloader must be placed in lower memory (0x3nnnn instead of 0x7nnnn), and this could be achived using nrfutil to get a new bootload_setting.hex (using the family setting NRF52QFAB), but we also had to update the file dfu_gcc_nrf52.ld and dfu_types.h, changing all 0x7 addresses to 0x3.

But, anyway we do it, we fail somehow. Ie we see that changing the values we either get the application to work but fota (dfu) will fail:

#define BOOTLOADER_REGION_START             0x0007A000
=> app boot: ok, fota: nok

When changing the address in the .ld/.h files, the dfu seems to work, but then the application wont start:
#define BOOTLOADER_REGION_START             0x0003A000
=> app boot: nok, fota: ok

It seems as if the following test fails:

  if (p_bootloader_settings->bank_0 == BANK_VALID_APP)

So, obviously we have missed something while trying to set up the project to work with nRF52832-QFAB E0 variant.

Could you please help me to show which changes and tools to use to be able to link correctly for the nRF52832-QFAB variant E0 using SDK11, ie only using 256/32 kB of memory?

Best regards,
Thomas

  • Hi Thomas,

    Sorry for the delayed response. It sounds like you've already made the necessary changes to make the bootloader run on this smaller memory variant. But are you sure you used the QFAB package variant and not the QFAA earlier? The build code ( B0 vs E0) is related to silicon revision and not memory configuration as you can see from the table here: SoC revisions and variants.

    Probably the only relevant difference between these 2 silicon revisions is this errata: [163] FICR: Code and RAM size fields do not match chip specification.

    Since the memory is only half in the E0 variant, the bootloader must be placed in lower memory (0x3nnnn instead of 0x7nnnn), and this could be achived using nrfutil to get a new bootload_setting.hex (using the family setting NRF52QFAB), but we also had to update the file dfu_gcc_nrf52.ld and dfu_types.h, changing all 0x7 addresses to 0x3.

    nrfutil generates the settings page with the format for our secure bootloader introduced in SDK v12. The legacy bootloader in SDK 11 had a simpler format which made it easier to validate a programmed app without creating a settings page. E,g, you can set the BANK_VALID_APP flag with the debugger like this: nrfjprog --memwr <bootloader settings page address> --val 0x1.

    Best regards,

    Vidar

  • Hi Vidar,

    Thanks for the reply - sorry for my late response (vacation times ...)!

    No, we have been using QFAB-B0, and have been building and linking as if the device have 512/64 kB memory, and this works fine.

    We then changed to QFAB-E0 and then it failed to flash (since the upper memory doesn't exist), we have also used QFAA successfully:

    Version             Memory           Work

    QFAAEO            512/64 kB         OK

    QFABB0             512/64 kB         OK (we know that the specification says 256/32, but it works as if 512/64)

    QFABE0             256/32 kB         Not OK (fails to flash - memory pages not found)

    So the same software we have build works in QFAB-B0 but not in QFAB-E0

    We had to re-compile and link the software to fit inside the QFAB-E0, but we are only partially successfully, as described, either the application works (but not dfu), or we can get the dfu to work but not the application, by changing the define BOOTLOADER_REGION_START (as described above). And why does it fail checking the BANK_VALID_APP then?

    Please note that the software is small enough to fit within 264/32, so that is not the problem, my guess is that this is only a configuration mismatch somewhere (flashing works, the application works, but we can't get the application and dfu to work at the same time - ie we can't get firmware update to work when the application is running).

    So, my question is, how should we setup to compile and link using SDK11 for the QFAB-E0 version, do we need to manually update some files (eg dfu_gcc_nrf52.ld), or should it work by generating new bootloader_settings? We have tried both ways but failed, so I guess that we are just missing something in our build steps.

    Any suggestions, or could you point to some example code, that uses SDK11, Softdevice and works with QFAB-E0?

    Best regards,
    Thomas

  • Hi Thomas,

    I've looked through the bootloader to refresh my memory, and it looks it should be sufficient to adjust the layout in the linker script and update the address symbols in nrf_dfu_types.h as you've done already:

    diff --git a/components/libraries/bootloader_dfu/dfu_types.h b/components/libraries/bootloader_dfu/dfu_types.h
    index 9a4f705..506708f 100644
    --- a/components/libraries/bootloader_dfu/dfu_types.h
    +++ b/components/libraries/bootloader_dfu/dfu_types.h
    @@ -54,7 +54,13 @@
     
     #endif      
     
    +#elif NRF52832_XXAB
     
    +#define BOOTLOADER_REGION_START             0x0003A000                  /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
    +#define BOOTLOADER_SETTINGS_ADDRESS         0x0003F000                  /**< The field specifies the page location of the bootloader settings address. */
    +#define BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS  0x0003E000                  /**< The field specifies the page location of the mbr params page address. */
    +        
    +#define CODE_PAGE_SIZE                      0x1000                      /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */
             
     #elif NRF52     
             
    diff --git a/examples/dfu/bootloader/custom_board_nrf52832_xxab/dual_bank_ble_s132/armgcc/Makefile b/examples/dfu/bootloader/custom_board_nrf52832_xxab/dual_bank_ble_s132/armgcc/Makefile
    index edfd7d7..03f75fe 100644
    --- a/examples/dfu/bootloader/custom_board_nrf52832_xxab/dual_bank_ble_s132/armgcc/Makefile
    +++ b/examples/dfu/bootloader/custom_board_nrf52832_xxab/dual_bank_ble_s132/armgcc/Makefile
    @@ -103,6 +103,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS
     
     #flags common to all targets
     CFLAGS  = -DNRF52
    +CFLAGS += -DNRF52832_XXAB
     CFLAGS += -DBOARD_PCA10040
     CFLAGS += -DNRF52_PAN_12
     CFLAGS += -DNRF52_PAN_15
    diff --git a/examples/dfu/bootloader/dfu_gcc_nrf52832_xxAB.ld b/examples/dfu/bootloader/dfu_gcc_nrf52832_xxAB.ld
    index 332b78f..00295f4 100644
    --- a/examples/dfu/bootloader/dfu_gcc_nrf52832_xxAB.ld
    +++ b/examples/dfu/bootloader/dfu_gcc_nrf52832_xxAB.ld
    @@ -11,7 +11,7 @@ MEMORY
        *  those values do not match. The check is performed in main.c, see
        *  APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
        */
    -  FLASH (rx) : ORIGIN = 0x7A000, LENGTH = 0x4000
    +  FLASH (rx) : ORIGIN = 0x3A000, LENGTH = 0x4000
     
       /** RAM Region for bootloader. This setting is suitable when used with s132. */
       RAM (rwx) :  ORIGIN = 0x20002C00, LENGTH = 0x5380
    @@ -22,13 +22,13 @@ MEMORY
       NOINIT (rwx) :  ORIGIN = 0x20007F80, LENGTH = 0x80
     
       /** Location of bootloader setting in flash. */
    -  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000
    +  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0003F000, LENGTH = 0x1000
     
       /** Location in UICR where bootloader start address is stored. */
       UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
       
       /** Location of mbr params page in flash. */
    -  MBR_PARAMS_PAGE (rw) : ORIGIN = 0x0007E000, LENGTH = 0x1000
    +  MBR_PARAMS_PAGE (rw) : ORIGIN = 0x0003E000, LENGTH = 0x1000
       
       /** Location in UICR where mbr params page address is stored. */
       UICR_MBR_PARAM_PAGE(r) : ORIGIN = 0x10001018, LENGTH = 0x04

    So I think the problem must be with the BL settings page you're using. Note that the nrfutil tool only supports generation of settings pages with the new settings format required by our secure bootloader introduced in SDK 12. The legacy format is much simpler. You can validate the app simply by writing 0x1 to the first word in your settings page like this: nrfjprog --memwr 0x3A000 --val 1 && nrfjprog --reset

    Lastly, not related to this problem, but since you are using SDK 11, please remember to apply our proposed workaround for errata 108 in your startup code ([108] RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode).

    Best regards,

    Vidar

  • Hi Vidar,

    Thanks for your information!


    I'm still haven't get a good grip on the problem and have some follow upp questions.

    You suggested to use memwr to update the BANK_VALID_APP byte (nrfjprog --memwr 0x3A000 --val 1 && nrfjprog --reset), but shuldn't that be address 0x3F000? As far as I can see, the bootloader settings page reside at 0x3F000.

    (At 0x3A000 is the byte 0x80, and that can not be changed by memwr without erasing the whole page.)

    What is written to that page (0x3F000) is the following:

      :10 F000 00 4188A0B0010000000000000001000000 E5
      :10 F010 00 00000000000000000000000000000000 F0
      :10 F020 00 00000000000000000000000000000000 E0
      :10 F030 00 00000000000000000000000000000000 D0
      :10 F040 00 00000000000000000000000000000000 C0
      :0C F050 00 000000000000000000000000 B4

    So, changing 0x41 (which is no valid code bank state eg BANK_VALID_APP) to 0x01 makes the test above pass, but then we stop at the next test which is a crc-check. If we skip these two test all together (by updating the code), then we pass and it seems to work fine again (both application and dfu).

    Where does these 92 bytes (0x5C) comes from, ie what is the 0x41 placed at 0x3F000? And is 0x01B0A088 the crc?

    So the bootloader_settings content seems to be faulty somehow, but I can't see how ...

    Best regards,

    Thomas

  • Hi Thomas,

    You suggested to use memwr to update the BANK_VALID_APP byte (nrfjprog --memwr 0x3A000 --val 1 && nrfjprog --reset), but shuldn't that be address 0x3F000? As far as I can see, the bootloader settings page reside at 0x3F000.

    Yes, sorry, I meant to say 0x3F000.

    What is written to that page (0x3F000) is the following:

      :10 F000 00 4188A0B0010000000000000001000000 E5
      :10 F010 00 00000000000000000000000000000000 F0
      :10 F020 00 00000000000000000000000000000000 E0
      :10 F030 00 00000000000000000000000000000000 D0
      :10 F040 00 00000000000000000000000000000000 C0
      :0C F050 00 000000000000000000000000 B4

    How was this settings page generated? If it was generated with nrfutil, the first word would be holding a 32-bit checksum value as is required by the secure bootloader, instead of the bank_0 code expected by the legacy bootloader. Here you can see the legacy bootloaders' settings format: bootloader_settings_t(boot validation of app is skipped when bank_0_crc==0)

    Assume everything works if you don't program the settings page but only run the --memwr command as I mentioned?

    Best regards,

    Vidar

Related