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

pstorage update sometimes doesn't update, prevents BLE reconnect

Hello,

I am using SDK version 9 with softdevice s130 operating as both a central and peripheral. I provide a custom peripheral BLE service, and when it receives some information in one of the characteristics, it is supposed to write this information to persistent storage. I do this in a function that looks like this:

void save_settings_to_flash(uint8_t *settings, uint16_t dsize)
{
	pstorage_handle_t block_handle;
	uint32_t err_code;

	err_code = pstorage_block_identifier_get(&app_data_flash_manager_handle, 0, &block_handle);
	APP_ERROR_CHECK(err_code);

	err_code = pstorage_update(&block_handle, settings, dsize, 0);
	APP_ERROR_CHECK(err_code);
}

No errors are reported at any time, and my callback is being called with no problem. However, about 20% of the time, the data does not actually get saved, and if I disconnect from the service after this happens, apparently it stops advertising, as the service is no longer visible and I cannot reconnect to it. Note that if I remain in the connection, I can still communicate through the service, and it's responding normally. It's just that once I disconnect, I can't reestablish the connection.

It appears that the scanner is continuing to receive advertisements from another peripheral even after it loses the ability to connect as a peripheral.

app_data_flash_manager_handle and block_handle are the same each time for both reading and writing.

I have tried:

  1. performing the save operation in a scheduled event, rather than directly in the response to receiving the characteristic data.
  2. implementing the workaround in this thread.
  3. using a pstorage_clear() operation before the update (this makes it worse).

But nothing I do seems to fix this problem.

Any help would be appreciated. Thanks!

  • Just a guess, but I think you want to make your block_handle a static or global. The address of it is passed to pstorage and queued up with the update operation. If the stack is reused in that time the handle could be changed on you.

  • Thanks. That's a good point. However, I just tried it with block_handle (and app_data_flash_manager_handle) as static globals, and it still seems to behave the same.

  • Hmmm... Bummer. I do think your #1 change to use a scheduled event would be a good idea though. I would think if it was failing you should get a flash error event back. I had a problem in production where saving a serial number in flash was failing due to a timeout because I was advertising so quickly. It was very intermittent and took forever to track down.

  • Hi Dan

    The advertising module will not start advertising unless the pstorage command queue is empty. If the queue is not empty, the advertising start will be set as pending and will start whenever the pstorage command queue becomes empty, i.e. when you receive a pstorage callback. If the pstorage command queue will never become empty, advertising will never start.

    Perhaps the next thing to do is to check if the pstorage command queue is empty. You could check if there is pstorage callback received from softdevice in the sys_evt_dispatch function (in i.e. ble_app_bps in the SDK). You could also check if the flash_access_in_progress() function returns true or false when you attempt to start advertising by calling ble_advertising_start

Related