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

Using FDS Flash storage for user settings as well as for DFU

I am building on a BLE DFU project which already has a NRF_FSTORAGE_DEF for allocation of non-volatile data used by DFU.
I want to add another instance of NRF_FSTORAGE_DEF for use with application setting data.

Can I define two different regions in Flash for this purpose, or do all uses of NRF_FSTORAGE_DEF need to be in a contiguous block of Flash memory?

One problem is that m_fs is used for both instance - which is easily fixed by renaming the DFU one to m_dfu_fs to avoid a name conflict.

The DFU section is set to between 0x7F000 - 0x80000.

Can I set my other section to 0x20000 - 0x22000?

I tried this and it compiles and runs OK, but when the pages_init() function is called on initialization of the FDS module, all three pages are marked as FDS_PAGE_UNDEFINED and are not erased, so all three are discounted and the function returns NO_PAGES.

I have the following settings in sdk_config.h:

#define FDS_VIRTUAL_PAGES 3

#define FDS_VIRTUAL_PAGE_SIZE 1024

#define FDS_VIRTUAL_PAGES_RESERVED 0

Are these settings correct for what I need?

If the Flash fs_data section needs to be contiguous, how should the region be defined? In the project settings or in code (as is done for the DFU region)?

Thanks...

Declan Traill

  • I am using the latest SDK (nRF5_SDK_15.3.0_59ac345)

    I tried changing to s132_nrf52_6.1.1_softdevice.hex and also changing the Flash region for the application from staring at 0x23000 to 0x26000 (due to the softdevice change).

    The flash_bounds_set() function still tries to set the pages address to 0x21000 - 0x24000 and finds all pages to be FDS_PAGE_UNDEFINED and not erased.

    If I override the flash_bounds_set() function and set the start/end address for my FDS region to 0x7A000 - 0x7E000, then the pages are found OK, but when a write is attempted it returns NRF_ERROR_INTERNAL.

    The FDS area is not 0x1000 - 0x3000. I just tried that once following your suggestion about placing it at the bottom of the Flash, before I realized that the softdevice was occupying that region.

    Can you see why the FDS module keeps wanting to set the Flash region to 0x21000 - 0x24000?

    I there some project setting/config that determines this that I need to change?

  • I found that the flash_bounds_set() function was using the defined BOOTLOADER_START_ADDR to determine where to put the FDS region (just below the bootloader as you suggested), but the value of BOOTLOADER_START_ADDR was set to 0x26000 which is the start of the application Flash region. So by adding a global setting for BOOTLOADER_START_ADDR = 0x78000 into the project file, the bootloader location can be specified, and the FDS area is then put below it, and further down is the application code (from 0x26000 to 0x4326C). This then seems to work OK.

  • Hi Declan, 
    Are you sure it was BOOTLOADER_START_ADDR  ? but not BOOTLOADER_ADDRESS. As far as I know the BOOTLOADER_START_ADDR  only used in the bootloader. This is how my flash_end_addr() looks like: 

    static uint32_t flash_end_addr(void)
    {
    uint32_t const bootloader_addr = BOOTLOADER_ADDRESS;
    uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;

    #if defined(NRF52810_XXAA) || defined(NRF52811_XXAA)
    // Hardcode the number of flash pages, necessary for SoC emulation.
    // nRF52810 on nRF52832 and
    // nRF52811 on nRF52840
    uint32_t const code_sz = 48;
    #else
    uint32_t const code_sz = NRF_FICR->CODESIZE;
    #endif

    uint32_t end_addr = (bootloader_addr != 0xFFFFFFFF) ? bootloader_addr : (code_sz * page_sz);

    return end_addr - (FDS_PHY_PAGES_RESERVED * FDS_PHY_PAGE_SIZE * sizeof(uint32_t));
    }

    And here is flash_bound_set: 

    static void flash_bounds_set(void)
    {
    uint32_t flash_size = (FDS_PHY_PAGES * FDS_PHY_PAGE_SIZE * sizeof(uint32_t));
    m_fs.end_addr = flash_end_addr();
    m_fs.start_addr = m_fs.end_addr - flash_size;
    }

  • Yes, they are the same, but if you follow the definitions, you see BOOTLOADER_START_ADDR at the end of the line:

    #define BOOTLOADER_ADDRESS      ((*(uint32_t *)MBR_BOOTLOADER_ADDR) == 0xFFFFFFFF ? *MBR_UICR_BOOTLOADER_ADDR : *(uint32_t *)MBR_BOOTLOADER_ADDR) /**< The currently configured start address of the bootloader. If 0xFFFFFFFF, no bootloader start address is configured. */

    /** @brief Location (in the flash memory) of the bootloader address. */
    #define MBR_BOOTLOADER_ADDR      (0xFF8)

    /**
     * @brief Location of the pointer to the start of the bootloader.
     *
     * See also @c BOOTLOADER_ADDRESS in @c app_util.h.
     */
    #define NRF_UICR_BOOTLOADER_START_ADDRESS       (MBR_BOOTLOADER_ADDR)



        uint32_t  m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS)))
                                                        = BOOTLOADER_START_ADDR;


  • Hi Declan, 

    I'm sorry my mistake. I was confused with a similar case with fds in the application. In your case you are using it within the bootloader. 

    In the bootloader BOOTLOADER_START_ADDR is defined as (CODE_START)

    And CODE_START is defined as 

    #define CODE_START ((uint32_t)&Load$$LR$$LR_IROM1$$Base) 

    Which matches with the start address of the bootloader (address 0x78000) 

    We need to check why it points to 0x26000 in your case ? 

Related