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

Flash Memory Issue

Hi,
I have written these 3 functions to erase/read and write.

/////////////////////////////////////////////////////////////////////////////// SNV

const uint32_t f_addr = 0x000FF000; // Last page start address 255

// Create a pointer to that address
uint32_t * p_addr = (uint32_t *)f_addr; //cast f_addr to a pointer

uint32_t erase_SNV()
{
    NRF_LOG_INFO("Memory Erased");
    return sd_flash_page_erase(255);
}


uint32_t write_SNV(int address,uint8_t value)
{
    uint32_t val;
    val=value;
    NRF_LOG_INFO("Data Write in Flash");
    ret_code_t err_code;
    err_code = sd_flash_write(p_addr+address, &val, sizeof(val));
    APP_ERROR_CHECK(err_code);
    return err_code;
}

uint32_t read_SNV(int address)
{
     NRF_LOG_INFO("The Data read from flash is: %d", *(p_addr)+address);
     return *(p_addr)+address;
}


When I write any value from address 1 it gives following wrong output(0 1 2 3).
    write_SNV(1,11);
    read_SNV(1);
    write_SNV(2,12);
    read_SNV(2);
    write_SNV(3,13);
    read_SNV(3);

  //  read_SNV(0);
    read_SNV(1);
    read_SNV(2);
    read_SNV(3);
 



But When I start address from 0 it gives the right values.

    write_SNV(0,10);
    read_SNV(0);
    write_SNV(1,11);
    read_SNV(1);
    write_SNV(2,12);
    read_SNV(2);
    write_SNV(3,13);
    read_SNV(3);

    read_SNV(0);
    read_SNV(1);
    read_SNV(2);
    read_SNV(3);




How can I save values in rondom addresses?
Thanks!

Parents
  • Hello,

    I think you should read up on flash handling before doing this. I suggest that you check out the flash_fds or the flash_fs example, but I can try to explain why this is not working.

    And by the way, if you upload the examples that you use to test it is faster for us to browse your code, and find the references to the SDK\softdevice functions you are using.

    Are you sure that you have pasted the implementation you are using? I suspect you have removed at least one APP_ERROR_CHECK(err_code)?

    Flash operations are fairly slow, compared to the runtime of your application. If I try to run your application implementation, the first write_SNV() is working fine, but the next is generating an error because APP_ERROR_CHECK(err_code) is called with err_code = 17, returned from sd_flash_write(). This is because there is already a flash operation ongoing. 

    If the first flash write is not yet done, it is not possible to read out the flash that you are not yet finished writing in between.

    This is why I recommend you looking into the flash_fs example. When you set up a proper flash handler, you can wait for the flash callback before you try to read it back. Try to search for the flash tickets here on devzone. There are probably hundreds of flash related tickets related to this kind of issue. 

    Best regards,

    Edvin

  • Hi ,

    Sorry for the late reply.Can I add a handler in my current code?

    I am trying this. Is this the correct way?
    Or any suggestion to fix the issue in this code?

    uint32_t write_SNV(int address,uint8_t value)
    {
        uint32_t val;
        val=value;
        ret_code_t         err_code;
        err_code=NRF_ERROR_BUSY;
       // NRF_LOG_INFO("Data Write in Flash");
    
       // err_code = sd_flash_write(p_addr+address, &val, sizeof(val));
        
    
        while(err_code!=NRF_SUCCESS)
        {
        err_code = sd_flash_write(p_addr+address, &val, sizeof(val));
        }
        
    //    APP_ERROR_CHECK(err_code);
    
    
      if(err_code==NRF_ERROR_INTERNAL)
      {
       NRF_LOG_INFO("NRF_ERROR_INTERNAL");
      }
      else if(err_code==NRF_ERROR_INVALID_ADDR)
      {
       NRF_LOG_INFO("NRF_ERROR_INVALID_ADDR");
      } 
      else if(err_code==NRF_ERROR_BUSY)
      {
       NRF_LOG_INFO("NRF_ERROR_BUSY");
      }
      else if(err_code==NRF_ERROR_FORBIDDEN)
      {
       NRF_LOG_INFO("NRF_ERROR_FORBIDDEN");
      }
      else if(err_code==NRF_SUCCESS)
      {
       NRF_LOG_INFO("NRF_SUCCESS");
      }
    
        return err_code;
    }
    

  • Edvin said:
    check the function description in the .h file

     that snippet is not from the .h file. That is from the .c file. Check the file nrf_fstorage.h

  • Hi,
    I have checked in .h file.

    ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
                                  uint32_t               dest,
                                  void           const * p_src,
                                  uint32_t               len,
                                  void                 * p_param);
    
    
    /**@brief   Function for erasing flash pages.
     *
     * @details This function erases @p len pages starting from the page at address @p page_addr.
     *          The erase operation must be initiated on a page boundary.
     *
     * @param[in]   p_fs        The fstorage instance.
     * @param[in]   page_addr   Address of the page to erase.
     * @param[in]   len         Number of pages to erase.
     * @param[in]   p_param     User-defined parameter passed to the event handler (may be NULL).
     *
     * @retval  NRF_SUCCESS                 If the operation was accepted.
     * @retval  NRF_ERROR_NULL              If @p p_fs is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p page_addr is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     * @retval  NRF_ERROR_NO_MEM            If no memory is available to accept the operation.
     *                                      When using the @ref nrf_fstorage_sd, this error
     *                                      indicates that the internal queue of operations is full.
     */
    

    I am sending hard code value but still getting same issue.

        
        char      SNV_Data[]   ="Hello";
        
        NRF_LOG_INFO("Writing \"%s\" to flash.", SNV_Data);
        rc = nrf_fstorage_write(&fstorage, 0x3f000, SNV_Data, 5, NULL);
        APP_ERROR_CHECK(rc);
    
     

  • /**@brief   Function for erasing flash pages.
     *
     * @details This function erases @p len pages starting from the page at address @p page_addr.
     *          The erase operation must be initiated on a page boundary.
     *
     * @param[in]   p_fs        The fstorage instance.
     * @param[in]   page_addr   Address of the page to erase.
     * @param[in]   len         Number of pages to erase.
     * @param[in]   p_param     User-defined parameter passed to the event handler (may be NULL).
     *
     * @retval  NRF_SUCCESS                 If the operation was accepted.
     * @retval  NRF_ERROR_NULL              If @p p_fs is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p page_addr is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     * @retval  NRF_ERROR_NO_MEM            If no memory is available to accept the operation.
     *                                      When using the @ref nrf_fstorage_sd, this error
     *                                      indicates that the internal queue of operations is full.
     */

    That part is not the description for nrf_fstorage_write(). It is the description for the function below (nrf_fstorage_erase()).

    The description of nrf_fstorage_write() is above the line:

    ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
                                  uint32_t               dest,
                                  void           const * p_src,
                                  uint32_t               len,
                                  void                 * p_param);

  • Oh sorry, my bad.
    Any suggestions for the issue?

  • Hi
    It's STRANGE. I have changed the initializing value and its work.

    char      SNV_Data[]   ="Muqarrab112";
    char Test_SNV_Data[]   ="Muqarrab112";
    


Reply Children
  • did you find the reason? I am trying to make you understand what the return value means. Did you check the description above nrf_fstorage_write() in the .h file?

    It works now, but you may encounter it later, and come back to us, either with the same issue, or a similar one. I am trying to explain how to debug these kind of return values. 

    So let me help you. The description of nrf_fstorage_write() says:

    /**@brief   Function for writing data to flash.
     *
     * Write @p len bytes from @p p_src to @p dest.
     *
     * When using @ref nrf_fstorage_sd, the data is written by several calls to @ref sd_flash_write if
     * the length of the data exceeds @ref NRF_FSTORAGE_SD_MAX_WRITE_SIZE bytes.
     * Only one event is sent upon completion.
     *
     * @note The data to be written to flash must be kept in memory until the operation has
     *       terminated and an event is received.
     *
     * @param[in]   p_fs        The fstorage instance.
     * @param[in]   dest        Address in flash memory where to write the data.
     * @param[in]   p_src       Data to be written.
     * @param[in]   len         Length of the data (in bytes).
     * @param[in]   p_param     User-defined parameter passed to the event handler (may be NULL).
     *
     * @retval  NRF_SUCCESS                 If the operation was accepted.
     * @retval  NRF_ERROR_NULL              If @p p_fs or @p p_src is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero or not a multiple of the program unit,
     *                                      or if it is otherwise invalid.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p dest is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     * @retval  NRF_ERROR_NO_MEM            If no memory is available to accept the operation.
     *                                      When using the @ref nrf_fstorage_sd, this error
     *                                      indicates that the internal queue of operations is full.
     */
    ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
                                  uint32_t               dest,
                                  void           const * p_src,
                                  uint32_t               len,
                                  void                 * p_param);

    What does it say about NRF_ERROR_INVALID_LENGTH? It explains two scenarios, and a hint is that the issue was not that the length was 0, because len was 5. So it is related to the length, right?

  • Hi .

    I think flash memory is very sensitive. Nerd
    Now I am adding the Flash memory part to my main project.
    So here are some new points I want to discuss.

    1-I have made these functions to read/write. As per your instruction.

    char      SNV_Data[]   ="Muqarrab112";
    char Test_SNV_Data[]   ="11223344556";
    
    
    /////////////////////////////////////////////////////////////////////////////// SNV
    
    void write_SNV()
    {
        ret_code_t rc;
        //SNV_Data[0]=0xEE;
    
    
    
        sd_flash_page_erase(0xf4);
    
        NRF_LOG_INFO("Writing \"%s\" to flash.", SNV_Data);
        rc = nrf_fstorage_write(&fstorage, 0xf4000, SNV_Data, sizeof(SNV_Data), NULL);
        APP_ERROR_CHECK(rc);
    
        wait_for_flash_ready(&fstorage);
        NRF_LOG_INFO("Writing Done");
    
    }
    
    uint32_t read_SNV()
    {
        ret_code_t rc;
    
        rc = nrf_fstorage_read(&fstorage, 0xf4000, Test_SNV_Data, sizeof(Test_SNV_Data));
        APP_ERROR_CHECK(rc);
    
    
        NRF_LOG_INFO("Reading from flash hex:");
        for(uint8_t i=0; i<sizeof(Test_SNV_Data); i++)
        {
            NRF_LOG_RAW_INFO("%02x:", Test_SNV_Data[i]);
        //    NRF_LOG_INFO("Reading from flash char Hex %h :",Test_SNV_Data[i] );
        }
    
        NRF_LOG_RAW_INFO("\r\n");
        NRF_LOG_INFO("Reading from flash char:");
        for(uint8_t i=0; i<sizeof(Test_SNV_Data); i++)
        {
            NRF_LOG_RAW_INFO("%c", Test_SNV_Data[i]);
        }
        NRF_LOG_RAW_INFO("\r\n");
    
        NRF_LOG_INFO("Reading Done");
    }
    /////////////////////////////////////////////////////////////////////////////// SNV
    

    Why I am getting this warning?


    2-I am calling these two functions in main and they are working fine.

    BUT when I am calling after connection they are not responding anything? NO RESPONSE from this function(When I write on characteristic 9 I call this function) even not print anything.
    As I comment  write_SNV(); read_SNV(); these functions print statment start wotking.
    What is the problem? Does any suggestion please?

    void Charcteristics_9(uint8_t test)
    {
        NRF_LOG_INFO("Memory Function");
    
        SNV_Data[0]=0xEE;
        write_SNV();
        read_SNV();
        ble_cus_custom_value_update(p_cus,5,9);
    
    }
    

    3-

    The secure_bootloader\pca10056_s140_ble bootloader has a flash start address of 0xf8000. So if you use this one, then it means that the FDS pages are on 0xF7000, 0xF6000 and 0xF5000. You can use 0xF4000->0xF4FFF. 

    I have set the following address to store values.

    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
    {
        /* Set a handler for fstorage events. */
        .evt_handler = fstorage_evt_handler,
    
        /* These below are the boundaries of the flash space assigned to this instance of fstorage.
         * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
         * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
         * last page of flash available to write data. */
        .start_addr = 0xf4000,
        .end_addr   = 0xf4fff,
    };
    



    Any suggestion,s please?

  • Did you find the reason for your previous issue? that the write function returned invalid length?

     

    Muqarrab said:
    Why I am getting this warning?

     

    Do you have several (and probably different) implementations of wait_for_flash_ready()?

    When you compile it should say something like "your previous definition was here", which points to another place.

    NO RESPONSE from what function?

     

    Muqarrab said:
    As I comment  write_SNV(); read_SNV(); these functions print statment start wotking.
    What is the problem? Does any suggestion please?

     I guess your wait_for_flash_ready() doesn't return, which suggests that you don't get the event. Is that correct? From where do you call Charcteristics_9()? Inside an interrupt, by any chance? Try to call it from your main() function. Does it get executed then?

  • Did you find the reason for your previous issue? that the write function returned invalid length?

    I have changed the data length (set ~12) and it's working now.

    Do you have several (and probably different) implementations of wait_for_flash_ready()?

    When you compile it should say something like "your previous definition was here", which points to another place.

    NO, I have only one implementation in main.c.

    void fstorage_init_f(void)
    {
        ret_code_t rc;
    
        nrf_fstorage_api_t * p_fs_api;
        p_fs_api = &nrf_fstorage_sd;
    
        rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
        APP_ERROR_CHECK(rc);
    }
    

    I guess your wait_for_flash_ready() doesn't return, which suggests that you don't get the event. Is that correct? From where do you call Charcteristics_9()? Inside an interrupt, by any chance? Try to call it from your main() function. Does it get executed then?

    I have called the function in main and its working. But when I write on characteristics and called the same function it does not work. Does any suggestion please?

  • Hi

    Edvin is on leave for the time being, so I have been assigned to this case while he is away.

    Regarding your issue with the Characteristics_9(). When debugging, do you see any kind of error code in either the write_SNV() or read_SNV() functions? Does the application work as intended if just one of these functions are included? What I think is going on is that you try calling wither write or read _SNV before the flash is ready. You need to make sure that the reading/writing is completed and the flash is ready for a new operation first.

    Best regards,

    Simon

Related