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

FDS NO_SWAP error - no swap pages

Using SDK 16.0.0 on an nRF 52840 board.

Managed to get a board into a state where it had only data pages and no swap pages, and therefore fds_init fails with the NO_SWAP code from pages_init. Saw some other similar tickets, but none of them exactly the same. I have three pages all of which start with DEADC0DE F11E01FE. Only one page has any data after those markers. See attached document for flashdump. /cfs-file/__key/support-attachments/beef5d1b77644c448dabff31668f3a47-6a8175cd5d964af9875cb467636629a7/flashdump.txt

I am using the peer manager as well as storing a few configuration values in the FDS, which has all been working fine up until this board started failing on startup. I call garbage collection just after initialization whenever the board is booted, and I believe the peer manager also calls it as needed?

My theory is that garbage collection was interrupted by a power off at some specific point (similar to this bug https://devzone.nordicsemi.com/f/nordic-q-a/53687/fds---missing-swap-page), but I can't replicate this. The fix for that bug was implemented inside the FDS_PAGE_SWAP case in pages_init, which my code never reaches since all of my pages are marked as data.

Even without knowing the exact cause, it would be great to be able to implement recovery when this error code is returned. I know that means erasing a page and then reinitializing, but I can't seem to figure out how to erase the correct "page number" using sd_flash_page_erase. I can't access the start_addr of the FDS pages from outside the module - is there any way to get this value without recalculating it?

Parents
  • Hi, 

    Even without knowing the exact cause, it would be great to be able to implement recovery when this error code is returned. I know that means erasing a page and then reinitializing, but I can't seem to figure out how to erase the correct "page number" using sd_flash_page_erase.

     You would have to iterate page for page through the flash looking for an empty data page that hasn't been written to yet. You can do this by making a new function that is similar to the page_can_tag function but starts to check the page data after the page tag:

    static bool page_can_tag2(uint32_t const * const p_page_addr)
    {
        // This function should consider pages that have only the first half
        // of the fds page tag written as erased (taggable).
        // That is because the tag is two words long, and if the device
        // has rebooted after writing the first word, that would cause
        // the page to be unusable (since undefined and not fully erased).
        // By considering the first word as erased if it contains fds page tag,
        // the page can be re-tagged as necessary.
    
        if ((p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_ERASED_WORD) &&
            (p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_PAGE_TAG_MAGIC))
        {
            return false;
        }
    
        // Ignore the tag and check if the rest of the page is written or not
        for (uint32_t i = FDS_PAGE_TAG_SIZE; i < FDS_PAGE_SIZE; i++)
        {
            if (*(p_page_addr + i) != FDS_ERASED_WORD)
            {
                return false;
            }
        }
    
        return true;
    }
    

    You can call this function for each data page and see if it has been written to or not. If it hasn't then you can delete it and reset the chip which will cause the system to promote the page to a swap page.

    regards

    Jared

Reply
  • Hi, 

    Even without knowing the exact cause, it would be great to be able to implement recovery when this error code is returned. I know that means erasing a page and then reinitializing, but I can't seem to figure out how to erase the correct "page number" using sd_flash_page_erase.

     You would have to iterate page for page through the flash looking for an empty data page that hasn't been written to yet. You can do this by making a new function that is similar to the page_can_tag function but starts to check the page data after the page tag:

    static bool page_can_tag2(uint32_t const * const p_page_addr)
    {
        // This function should consider pages that have only the first half
        // of the fds page tag written as erased (taggable).
        // That is because the tag is two words long, and if the device
        // has rebooted after writing the first word, that would cause
        // the page to be unusable (since undefined and not fully erased).
        // By considering the first word as erased if it contains fds page tag,
        // the page can be re-tagged as necessary.
    
        if ((p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_ERASED_WORD) &&
            (p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_PAGE_TAG_MAGIC))
        {
            return false;
        }
    
        // Ignore the tag and check if the rest of the page is written or not
        for (uint32_t i = FDS_PAGE_TAG_SIZE; i < FDS_PAGE_SIZE; i++)
        {
            if (*(p_page_addr + i) != FDS_ERASED_WORD)
            {
                return false;
            }
        }
    
        return true;
    }
    

    You can call this function for each data page and see if it has been written to or not. If it hasn't then you can delete it and reset the chip which will cause the system to promote the page to a swap page.

    regards

    Jared

Children
Related