I am transferring a working project from TI to nRF 2840. In main.c, two threads are created that collect data from the ADC in an endless loop. As data portions are completed, upon receipt of the required number of readings, they are sent through the BLE. For ease of debugging the BLE part, for now, threads simply generate data on a timer, each portion of data also has a portion counter to control data integrity during transmission. Each thread notifies via k_sem_give() that the next piece of data is ready. First, I did as in the examples: in the main thread, I wait for semaphores, and from there I call bt_gatt_notify().
In this version, everything works, but sometimes data loss occurs.
Then I redid it differently, without any semaphores - bt_gatt_notify() calls each of the two threads as soon as it collects a portion of data. In this version, it works perfectly, there is no data loss!
But I have no information about how long the bt_gatt_notify() function will run, it may not have time to return before the next ADC sample arrives. Then I returned to the data-collecting threads k_sem_give() instead of bt_gatt_notify(), and created two more threads, each of which waits for its own semaphore and calls bt_gatt_notify(). To my surprise, the data again began to be lost during transmission!
So I have two questions: is it good practice to call bt_gatt_notify() directly from the thread that is collecting the data to send? The bt_gatt_notify() function won't return until the on-the-air notification is done, or will it return almost immediately, just by putting the notification on the internal BlE queue?