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

FDS storing random value when called in ble_evt_handler

Whenever I store my data in Flash using FDS (Flash Data Storage Library) it stores a random value (but fixed) even though I am giving it a value.

I run the same thing in main as follows and it writes the correct value:

    //----Writing----
    uint32_t data_test = 0x000010EE;
    fds_record_t        record;
    fds_record_desc_t   record_desc;

    record.file_id              = FILE_ID;
    record.key                  = TEST_KEY;
    record.data.p_data          = &data_test;
    record.data.length_words    = 1;

    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};

    uint32_t *data;
    
    rc = fds_record_find(FILE_ID, TEST_KEY, &desc, &tok);

    if (rc == FDS_SUCCESS)
    {

        rc = fds_record_update(&desc, &record);
        APP_ERROR_CHECK(rc); 
        NRF_LOG_INFO("Updated in Main ");   
    }

    else
    {
        ret_code_t ret = fds_record_write(&record_desc, &record);
        APP_ERROR_CHECK(ret);
        NRF_LOG_INFO("Written in main");

      }
    

    //-----Reading------
    fds_record_desc_t desc_1 = {0};
    fds_find_token_t  tok_1  = {0};

    rc = fds_record_find(FILE_ID, TEST_KEY, &desc_1, &tok_1);

    if (rc == FDS_SUCCESS)
    {

        fds_flash_record_t config = {0};

            /* Open the record and read its contents. */
        rc = fds_record_open(&desc_1, &config);
        APP_ERROR_CHECK(rc);


        data = (uint32_t *) config.p_data;
        for (uint8_t i=0;i<config.p_header->length_words;i++)
        {
                NRF_LOG_INFO("0x%8x ",data[i]);
        }

        rc = fds_record_close(&desc_1);
        APP_ERROR_CHECK(rc);

    }

But when I do it in ble_evt_handler, it does not store the value I intend but some other value. Code inside ble_evt_handler:

uint32_t major_flash = 0x00000033;//(p_data[0] & (p_data[1] << 8));;
                uint32_t minor_flash = 0x00000033;//(p_data[2] & (p_data[3] << 8));

                fds_record_t        record;
                fds_record_desc_t   record_desc;
                fds_record_t        record_1;
                fds_record_desc_t   record_desc_1;

                record.file_id              = FILE_ID;
                record.key                  = TEST_KEY;
                record.data.p_data          = &minor_flash;//&data_test_1;//0x00000070; //(p_data[0] & (p_data[1] << 8));
                record.data.length_words    = 1;

                fds_record_desc_t desc = {0};
                fds_find_token_t  tok  = {0};
                fds_record_desc_t desc_1 = {0};
                fds_find_token_t  tok_1  = {0};

                ret_code_t ret;
                ret_code_t rc = fds_record_find(FILE_ID, TEST_KEY, &desc, &tok);

                if (rc == FDS_SUCCESS)
                {   
                    NRF_LOG_INFO("Similar Record was found thus it is being updated");
                    rc = fds_record_update(&desc, &record);
                    APP_ERROR_CHECK(rc);

                }

                else
                {
                    ret_code_t ret = fds_record_write(&record_desc, &record);
                    APP_ERROR_CHECK(ret);
                    NRF_LOG_INFO("First time writing Major record");

                }

Any leads as to why its storing a garbage value when called in the event handler (its being called in the event handler as when data is written it stores it in the flash aswell)

  • Hi,

    The record data must be kept in RAM until the flash operation is complete, but it looks like you are using stack variables to hold the data. Do you see the same if you make minor_flash static?

    static uint32_t minor_flash = 0x00000033;//(p_data[2] & (p_data[3] << 8));

  • Converting them to:

    static uint32_t minor_flash = 0x00000033;


    Fixed the problem and its writing correctly inside flash. But how do save p_data (below definition) inside flash
    uint8_t * p_data = p_ble_evt->evt.gatts_evt.params.write.data;
    
    ......
    fds_record_t    record;
    
    record.data.p_data  = &p_data; //I guess this is not correct, as in the type handling


    Okay so I have also tried another approach to it, rather then saving in the ble_evt_handler function call, I raised a flag in the main (which allowed me to save a self declared variable in the flash without issues) but I am unable to fetch the variables that I declared global from the ble_evt_handler function so they could be used in the main flash function call. When I come to the main to write them, the value is just converted into a random number as opposed to what it was in the ble_evt_handler.

    uint8_t * p_data_evt; //Global
    
    ......
    uint8_t * p_data = p_ble_evt->evt.gatts_evt.params.write.data;  //Inside Function
    p_data_evt = p_data;    //Inside Function


    But the p_data_evt when comes into the main flash saving it has its value changed.

  • The event data must be copied to static memory. Use memcpy() if the data len is more than one byte.

    E.g.,

    __ALIGN(4) static uint8_t m_data[MAX_DATA_LEN]; //Global. __ALIGN(4) used to ensure word alignment
    
    ......
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;  //Inside Function
    memcpy(m_data, p_evt_write->data, p_evt_write->len);    //Inside Function. 
    
    ...
    record.data.p_data = &m_data

  • Thanks to Vidar Berg on the hint of the static, I got it working.

    Since static type was working with the flash, I saved the p_data into a global static variable and then saved it:

    //Global
    static uint32_t major_flash = 0; 
    static uint32_t minor_flash = 0;
    
    ......
    
    
    //Inside ble_evt_handler
    major_flash = ( (p_data[1]) | (p_data[0] <<8) );
    minor_flash = ( p_data[3] | (p_data[2] <<8)); 
    
    .....
    
    record.data.p_data          = &major_flash;
    
    .....
    
    record.data.p_data          = &minor_flash;

Related