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

fds issues

Hello,

I'm using a nrf51422_xxac_s110 chip, with the 12.3 SDK. My code is based on the ble_peripheral\ble_app_uart example in the 12.3 SDK.  I'm hoping you can provide some insights, and/or some relevant coding examples to review.


I added two characteristics to the existing uart service, one to change the baud rate of the BLE module, and one to change the device name, as used by the advertising. Each can be set within the same app running on a tablet. (I'm actually using a Nordic app called nRF Connect to test my code). They each have corresponding, independent event handlers, called from the

on_write(ble_nus_t * p_nus, ble_evt_t * p_ble_evt)

function, in ble_nus.c.   I'm having issues with getting the device name change to work as desired.  The sequence of events is as follows: 

When the event handler for the device name change is called, it'll run fds_write to save the value to flash, before exiting.  

After a power cycle, the value saved to flash will be read back, and the string value will be used by gap_params_init(), which will then use it to update the advertising functions. 

The first time I run the program after saving the hex files to flash, (i.e. when a device name change event hasn't happened yet, and fds_write hasn't run) a hardcoded default name is used.

I'm finding that I can change the name once, and have the system behave as expected.  When I try to change the name a second time, using the same sequence of operations, I found the device name as displayed on nRF Connect is not what I wrote, but a garbage value made up of non-standard ASCII characters.   

the main() executes as follows:

//**************************

int main(void)
{
uint32_t err_code;
main_event_handler = uart_event_handle;
APP_SCHED_INIT(5, 5);
timers_init();
timer1_init();
uart_init();
ble_stack_init();

app_fds_init();
services_init();
read_device_name();
gap_params_init();
conn_params_init();
read_baudrate();
advertising_init();


err_code = fds_find_and_delete2();


APP_ERROR_CHECK(err_code);
while(fds_flag==1)
{
       ;
}


err_code = ble_advertising_start(BLE_ADV_MODE_FAST);

APP_ERROR_CHECK(err_code);


// Enter main loop.
for (;;)
{
power_manage();

}
}

//**************************

The read_device_name() function will call the fds_read() function associated with the device name change event.  (Both of the two characteristics I added have their own fds_write and fds_read functions.  The fds_find_and_delete2() function finds and deletes the data associated with the file and record #'s for the device name change data.  This function, along with the fds_write and fds_read functions are mostly the example nordic code.  Within fds_find_and_delete2(), I set a global var called fds_flag, that I don't clear until it returns NRF_SUCCESS.  And then I wait till it's cleared before starting the advertising.  This while() I just added to see if the garbage collector needed to finish before adverstising started.  I didn't make a difference to what I observed.  

ps.  I found that commenting out the call to fds_find_and_delete2, and it's associated code, would result in the device name retaining  the value I first wrote to it, without changing at all, even to a garbage value.

Anyways any help would be greatly appreciated.  Hope I was clear

Thanks

Dak

  • By the way the gap_params() function takes the device_name_pointer, to update the device name code architecture, which is eventually used by the advertising functionality.  In the original sdk 12.3, this was a #define value.  All I did was change what gap_params() looks at

  • Hi,

    There are a few issues with your code, but I do not see why you get corrupt data, but I am missing some context since I don't see all your relevant code. Some thoughts:

    • Using device_name_pointer as you write should be OK, but there is clearly some issue and I cannot see everything (since it is not included in your code snippet).
      • One significant problem is that you should not set device_name_pointer to point to the FDS data in flash like you do in your fds_read2(), since it is not guaranteed to stay intact after you call fds_record_close().
    • As mentionned, I don't see if you wait for FDS operations to complete before e.g. resetting. That should not lead to corruption, though.

    Let me just mention a few other issues which are not directly related to this issue:

    • You use always use fds_record_write(), which means that is you change name more than once you will add new records with new names, without removing the old. However, you do not have any method of choosing the right name, so it will probably not be what you would like (and you will fill up the flash if you change name may times). So you should use fds_record_update() to only keep the last name.
    • You define FILE_ID2 and REC_KEY2 repeatedly. This is a bad idea and will generate a warning, but it works since you use the same value. If you change it at some point, it will not work.
    • No indention in your code makes it difficult to read. That may only be an issue in the code you posted here, but please remember that in the future, as better readability makes it easier to understand what is going for us looking at it.
Related