Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Internal flash memory data not getting deleted even after using fds_file_delete(); function

Hi,

I am using the Nordic NRF52832_dk with SDK 16.

I need to write, read, and delete data in flash memory.

I store the data by creating a file in the flash memory. To delete it, I use the fds_file_delete() function and then run garbage collection by calling fds_gc(). However, even after deleting, the data is not being erased from the memory, and I can still read the file.

Regards,

Mridula

Parents
  • Hello,

    Can you please show me some snippets (or the entire main.c file) on how you write, delete, gc and read the files?

    What HW are you running this on? Is it the nRF52832 DK?

    Best regards,

    Edvin

  • Hi,
       Thank you for the reply .
       We use the following functions for write ,read, delete and gc the  files

    To write data:

    static ret_code_t write_data_to_flash()
    {
        ret_code_t ret;

        __ALIGN(4) static uint8_t fds_flash_data[24] = {0};
        fds_record_t        record;
        fds_record_desc_t   record_desc;

        nvm_data.header= 0x10;
        nvm_data.footer = 0x11;
        memcpy(fds_flash_data,&nvm_data,sizeof(nvm_data));
      
           
       
        record.file_id           = TIME_UPDATE_FILE;
        record.key               = TIME_UPDATE_REC_KEY;
        record.data.p_data       = &fds_flash_data;
        /* The following calculation takes into account any eventual remainder of the division. */
        record.data.length_words =  sizeof(fds_flash_data)/sizeof(uint8_t);

        ret = fds_file_delete(TIME_UPDATE_FILE);
            wait_for_fds_delete();
        fds_gc();
            m_delete_all=false;
            if (ret != NRF_SUCCESS)
        {
            APP_ERROR_CHECK(ret);
            return ret;
        }
        ret = fds_record_write(&record_desc, &record);
        if (ret != NRF_SUCCESS)
        {
            APP_ERROR_CHECK(ret);
            return ret;
        }
        return NRF_SUCCESS;
    }

    To read data:

               
    static void get_data_from_flash()
    {
            fds_record_desc_t desc = {0};
            fds_find_token_t  ftok ={0};
            fds_flash_record_t config = {0};
             uint8_t *flash_data;
         
            uint8_t rtc_timestamp[14] = {0};
            ret_code_t err_code;
            err_code = fds_record_find(TIME_UPDATE_FILE, TIME_UPDATE_REC_KEY, &desc, &ftok);
            if (err_code != NRF_SUCCESS)
            {
                    #ifdef DEBUG_ENABLED
                    SEGGER_RTT_printf(0,"No flash record found\r\n");
                    #endif //DEBUG_ENABLED
                    memset(&nvm_data,0,sizeof(nvm_data));
            }
            else
            {
                 
                 /* Open the record and read its contents. */
                    err_code = fds_record_open(&desc, &config);
                    APP_ERROR_CHECK(err_code);
                    /* Copy the configuration from flash into m_dummy_cfg. */
                    flash_data =  (uint8_t *) config.p_data;
                     #ifdef DEBUG_ENABLED
                    SEGGER_RTT_printf(0,"Read data from flash length  0x%x \n\r",
                    config.p_header->length_words);
                     #endif //DEBUG_ENABLED
                    err_code = fds_record_close(&desc);
                    memcpy(&nvm_data,flash_data,sizeof(nvm_data));
            }

    }

    To delete data:

    ret = fds_file_delete(FILE_NAME);
        fds_gc();


    Hardware information:

          We use an ANNA-B112 SiP to run the program.


    Regards,
    Mridula

  • Hello Mridula,

    Is it possible to upload all the files that you have changed (probably .zip the application folder, and upload that, unless you changed any standard SDK files)?

    Particularly, I can't see your wait_for_fds_delete() function. 

    In addition, I see that you are using wait_for_fds_delete() after you delete the file using fds_file_delete(), but not after you do fds_gc(), and not after you do fds_record_write().

    In general, all of these functions takes time to perform, and the function calls return before the task is complete. Therefore, I guess what happens is that you delete the file, but then read it before the record is actually deleted. 

    However, even after deleting, the data is not being erased from the memory, and I can still read the file.

    It is not clear to me where you did this. Is that using the write_data_to_flash(), or:

    mridula said:
    To delete data:

    ret = fds_file_delete(FILE_NAME);
        fds_gc();

    Because if it is the last one, then you do not wait at all. 

    Make sure that you wait for the callbacks from FDS, and check that it's status is FDS_SUCCESS. Particularly on the functions that will change the content in flash.

    Also, as a note:

    It is not recommended to perform fds_gc() too frequently. You can keep deleting and adding new files until you get an error message saying it is full. Alternatively, you can use fds_status() to see how much more space you have.

    The reason not to use fds_gc() too often is that it will wear out the flash faster than necessary. 

    Also, you can use fds_record_update() to update an existing fds record. It will automatically delete the old one and write a new one for you. Just for simplicity.

    Best regards,

    Edvin

  • Hi Edvin,
         Actually the function to delete the file  

    ret = fds_file_delete(FILE_NAME);
        fds_gc();

    is called independently .

    We call this function before resetting the MCU using NVIC_SystemReset();
    and after starting again when we read it we are able to find the records that we deleted.

    Even though we got FDS_SUCCESS from the call backs.

    Unfortunately we wont be able to send the application files due to privacy concerns.

    Regards,

    Mridula

  • Make sure that you wait for the callback (not only return value from fds_gc()) before you reset. If not, you will just queue up the fds_file_delete and fds_gc() and then reset before they actually happen. 

    Try something like this:

    volatile bool flash_ready = false;
    
    void fds_callback_handler(status)
    {
        if (status == FDS_SUCCESS)
        {
            flash_ready = true;
        }
    }
    
    void wait_for_flash()
    {
        while (flash_ready == false)
        {
            // Wait.
        }
        flash_ready = false;
    }
    
    
    void some_function()
    {
        ret = fds_file_delete(...);
        APP_ERROR_CHECK(ret);
        wait_for_flash();
        ret = fds_gc();
        APP_ERROR_CHECK(ret);
        wait_for_flash();
        NVIC_SystemReset();
    }

    This is pseudo code, but use the flash callback handler and something similar to your wait_for_fds_delete() to wait for the flash operations to finish before you move on.

    Best regards,

    Edvin

Reply
  • Make sure that you wait for the callback (not only return value from fds_gc()) before you reset. If not, you will just queue up the fds_file_delete and fds_gc() and then reset before they actually happen. 

    Try something like this:

    volatile bool flash_ready = false;
    
    void fds_callback_handler(status)
    {
        if (status == FDS_SUCCESS)
        {
            flash_ready = true;
        }
    }
    
    void wait_for_flash()
    {
        while (flash_ready == false)
        {
            // Wait.
        }
        flash_ready = false;
    }
    
    
    void some_function()
    {
        ret = fds_file_delete(...);
        APP_ERROR_CHECK(ret);
        wait_for_flash();
        ret = fds_gc();
        APP_ERROR_CHECK(ret);
        wait_for_flash();
        NVIC_SystemReset();
    }

    This is pseudo code, but use the flash callback handler and something similar to your wait_for_fds_delete() to wait for the flash operations to finish before you move on.

    Best regards,

    Edvin

Children
No Data
Related