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!

  • /**@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";
    


  • 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?

Related