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

FDS module not working for me

Hi,

        I am developing against a custom board built around the NRF52840. I am trying to store and retrieve values from flash using the fds module. I am not seeing any errors either in the function calls or in the fds event handler. The only thing I seem to be able to do is to iterate over all records and to delete them. I have the following test code extracted from my code base:

/** @enum record_handles
*** @brief list of handles for flash stored records
*/
enum record_handles {
   CONF_BEGIN = 0x100,      ///< valid ids start at 0x0001 so the next item will be valid
   CONF_MOVEMENT_THRES,      ///< movement threshold handle @see sample.c
   CONF_TIME_THRES,          ///< movement time threshold @see sample.c
   CONF_IDLE_TIMEOUT,        ///< activity timeout @see standby.c   
   CONF_BAR_THRES,           ///< average value when off bar
   CONF_BAR_RANGE,           ///< variation for off bar value
   CONF_BAR_ENABLED,         ///< switch on and off bar
   CONF_SAMPLE_MODE,         ///< 1, 3 or 5 tof sensors in use
   CONF_SENSOR_ID,           ///< handle for the sensor id
   CONF_LAST,                ///< max for last is 0xC000, peer manager uses this and above
};

/** @enum default values for records
*** @brief constants or default values used in configuration
*/
enum record_defaults {
   CONF_BEGIN_DEF = 0x0,
   CONF_MOVEMENT_THRES_DEF = 30,          ///< (mm) movement threshold @see sample.c
   CONF_TIME_THRES_DEF = 10,              ///< (sec) movement time threshold @see sample.c
   CONF_IDLE_TIMEOUT_DEF = 600,           ///< (sec) activity timeout @see standby.c   
   CONF_BAR_THRES_DEF = 260,              ///< average value when off bar- off bar: 252-268
   CONF_BAR_RANGE_DEF = 12,               ///< variation for off bar value
   CONF_BAR_ENABLED_DEF = true,           ///< switch on and off bar
   CONF_SAMPLE_MODE_DEF = 1,              ///< 1, 3 or 5 tof sensors in use
   CONF_SENSOR_ID_DEF = 0x37313030,       ///< value for the sensor id
};


#define CONF_FILEHANDLE 0xF010            ///< conf file handle - range 0x0000 to 0xbfff

bool conf_is_started2 = false;
bool conf_write_done2 = false;

/** @brief configuration storage event handler
*** @param[in] the fds event structure
*/
void on_FDS_event(fds_evt_t const *p_evt) {
NRF_LOG_INFO("fds event: %d %d\r\n", p_evt->id, (p_evt->result));
    switch (p_evt->id) {
        case FDS_EVT_INIT:
            if (p_evt->result == FDS_SUCCESS) {
                conf_is_started2 = true;
            }
            break;
        case FDS_EVT_WRITE: 
            conf_write_done2 = true;
NRF_LOG_INFO("EVT_WRITE: %d", p_evt->result);
            if (p_evt->result != FDS_SUCCESS) {
               NRF_LOG_INFO("conf evt: failed write 0x%x", p_evt->result);
            }
            break;
        case FDS_EVT_UPDATE:
            if (p_evt->result != FDS_SUCCESS) {
               NRF_LOG_INFO("conf evt: failed update 0x%x", p_evt->result);
            }
            break;
        case FDS_EVT_DEL_RECORD:
            if (p_evt->result != FDS_SUCCESS) {
               NRF_LOG_INFO("conf evt: failed del rec 0x%x", p_evt->result);
            }
            break;
        case FDS_EVT_DEL_FILE:
            if (p_evt->result != FDS_SUCCESS) {
               NRF_LOG_INFO("conf evt: failed del file 0x%x", p_evt->result);
            }
            break;
        case FDS_EVT_GC:
            if (p_evt->result != FDS_SUCCESS) {
               NRF_LOG_INFO("conf evt: failed GC 0x%x", p_evt->result);
            }
            break;
        default:
            break;
    }
}

void conf_2dump(void) {
fds_record_desc_t desc;
fds_find_token_t  tok;
NRF_LOG_INFO("DUMPING...");
    memset(&tok, 0x00, sizeof(fds_find_token_t));
    memset(&desc, 0x00, sizeof(fds_record_desc_t ));
    while(fds_record_iterate(&desc, &tok) != FDS_ERR_NOT_FOUND) {
          NRF_LOG_INFO("Exists record: %d", desc.record_id);
    }
NRF_LOG_INFO("DUMPED.");

}

int main(void) {   
    memset(NRF_SECTION_START_ADDR(rtt), 0, NRF_SECTION_LENGTH(rtt));
    log_init();
fds_record_desc_t desc;
fds_find_token_t  tok;
fds_stat_t stat;
fds_record_t record;
ret_code_t err_code;
const uint32_t record_def_values[9] = {CONF_BEGIN_DEF, 
                                       CONF_MOVEMENT_THRES_DEF, 
                                       CONF_TIME_THRES_DEF,
                                       CONF_IDLE_TIMEOUT_DEF,
                                       CONF_BAR_THRES,
                                       CONF_BAR_RANGE,
                                       CONF_BAR_ENABLED,
                                       CONF_SAMPLE_MODE_DEF,
                                       CONF_SENSOR_ID_DEF};
    // register a handler
    err_code = fds_register(on_FDS_event);
    if (err_code != FDS_SUCCESS) {
       NRF_LOG_INFO("conf init: failed to register event handler0x%x", err_code);
       return err_code;
    }

    // init the fds api
    err_code = fds_init();
    if (err_code != FDS_SUCCESS) {
       NRF_LOG_INFO("conf init: failed to init the api 0x%x", err_code);
       return err_code;
    }
    while (!conf_is_started2)
           ;
    fds_stat(&stat);
    memset(&tok, 0x00, sizeof(fds_find_token_t));
    memset(&desc, 0x00, sizeof(fds_record_desc_t ));
    conf_2dump();
    while(fds_record_iterate(&desc, &tok) != FDS_ERR_NOT_FOUND) {
          NRF_LOG_INFO("Exists record: %d", desc.record_id);
          fds_record_delete(&desc);
          
    }
    conf_2dump();
    for (int i = CONF_BEGIN + 1; i < CONF_LAST; i++) {
        memset(&desc, 0x00, sizeof(fds_record_desc_t ));
        record.file_id = CONF_FILEHANDLE;
        record.key = i;
        record.data.p_data =  &record_def_values[i - CONF_BEGIN];;
        record.data.length_words = 1;  //32bit width words
        conf_write_done2 = false;
        err_code = fds_record_write(&desc, &record);
        while(!conf_write_done2)                     
                ;
    }
    conf_2dump();
}

a typical run produces:

<info> app: fds event: 0 0

<info> app: DUMPING...
<info> app: Exists record: 9
<info> app: Exists record: 10
<info> app: Exists record: 11
<info> app: Exists record: 12
<info> app: Exists record: 13
<info> app: Exists record: 14
<info> app: Exists record: 15
<info> app: Exists record: 16
<info> app: DUMPED.
<info> app: Exists record: 9
<info> app: fds event: 3 0

<info> app: Exists record: 10
<info> app: fds event: 3 0

<info> app: Exists record: 11
<info> app: fds event: 3 0

<info> app: Exists record: 12
<info> app: fds event: 3 0

<info> app: Exists record: 13
<info> app: fds event: 3 0

<info> app: Exists record: 14
<info> app: fds event: 1 0

<info> app: EVT_WRITE: 0
<info> app: fds event: 1 0

<info> app: EVT_WRITE: 0
<info> app: fds event: 1 0

<info> app: EVT_WRITE: 0
<info> app: fds event: 1 0

<info> app: EVT_WRITE: 0
<info> app: DUMPING...
<info> app: Exists record: 17
<info> app: Exists record: 18
<info> app: Exists record: 19
<info> app: Exists record: 20
<info> app: Exists record: 21
<info> app: Exists record: 22
<info> app: Exists record: 23
<info> app: Exists record: 24
<info> app: DUMPED.

I am developing against SDK 15.0 using SES

Many thanks in advance

Paul

Parents
  • Hi,

    I am having a problem extracting the question here? I see form your code and debug output that you write records and find and mark them for deletion (the space is not reclaimed though, as you do not do a garbage collection). This matches what you write. That is probably not very useful, but it seems like the behavior matches the intention.

    If you want to read the data, then you should use fds_record_iterate() or fds_record_find(). If a record was found, then you use fds_record_open() and supply the pointer to fds_record_desc_t. This will provide you with a pointer to the data. Then read it and close it. You can see how this is done by looking at the FDS example. These is the most relevant part of the FDS example in SDK 15.3:

        rc = fds_record_find(CONFIG_FILE, CONFIG_REC_KEY, &desc, &tok);
    
        if (rc == FDS_SUCCESS)
        {
            /* A config file is in flash. Let's update it. */
            fds_flash_record_t config = {0};
    
            /* Open the record and read its contents. */
            rc = fds_record_open(&desc, &config);
            APP_ERROR_CHECK(rc);
    
            /* Copy the configuration from flash into m_dummy_cfg. */
            memcpy(&m_dummy_cfg, config.p_data, sizeof(configuration_t));
    
            NRF_LOG_INFO("Config file found, updating boot count to %d.", m_dummy_cfg.boot_count);
    
            /* Update boot count. */
            m_dummy_cfg.boot_count++;
    
            /* Close the record when done reading. */
            rc = fds_record_close(&desc);
            APP_ERROR_CHECK(rc);
    
            /* Write the updated record to flash. */
            rc = fds_record_update(&desc, &m_dummy_record);
            APP_ERROR_CHECK(rc);
        }

  • Thanks Einar,

                            I have figured it out. My confusion was that record_ids are not the same as record_keys. I was writing records and supplying keys and then expecting to see those keys when actually I was seeing the ids.

    Cheers Paul

Reply Children
No Data
Related