2022-08-17 08:02 AM
Hi all,
I want to send loads of data to a client whenever it enables notification for that service. What I have now is that I can catch the En/disable of the characteristic notification and start a task on it using the sequencer. However as long as the task is running, all the received requests aren't executed until the transmission task is completed. Causing data to get lost.
How do I properly yield the task for received BLE requests to be executed?
Steps executed by code:
void TransmitDataTask()
{
while (notify == enabled)
{
Read 1 data entry
chop data into packages
send packages using aci_gatt_update_char_value
// TODO: Check for incomming ble requests/yield task ??
}
}
void IDataNotifyEnabled()
{
notify = enabled
set TransmitDataTask using UTIL_SEQ_SetTask
}
void IDataNotifyDisabled()
{
notify = disabled // will terminate the task
}
Kind regards,
Taxara
2022-08-17 08:07 AM
Perhaps leave and come back later?
2022-08-18 04:57 AM
I've modified that task to not be an long lasting while loop and used a periodic timer to set the task whenever notify is enabled. Feels a bit like a work around but it does work and is very stable.
I've tried to pause the task using UTIL_SEQ_PauseTask as well, but didn't manage to get that way to work.
Suppose that's what you meant @Community member ?
2023-10-09 02:50 AM
Hi Taxara,
Just wanted to check if you were able to figure out how to accomplish this? I am trying to do something similar and so far have not come across a definitive answer. Thanks for your time in advance!
2023-10-28 08:11 PM - edited 2023-10-28 08:12 PM
Hi there,
I think I know how to do this. If you just use UTIL_SEQ_PauseTask() the task will not yield, this will just cause the task to not run the next time around the sequencer super loop but you still need to exit the current task to do this. If you want the task to yield you need to use UTIL_SEQ_WaitEvt() [See 4.4.3 AN5289] and use UTIL_SEQ_SetEvt() to have the task resume from its current context.
For example, say you want a task to check for a flag every 1000ms but not block the program in between checks
// Task that you don't want blocking your other tasks
while(1)
{
while(!some_flag)
{
// You will need to create your HW Timer before you can use it
// The function attached to this timer should set the event. So that every second
// your task will check if the flag is set
HW_TS_Start(timer_id, 1000);
UTIL_SEQ_WaitEvt(event_id);
}
// Task continues...
}
void your_timer_callback(void)
{
UTIL_SEQ_SetEvt(event_id);
}
This is somewhat more tedious than using FreeRTOS where just using os_delay(1000) would make your task yield for 1000ms.