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

sdk17 ble_app_template fds_init() error FDS_ERR_NO_PAGES 0x860A when upgrading bootloader+sd+app via DFU from sdk12.3/sd3.1.0 to sdk17/sd7.0.1

Hello all,

I am developing a custom application on a Ruuvi tag with nrf52830 ic. I am using the latest sdk17 and softdevice s132 7.0.1. I am having problems updating the bootloader/sd/app from the original stock ruuvi fw that is based on sdk12.3 and has sd 3.1.0.

I have built my own bootloader using the dfu/secure_bootloader/pca10040_s132_ble_debug example with only minimal modifications. My application is based on the ble_peripheral/ble_app_template example.

I have tested the bootloader+sd+app combo by using mergehex and flashing via them all via the nrf52dk + nrfjprog.

This does not work when updating BL+SD+APP via DFU. I have managed to update the stock Ruuvi tag bootloader with the secure_bootloader example over DFU (BL + SD), and I have managed to also flash my application over the DFU using the new bootloader, however, the application fails to start with the following error:

<error> peer_manager_pds: Could not initialize flash storage. fds_init() returned 0x860A.
<error> peer_manager: pm_init failed because pds_init() returned NRF_ERROR_STORAGE_FULL.

And here is where it fails exactly in fds.c:

    fds_init_opts_t init_opts = pages_init();

    switch (init_opts)
    {
        case NO_PAGES:
        case NO_SWAP:
            return FDS_ERR_NO_PAGES;
            <...>

After reading through many posts with related fds page issues, I have come to the understanding that the reason fds_init() fails is that it cannot find any flash pages marked as empty/unused (as, i assume, nrfjprog --eraseall marks everything with some magic values). I am unable to find good information on how to erase the application data memory when updating via DFU.

The discussion here https://devzone.nordicsemi.com/f/nordic-q-a/28076/sdk-13-0-fds_init-causes-errors-unless-doing-a-full-flash-erase hints that the NVMC driver can be used to erase the flash data pages before running fds_init().

I have also added #define DFU_APP_DATA_RESERVED (CODE_PAGE_SIZE * 3) (as mentioned here https://devzone.nordicsemi.com/f/nordic-q-a/52581/fds_err_no_pages-problem) to my bootloader's sdk_config, which did not change anything.

My view is that there are two solutions for this, 1) have the flash be erased when doing an update via DFU (something similar to a partial nrfjprog --eraseall), or 2) Erase all application data from flash on first boot (or when the error occurs). I cant find definitive answers on how to do either of these. I believe no. 2 would be fairly straightforward, but im not quite sure what SDK funcitons to use for erasing flash, nor how to exactly find the bounds of the app data.

I would really appreciate any help and guidance with this issue.

  • Hi,

    The information you have already found is correct. When you get FDS_ERR_NO_PAGES, this effectively means that the FDS pages are corrupt, and cannot be used. If you are happy with losing the content, then the workaround is simply to erase the FDS pages before you initialize FDS.

    but im not quite sure what SDK funcitons to use for erasing flash, nor how to exactly find the bounds of the app data.

    The only thing you need to do is erase the flash pages. Assuming you do this after enabling the SoftDevice, this must be done via the SoftDevice (directly, or via a library). I suggest you use sd_flash_page_erase(). You should erase all FDS pages, which come from your application's sdk_config.h file. (This should be the same number of pages as you used to find DFU_APP_DATA_RESERVED in the bootloader, so it should be 3 in your case). Please note that FDS is also used by the peer manager to store bonding information, so you will lose all bonds when doing this.

    I have tested the bootloader+sd+app combo by using mergehex and flashing via them all via the nrf52dk + nrfjprog.

    This does not work when updating BL+SD+APP via DFU.

    I want to get back to this point, which gives a hint about the root cause of this issue. Can you confirm that the bootloader reserves the correct number of pages for FDS, or do you use a higher FDS page count? What is the value of FDS_VIRTUAL_PAGES and FDS_VIRTUAL_PAGE_SIZE in the application sdk_config.h? Has it been the same through all versions? And similarly with DFU_APP_DATA_RESERVED in the bootloader sdk_config.h?

  • Hello Einar and thank you for the quick reply!

    This does not work when updating BL+SD+APP via DFU.

    Sorry, i may have been a bit unclear. I have 2 separate DFU packages for updating, firstly i flash a DFU containing the new BL+SD, then i flash a DFU containing only the new app. The BL+SD+APP combined hex was only used as a test to ensure that the entire combination actually works together.

    I want to get back to this point, which gives a hint about the root cause of this issue. Can you confirm that the bootloader reserves the correct number of pages for FDS, or do you use a higher FDS page count?

    I do not know how to check or confirm this - the peer manager is just part of the ble_app_template example that my application is based on, and it uses the FDS . I have not actually modified any settings or source code related to the fds. I appreciate that i could remove the peer manager, but I believe i may need the bonding functionality in the future.

    The only related things i have modified in the bootloader and app is the flash memory layout to match the previous app layout, and to also accommodate the new softdevice size.

    What is the value of FDS_VIRTUAL_PAGES and FDS_VIRTUAL_PAGE_SIZE in the application sdk_config.h?

    I have checked the source for the original bootloader, and the sdk17 secure_bootloader example, and neither has FDS_VIRTUAL_PAGES nor FDS_VIRTUAL_PAGE_SIZE defined in the sdk_config.h.

    Should I define these parameters in the new bootloader? I would not be able to modify the original bootloader that I am trying to upgrade however.

    And similarly with DFU_APP_DATA_RESERVED in the bootloader sdk_config.h?

    This is not defined in the original bootloader, but i have set it to #define DFU_APP_DATA_RESERVED (CODE_PAGE_SIZE * 3) in the secure_bootloader example (which didnt have any effect).

    Please note that i am not interested in preserving any data during this particular upgrade. My goal is to replace the BL+SD+APP combo that comes pre-loaded on the devices without the devkit (though i may be interested in preserving app data in the future, but only when updating my the new custom application via DFU).

    I suggest you use sd_flash_page_erase(). You should erase all FDS pages, which come from your application's sdk_config.h file

    For a quick test, i have tried adding

        sd_flash_page_erase(0);
        sd_flash_page_erase(1);
        sd_flash_page_erase(2);

    before the peer manager init, however the erase fails with app: ERROR 15 [NRF_ERROR_FORBIDDEN].

    As a side note, in the APP, the following is defined (these were defined in the example by default):

    #define FDS_VIRTUAL_PAGES 3

    #define FDS_VIRTUAL_PAGE_SIZE 1024

    #define FDS_VIRTUAL_PAGES_RESERVED 0

  • Hi,

    nk1 said:

    I have checked the source for the original bootloader, and the sdk17 secure_bootloader example, and neither has FDS_VIRTUAL_PAGES nor FDS_VIRTUAL_PAGE_SIZE defined in the sdk_config.h.

    Should I define these parameters in the new bootloader?

    No. These configurations are found in the application's sdk_config.h. And they should match what you have configured for DFU_APP_DATA_RESERVED in the bootloader. If you have modified neither it should not be a problem as most SDK examples reserve 3 pages.

    nk1 said:
    Please note that i am not interested in preserving any data during this particular upgrade. My goal is to replace the BL+SD+APP combo that comes pre-loaded on the devices without the devkit (though i may be interested in preserving app data in the future, but only when updating my the new custom application via DFU).

    Then you can use the approach I suggested. It is a bit odd that you get this problem in the first place, though. Did you do a full chip erase before programming? But that is a different matter...

    nk1 said:
    however the erase fails with app: ERROR 15 [NRF_ERROR_FORBIDDEN].

    That is expected. You are not trying to erase the FDS pages in this case, but page 0-2 which is the MBR page and the two first pages of the SoftDeviec. This is not legal. You need to find out which pages you use for FDS. Please take a look at the memory layout in the bootloader documentation. The FDS pages are part of the application data here and are immediately below the bootloader. So if for instance the bootloader's start address is 0x78000 and you use 3 FDS pages (page size is 0x1000), this means that the page numbers are 117, 118, and 119.

  • I believe the example you have me of the page numbers 117, 118, 119, when the bl starts at 0x78, is not correct - based on the memory layout link the app data is stored downwards from the bl start.

    My bootloader starts at 0x75000, so i have erased the pages 0x74, 0x73, 0x72 as follows, and it solved my fds_init() issue:

        err_code = sd_flash_page_erase(0x74);
        APP_ERROR_CHECK(err_code);
        nrf_delay_ms(10);
    
        err_code = sd_flash_page_erase(0x73);
        APP_ERROR_CHECK(err_code);
        nrf_delay_ms(10);
    
        err_code = sd_flash_page_erase(0x72);
        APP_ERROR_CHECK(err_code);
        nrf_delay_ms(10);

    I realize its not a safe way to do this (as discussed here https://devzone.nordicsemi.com/f/nordic-q-a/48074/sd_flash_page_erase-error-code-success-but-flash-erase-fail - the sd_flash_page_erase generates an sd event when finished which should be consumed via sd handler) but this info may be useful for someone looking  for a quick hack, and i can take care of the proper implementation some time later.

    Thank you very much for your help Einar!

Related