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

Problem with fds: Flash read, write, delete calling that function using android phone.

Hello to all,

I am using nRF52832 DK with sd132, v6.0.0 and sdk 15.0.0, segger embedded studio. We want to achieve change application timer time (APP_TIMER_TICKS(update_time)) using android phone. We have a sensor devices it will wake up as per app timer time defined, we want to change this wake up time using Noridc UART tool box app. For that we are using fds example as referred in given sdk 15.0 and other nRF5-flash-storage-examples .

We are able to flash write read and delete but problem is:

  1.  When i call fds_test_find_and_delete(), fds_test_write(), fds_read() whenever received command from nordic UART app it not able to read and write at this time.
  2. I want to change update_time variable of app timer ticks using android phone and store this time in flash. Whenever want to user need to change this time first delete previous and update latest send time. 
  3. Will you please provide me program snippet for How i call flash fds API through android phone and store received time in that app_timer ticks. Confused regarding this.

I am currently using this following functions for FDS read, write, and delete:

static ret_code_t fds_test_write(void)
{
		
    //static uint32_t const m_deadbeef[2] = {0xDEADBEEF,0xBAADF00D};
    static uint8_t const m_deadbeef[1] = {0x14};
//    memcpy(m_deadbeef, write_data, sizeof(m_deadbeef));
    fds_record_t        record;
    fds_record_desc_t   record_desc;

    // Set up data.
    
    // Set up record.
    record.file_id        = FILE_ID_FDS_TEST;
    record.key            = REC_KEY_FDS_TEST;
    record.data.p_data    = &m_deadbeef;
    //record.data.length_words   = sizeof(m_deadbeef)/sizeof(uint32_t);
    record.data.length_words   = sizeof(m_deadbeef)/sizeof(uint8_t);
                    
    ret_code_t ret = fds_record_write(&record_desc, &record);
    if (ret != FDS_SUCCESS)
    {
                    return ret;
    }
     NRF_LOG_INFO("Writing Record ID = %d \r\n",record_desc.record_id);
    return NRF_SUCCESS;
}

static ret_code_t fds_read(void)
{

    fds_flash_record_t  flash_record;
    fds_record_desc_t   record_desc;
    fds_find_token_t    ftok ={0};//Important, make sure you zero init the ftok token
    //uint32_t *data;
    uint8_t *data;
    uint32_t err_code;
    
    NRF_LOG_INFO("Start searching... \r\n");
    // Loop until all records with the given key and file ID have been found.
    while (fds_record_find(FILE_ID_FDS_TEST, REC_KEY_FDS_TEST, &record_desc, &ftok) == FDS_SUCCESS)
    {
                    err_code = fds_record_open(&record_desc, &flash_record);
                    if ( err_code != FDS_SUCCESS)
                    {
                            return err_code;		
                    }
                    
                    NRF_LOG_INFO("Found Record ID = %d\r\n",record_desc.record_id);
                    NRF_LOG_INFO("Data = ");
                    //data = (uint32_t *) flash_record.p_data;
                    data = (uint8_t *) flash_record.p_data;
                    for (uint8_t i=0;i<flash_record.p_header->length_words;i++)
                    {
                            NRF_LOG_INFO("0x%8x ",data[i]);
                    }
                    NRF_LOG_INFO("\r\n");
                    // Access the record through the flash_record structure.
                    // Close the record when done.
                    err_code = fds_record_close(&record_desc);
                    if (err_code != FDS_SUCCESS)
                    {
                            return err_code;	
                    }
    }
    return NRF_SUCCESS;
		
}


static ret_code_t fds_test_find_and_delete (void)
{
    fds_record_desc_t   record_desc;
    fds_find_token_t    ftok;

    ftok.page=0;
    ftok.p_addr=NULL;
    // Loop and find records with same ID and rec key and mark them as deleted. 
    while (fds_record_find(FILE_ID_FDS_TEST, REC_KEY_FDS_TEST, &record_desc, &ftok) == FDS_SUCCESS)
    {
        fds_record_delete(&record_desc);
        NRF_LOG_INFO("Deleted record ID: %d \r\n",record_desc.record_id);
    }
    // call the garbage collector to empty them, don't need to do this all the time, this is just for demonstration
    ret_code_t ret = fds_gc();
    if (ret != FDS_SUCCESS)
    {
        return ret;
    }
    return NRF_SUCCESS;
}

Parents
  • You cannot call the fds API through an android phone!

    What you will need to do is to devise some sort of command that your app will send to instruct your nRF code to update the parameters, and store in Flash

    please provide me program snippet for How i call flash fds

    That is exactly what the example project does - but it does it for an interactive human user at a terminal.

    So you just need to get rid of the interactive CLI stuff, and implement a command over the BLE link ...

  • Thanks for fast response,

    So you just need to get rid of the interactive CLI stuff, and implement a command over the BLE link ...

    But as you said above how i can implement CLI stuff over BLE link will you please provide me tutorial or example.

    If i call flash write function like this is it have any restriction:

    When Nordic UART tool box connected to device then we send 3 commnd-->

    static void nus_data_handler(ble_nus_evt_t * p_evt)
    {
    
    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {
    uint32_t err_code;
    NRF_LOG_INFO("nus_data_handler call");
    // send_to_central();
    NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
    NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
    
    for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
    {
    do
    {
    err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
    if(p_evt->params.rx_data.p_data[i] == '3')
    {
    NRF_LOG_INFO("Start flashing....");
    err_code = fds_test_find_and_delete();
    APP_ERROR_CHECK(err_code);
    nrf_delay_ms(1000);
    fds_test_write();
    nrf_delay_ms(1000);
    // fds_read();
    break;
    }

    Thanks,

  • Ok, 
    Which is best and simple flash library for achieving to change update_time variable value of app timer ticks using android phone and store this time in flash.

    Will use FDS or f_storage this would be easy and simplest code. we do not want to store more data in flash only need to store user required time value. For e.g. 10min, 15min, 1hr, 12hr, 24 hr etc.

    Thanks....!!! 

  • The android phone is irrelevant.

    FDS gives you the advantage of wear levelling, and the ability to update information already in flash.

    f_storage is much more basic - you would have to manage the wear levelling yourself, and work out your own scheme for doing updates.

    Neither of them has anything to do with the communications to the Central.

  • is correct. The FDS is the easiest to use, as it will manage the flash wear leveling.

    You need to set up a ble link, like the ble_app_uart example. Then, when you receive a message, instead of forwarding it to the UART, you do the flash operations that you want to do instead. 

    The protocol that you use, you must implement  yourself, and use in the application.

     

    Best regards,

    Edvin

  • Thanks Edvin,

    I have used FDS library and able to flash write and delete data when message received from ble_app_uart.

    But problem getting for read function: I am write this data  const m_deadbeef = 0xDEADBEEF;

    When i call read function after write event generated got this data in read function: "0x      EF"

    Why not getting all write hex data?

    Also will you please tell me how i can write integer value instead of this hex data? 

    Thanks in advanced,....!!!

  • Hello,

     

    The issue is that you cast the flash_record.p_data to a uint8_t, while it is really a uint32_t pointer.

    Try the fds_read function looking something like this:

    void fds_test_read(void)
    {
        ret_code_t err_code = FDS_SUCCESS;
        fds_flash_record_t  flash_record;
        fds_record_desc_t   record_desc;
        fds_find_token_t    ftok;
        memset(&ftok, 0x00, sizeof(fds_find_token_t));
        
        while (fds_record_find(FILE_ID, RECORD_KEY_1, &record_desc, &ftok) == FDS_SUCCESS)
        {
            err_code = fds_record_open(&record_desc, &flash_record);
            if (err_code != FDS_SUCCESS)
            {
                // Handle error
                printf("fds_record_open error %d\r\n", err_code);
            }
            // Access the record through the flash_record structure
            // Close the record when done.
            err_code = fds_record_close(&record_desc);
            if(err_code != FDS_SUCCESS)
            {
                // Handle error
                printf("fds_record_close err_code %d\r\n", err_code);
            }
            uint32_t *data = (uint32_t *) (flash_record.p_data);
            printf("record found:\r\n");
            printf("%08x\r\n", *data);
            
        }
    }

    Of course, use the NRF_LOG_INFO instead of printf. I just started implementing this to the SDK15\examples\peripheral\uart example, so printf was already set up.

     

    You can write int values instead of hex values. Just create an int variable when you write, which you pass the pointer to into the fds_write function:

    record.data.p_data = &m_my_variable;

    The same goes when you read out the variable. Remember that all you read is a register in flash. If I stored an int (int32_t) instead hexadecimal, I would write something like this:

     

    int32_t *data = (int32_t *)(flash_record.data);

    NRF_LOG_INFO("%d", *data);

    And the data will be printed as a number instead of hexadecimal values.

     

    Best regards,

    Edvin

Reply
  • Hello,

     

    The issue is that you cast the flash_record.p_data to a uint8_t, while it is really a uint32_t pointer.

    Try the fds_read function looking something like this:

    void fds_test_read(void)
    {
        ret_code_t err_code = FDS_SUCCESS;
        fds_flash_record_t  flash_record;
        fds_record_desc_t   record_desc;
        fds_find_token_t    ftok;
        memset(&ftok, 0x00, sizeof(fds_find_token_t));
        
        while (fds_record_find(FILE_ID, RECORD_KEY_1, &record_desc, &ftok) == FDS_SUCCESS)
        {
            err_code = fds_record_open(&record_desc, &flash_record);
            if (err_code != FDS_SUCCESS)
            {
                // Handle error
                printf("fds_record_open error %d\r\n", err_code);
            }
            // Access the record through the flash_record structure
            // Close the record when done.
            err_code = fds_record_close(&record_desc);
            if(err_code != FDS_SUCCESS)
            {
                // Handle error
                printf("fds_record_close err_code %d\r\n", err_code);
            }
            uint32_t *data = (uint32_t *) (flash_record.p_data);
            printf("record found:\r\n");
            printf("%08x\r\n", *data);
            
        }
    }

    Of course, use the NRF_LOG_INFO instead of printf. I just started implementing this to the SDK15\examples\peripheral\uart example, so printf was already set up.

     

    You can write int values instead of hex values. Just create an int variable when you write, which you pass the pointer to into the fds_write function:

    record.data.p_data = &m_my_variable;

    The same goes when you read out the variable. Remember that all you read is a register in flash. If I stored an int (int32_t) instead hexadecimal, I would write something like this:

     

    int32_t *data = (int32_t *)(flash_record.data);

    NRF_LOG_INFO("%d", *data);

    And the data will be printed as a number instead of hexadecimal values.

     

    Best regards,

    Edvin

Children
Related