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

OTA-DFU sometimes erases the application data unexpectedly

Hi,

We are facing an issue where the application data stored using FDS is erased one in a while after OTA-DFU multiple times.

This issue does not occur all the time, but it appears as often as 5% of the times.

We are developing the customized application based on the ble_peripheral/ble_app_uart example with the following environment:

  • Target Chip: nRF52832
  • SDK: v16.0.0
  • Soft Device: s132
  • Compiler: IAR

For the DFU, I used secure_bootloader exmaple and combined these 2 application to crated 1 .zip file by nrfutil to upload via nRF Tools app (either iOS or Android).

I have made sure that the following parameters are matched:

// In nrf_dfu_types.h
DFU_APP_DATA_RESERVED CODE_PAGE_SIZE * 3

// In sdk_config.h
FDS_VIRTUAL_PAGES 3

This problem occurs regardless of the application size to be uploaded, i.e. it doesn't matter if it's single-bank or dual-bank update.

Is there any possible factor this issue to happen only sometimes?

If anyone can suggest the way to resolve or to reproduce the issue with 100% frequency, it would be so helpful!

Thank you.

Parents
  • Hi Terje,

    Sorry about the delay.

    About your question regarding the power fail comparator, I asked my PCB designer and got the following answer:

    We are not using any feature for the abnormal power detection.

    The module is providing nRF52832 with 2.1V power generated from 3V battery by a linear regulator.

    When this issue occurred the 2.1V power supply as well as 3V battery was maintained and so as during OTA-DFU. 

    It was observed that the supply power was never below VPOF (1.7V).

    I hope this answers your question.

    Thank you.

  • Hi,

    Sorry for the very long delay from my side.

    Yes, it answered the question, and it means the issues that you see are more likely to stem from unidentified wrongly handled corner cases in FDS.

    Since my last reply, we have identified a potential issue that may leave the FDS pages without any swap page. It may be related, and I'll share the fix once we have a tested and verified solution.

    After having reread the previous entries in this thread, I noticed the following step:

    keni3 said:
    (4) Delete the flash page where the parameters are stored and over-write with the updated values

    Does that mean you delete the flash page through other means than deleting the records through the FDS API? Deleting FDS flash pages manually may leave FDS in an invalid state. If you used FDS to store records, you should use the proper FDS API calls to delete or update those records as well. You should not write to the FDS flash pages in any other way than through using the FDS API, or else there is no guarantee to data integrity.

    Alternatively, if it means this is a separate flash page from what is used for FDS, and both writing and erasing happens directly (not through FDS), then any issues there should not be related to FDS.

    Regards,
    Terje

Reply
  • Hi,

    Sorry for the very long delay from my side.

    Yes, it answered the question, and it means the issues that you see are more likely to stem from unidentified wrongly handled corner cases in FDS.

    Since my last reply, we have identified a potential issue that may leave the FDS pages without any swap page. It may be related, and I'll share the fix once we have a tested and verified solution.

    After having reread the previous entries in this thread, I noticed the following step:

    keni3 said:
    (4) Delete the flash page where the parameters are stored and over-write with the updated values

    Does that mean you delete the flash page through other means than deleting the records through the FDS API? Deleting FDS flash pages manually may leave FDS in an invalid state. If you used FDS to store records, you should use the proper FDS API calls to delete or update those records as well. You should not write to the FDS flash pages in any other way than through using the FDS API, or else there is no guarantee to data integrity.

    Alternatively, if it means this is a separate flash page from what is used for FDS, and both writing and erasing happens directly (not through FDS), then any issues there should not be related to FDS.

    Regards,
    Terje

Children
  • Hi Terje,

    Thank you for your update.

    I will wait for the fix you are working on! Glad to hear that there will be a cure to this issue.

    About your question, I DO use the FDS API to whenever accessing the flash.

    What I wrote may have been misleading because I used the word "flash page" instead of "flash record".

    More specifically, I use fds_record_delete() to delete and clean the record and then use fds_record_write() to re-write the updated parameters. When deleting, fds_record_find() is used with the same FILE_ID and REC_KEY as set in the descriptor for fds_record_write().

    Regards,

    Keni

  • Hi,

    We now have a patch for the newly found issue that may lead to no swap pages in FDS:

    One file need to be changed, and the required change is as follows:

    In <sdk folder>/components/libraries/fds/fds.c, in the function init_execute(), in the switch case FDS_OP_INIT_PROMOTE_SWAP, remove the lines:

                // When promoting the swap, keep the write_offset set by pages_init().
                ret = page_tag_write_data(m_swap_page.p_addr);
    

    In the same switch case, add the following lines right before the break:

                // Promote the old swap page to data, but do this at the end
                // because we can re-enter this function; we must update have
                // updated the page in RAM before that.
                ret = page_tag_write_data(p_old_swap);

    So that the full case FDS_OP_INIT_PROMOTE_SWAP now looks like this:

            case FDS_OP_INIT_PROMOTE_SWAP:
            {
                p_op->init.step       = FDS_OP_INIT_TAG_SWAP;
    
                uint16_t const         gc         = m_gc.cur_page;
                uint32_t const * const p_old_swap = m_swap_page.p_addr;
    
                // Execute the swap.
                m_swap_page.p_addr = m_pages[gc].p_addr;
                m_pages[gc].p_addr = p_old_swap;
    
                // Copy the offset from the swap to the new page.
                m_pages[gc].write_offset = m_swap_page.write_offset;
                m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
    
                m_pages[gc].page_type = FDS_PAGE_DATA;
    
                // Promote the old swap page to data, but do this at the end
                // because we can re-enter this function; we must update have
                // updated the page in RAM before that.
                ret = page_tag_write_data(p_old_swap);
            } break;

    This fix is verified to work with nRF5 SDK v17.

Related