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

Fds Read Operation is not working correctly

HI,

I am building my application on one of the nordic ble_app in SDK 15.3.. currently, I am facing a  strange issue. I am using fds to store some data on the flash. my write operation is successful and data is written. my read operation is always faulty. it points somewhere else. Although the found record ID is correct the data and pointer to memory both are wrong. I have used the example code. I have also checked the GitHub example but I am stuck here. I have attached the scree nshot of the log messages.

The data I am writing is deadbeef

kidly help I am stuck here for two days.

thanks.

void read_record(fds_record_t* record, uint16_t file_id, uint16_t key)
{
    ret_code_t rc;
    fds_record_desc_t desc;
    fds_find_token_t  tok;
    fds_flash_record_t flash_record;
    record->file_id = file_id;
    record->key = key;

    memset(&tok, 0x00, sizeof(fds_find_token_t));
    //fds_find_record_
    rc = fds_record_find(file_id, key, &desc, &tok);
    if(rc==NRF_SUCCESS)
    {
        /* A file is in flash. Let's update it. */
        
        
        /* Open the record and read its contents. */
        rc = fds_record_open(&desc, &flash_record);
        APP_ERROR_CHECK(rc);

        /* Copy the configuration from flash into record. */
        NRF_LOG_INFO("Found Record ID = %d\r\n",desc.record_id);
        //memcpy((uint8_t*)record->data.p_data, (uint8_t*)config.p_data, record->data.length_words * 4);
        // record->data.p_data = config.p_data;
        uint32_t* data = (uint32_t *)flash_record.p_data;
        record->data.p_data = data;
        record->data.length_words = flash_record.p_header->length_words;
        for (uint8_t i=0;i<flash_record.p_header->length_words;i++)
	{
          NRF_LOG_INFO("0x%8x",data[i]);
	}
        NRF_LOG_INFO("Record file found..\n");
        NRF_LOG_INFO("Record file location 0x%x\n", data);
        NRF_LOG_INFO("Record file length %d\n", flash_record.p_header->length_words);
        /* Close the record when done reading. */
        rc = fds_record_close(&desc);
        APP_ERROR_CHECK(rc);

    }
}


void write_record(fds_record_t* record)
{
    ret_code_t rc;
    m_fds_write = false;
    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};

    rc = fds_record_find(record->file_id, record->key, &desc, &tok);

    if (rc == NRF_SUCCESS)
    {
        /* A file is in flash. Let's update it. */

        /* Write the updated record to flash. */
        rc = fds_record_update(&desc, record);
        if ((rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH))
        {
            NRF_LOG_INFO("No space in flash, delete some records to update the config file.\n");
        }
        else
        {
            APP_ERROR_CHECK(rc);
        }
    }
    else
    {
        /* System config not found; write a new one. */
        NRF_LOG_INFO("Writing config file...\n");

        rc = fds_record_write(&desc, record);
        if ((rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH))
        {
            NRF_LOG_INFO("No space in flash, delete some records to update the config file.\n");
        }
        else
        {
            APP_ERROR_CHECK(rc);
        }
    }
    while(m_fds_write == false);
}

Parents
  • Hi,

    The "record file location" of 0x7E030 sounds reasonable, but the length of 4 (length in words, not bytes) does not match data of 0xDEADBEEF. Or did you write the data "deadbeef", which should be 9 bytes (eight characters plus null termination.) Can you share main.c, so we can see how your read and write functions are used?

    A flash dump would reveal contents of FDS flash pages. You can do a flash dump e.g. by using the command "nrfjprog --readcode --readuicr dump.hex" to dump flash and UICR contents to a file named dump.hex. If you attach that file I can have a look at what the real contents stored in FDS is.

    Regards,
    Terje

Reply
  • Hi,

    The "record file location" of 0x7E030 sounds reasonable, but the length of 4 (length in words, not bytes) does not match data of 0xDEADBEEF. Or did you write the data "deadbeef", which should be 9 bytes (eight characters plus null termination.) Can you share main.c, so we can see how your read and write functions are used?

    A flash dump would reveal contents of FDS flash pages. You can do a flash dump e.g. by using the command "nrfjprog --readcode --readuicr dump.hex" to dump flash and UICR contents to a file named dump.hex. If you attach that file I can have a look at what the real contents stored in FDS is.

    Regards,
    Terje

Children
  • I have found one error and that was I was pointing to the pointer address while writing. once I did that. I would be able to read and write 1 word. I tried to write three words "hello world" and it says no flash memory while writing. I change the length to 1 word and even then it says no flash memory. I erase the whole memory reprogram and again it says the same thing. right now here is the situation and here is the code.

    int main(void)
    {
        
        bool erase_bonds;
    
        // Initialize.
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
        ble_fds_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        peer_manager_init();
        
        //delete_all_records();
        //nrf_delay_ms(5000); 
        
        create_new_record(&dummy_record, 0x0001, 0x1111, (uint32_t *)(m_hello_world), 3);
        write_record(&dummy_record);
        
        nrf_delay_ms(5000);
        
        read_record(&reading_record, 0x0001, 0x1111);
        NRF_LOG_HEXDUMP_INFO(reading_record.data.p_data, reading_record.data.length_words * 4);
    }
    
    
    void create_new_record(fds_record_t* new_record,uint16_t file_id, uint16_t key, uint32_t* p_data, uint32_t length_words)
    {
        new_record->file_id           = file_id,
        new_record->key               = key,
        new_record->data.p_data       = (uint32_t*)p_data,
        /* The length of a record is always expressed in 4-byte units (words). */
        new_record->data.length_words = length_words;
    }
    
    
    void ble_fds_init()
    {
        ret_code_t rc;
        /* Register first to receive an event when initialization is complete. */
        (void) fds_register(fds_evt_handler);
    
        NRF_LOG_INFO("Initializing fds...\n");
    
        rc = fds_init();
        APP_ERROR_CHECK(rc);
    }
    
    void write_record(fds_record_t* record)
    {
        ret_code_t rc;
        m_fds_write = false;
        fds_record_desc_t desc = {0};
        fds_find_token_t  tok  = {0};
    
        rc = fds_record_find(record->file_id, record->key, &desc, &tok);
    
        if (rc == NRF_SUCCESS)
        {
            /* A file is in flash. Let's update it. */
    
            /* Write the updated record to flash. */
            rc = fds_record_update(&desc, record);
            if ((rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH))
            {
                NRF_LOG_INFO("No space in flash, delete some records to update the config file.\n");
            }
            else
            {
                APP_ERROR_CHECK(rc);
            }
        }
        else
        {
            /* System config not found; write a new one. */
            NRF_LOG_INFO("Writing config file...\n");
    
            rc = fds_record_write(&desc, record);
            if ((rc != NRF_SUCCESS) && (rc == FDS_ERR_NO_SPACE_IN_FLASH))
            {
                NRF_LOG_INFO("No space in flash, delete some records to update the config file.\n");
            }
            else
            {
                NRF_LOG_INFO("fds_record_write returned = %d\r\n",rc);
                APP_ERROR_CHECK(rc);
                NRF_LOG_INFO("Data has been written.\n");
            }
        }
        while(m_fds_write == false);
    }
    
    void read_record(fds_record_t* record, uint16_t file_id, uint16_t key)
    {
        ret_code_t rc;
        fds_record_desc_t desc = {0};
        fds_find_token_t  tok = {0};
        fds_flash_record_t flash_record;
        record->file_id = file_id;
        record->key = key;
    
        //memset(&tok, 0x00, sizeof(fds_find_token_t));
        //fds_find_record_
        rc = fds_record_find_by_key(key, &desc, &tok);
        NRF_LOG_INFO("fds_record_find returned = %d\r\n",rc);
        if(rc==NRF_SUCCESS)
        {
            /* A file is in flash. Let's update it. */
            
            
            /* Open the record and read its contents. */
            rc = fds_record_open(&desc, &flash_record);
            APP_ERROR_CHECK(rc);
    
            /* Copy the configuration from flash into record. */
            NRF_LOG_INFO("Found Record ID = %d\r\n",desc.record_id);
            //memcpy((uint8_t*)record->data.p_data, (uint8_t*)config.p_data, record->data.length_words * 4);
            // record->data.p_data = config.p_data;
            uint32_t* data = (uint32_t *)flash_record.p_data;
            record->data.p_data = data;
            record->data.length_words = flash_record.p_header->length_words;
            for (uint8_t i=0;i<flash_record.p_header->length_words;i++)
    	{
              NRF_LOG_INFO("0x%8x",data[i]);
    	}
            NRF_LOG_INFO("Record file found..\n");
            NRF_LOG_INFO("Record file location 0x%x\n", data);
            NRF_LOG_INFO("Record file length %d\n", flash_record.p_header->length_words);
            /* Close the record when done reading. */
            rc = fds_record_close(&desc);
            APP_ERROR_CHECK(rc);
    
        }
    }
    
    

  • Hi,

    As seen in your screenshot, fds_record_write returned error number 34306. If you convert that to hexadecimal it is 0x8602. 0x8600 is the base number for FDS errors, that is, FDS errors start at 0x8600 and goes upwards. Looking at the FDS return values, the first error is 0x8600, the next one 0x8601, and so on. 0x8602 is FDS_ERR_UNALIGNED_ADDR. According to the fds_record_write() documentation, this error means that the data you are trying to write is not aligned to a 4 byte boundary.

    What this error means, is that p_record was not pointing to a memory address at the beginning of a word. "Word" in this context means group of four bytes. In other words, the address for &dummy_record is not divisible by four. Can you share the rest of the main.c file as well, not only the functions? How/where is dummy_record defined?

    Regards,
    Terje

  • I was using C++ and using alignas(4) infront of variable decleration solved my problem.

Related