cancel
Showing results for 
Search instead for 
Did you mean: 

How to yield a task when sending large amount of data

Taxara
Associate III

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

4 REPLIES 4

Perhaps leave and come back later?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Taxara
Associate III

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​ ?

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!  

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.