Shuld be a delay in a FreeRTOS task main loop? - task

Is it necessary to add some delay into the infinite loop inside a FreeRTOS task (created by xTaskCreatePinnedToCore())? Also, in my case, since the function aws_iot_mqtt_yield already takes a timeout (100) I tend to think the extra task delay is unnecessary.
My task looks like:
...
while(1) {
error = aws_iot_mqtt_yield(&m_client, 100);
check error...
vTaskDelay(10 / portTICK_RATE_MS);
}
...

No. You shouldn't need to add a delay. In fact in my opinion it is bad practice as it means you could be suspended at two different points in the task which can lead to very confusing program flow and is hard to debug.

Related

FreeRTOS - creating a task in place of another task?

I am using heap_1 memory allocation. There is an initialization task Task_ini, from which 2 tasks Task_1 and Task_2 are launched. Then I delete Task_ini. At some point in time from Task_1 I need to create a new task Task_3. How can I create Task_3 in the FreeRTOS heap in place of Task_ini which has already been deleted by that time, knowing only its TaskHandle_t?
int main(void){
xTaskCreate(Task_ini, "Task_ini", configMINIMAL_STACK_SIZE, NULL, 1, &htask_ini);
vTaskStartScheduler();
for(;;);
}
void Task_ini(void *pParams){
xTaskCreate(Task_function, "Task_1", configMINIMAL_STACK_SIZE, &param1, 1, &htask1);
xTaskCreate(Task_function, "Task_2", configMINIMAL_STACK_SIZE, &param2, 1, &htask2);
vTaskDelete(NULL);
}
void Task_function(void *pParams){
for(;;){
//task code
//...
//end task code
if(create == true){
create = false;
//Here I need to create a task at the address where the "Task_ini" task was.
//My code creates a task in a new heap section, and if there is no space it will cause a memory allocation error.
xTaskCreate(Task_function, "Task_3", configMINIMAL_STACK_SIZE, &param3, 1, &htask3);
}
}
}
The main idea of heap_1 is that you can't free memory. It is simply not capable of doing so. If you want to delete tasks, you need to use other heap_n methods. Even in that case, you should let the kernel to do its job: It's kernels job to manage memory for FreeRTOS objects, not yours.
Actually, deleting tasks isn't considered as a good practice in general. Unless you are really low on heap space, you can simply suspend the task. In this way, you can wake it up again without any cost in case its services are required again.
It's true that an init task will become useless after the system initialization. But there is a well known solution for your init task problem: It can evolve into another task after it completes the initialization sequence. For example, Task_ini can create only Task_2, and instead of creating a Task_1, it can do the Task_1's job itself.
Update:
It's kernels job to manage memory for FreeRTOS objects, not yours.
Actually, FreeRTOS allows you to manage the memory manually, if you prefer to do so. There are static versions of object creation functions, like xTaskCreateStatic(). When using these static versions, you pass two statically allocated buffers to the function for the task stack and the task control block (TCB). Then you will literally be able to place one task onto another (provided that it's deleted). To be able to use these functions, configSUPPORT_STATIC_ALLOCATION must be defined as 1.
But I suggest you to avoid manual memory management unless you have a specific reason to do so.

Why we need the synchronous operation in ios

I want to know As we all know how asynchronous task are necessary for concurrency but Wanted to know why we need the synchronous tasks. while we can achieve the same with the normal usage of function.
Thanks & regards
Rohit
When you calls something synchronously, it means that 'the thread that initiated that operation will wait for the task to finish before
continuing'. Asynchronous means that it will not wait for finish the task.
synchronous calls stops your current action and returns when the call returned. with asynchronous calls you can continue.
synchronous is the opposite of asynchronous code, and therefore is ordinary code.
At the end, if asynchronous is totally out of scope then you will not emphasize the word synchronous.
It helps to synchronise threads, as the name suggests.
consider a typical usage of GCD async and sync (pseudo)
async background_thread {
//1 call webservice or other long task that would block the main thread
sync main_thread {
//2 update UI with results from 1
}
//3 do something else that relies on 2
}
now if 2 was in an async and you needed to do something at 3 that relies on the updates at 2 to have happened, then you are not guaranteed (and most likely wont) get the behaviour you are expecting. instead, you use a sync to make sure that the task is completed before continuing the execution in the background thread.
If you are asking now, why not just take out the sync/async around 2 so it executes in order anyway? the problem is, the UI must not be updated on a background thread otherwise the behaviour is undefined (which usually means the UI lags a lot). So in essence what happens is the background thread waits at 2's sync until the main thread gets round to executing that block, then it will continue with the rest of the execution on the background thread.
If you were dealing with a task that doesnt require the main thread (or some other thread) to execute properly, then yes you may as well take out the sync at 2.
This is just one example of how a sync is useful, there are others if you are doing advanced threading in your app.
Hope this helps
Typically it's because you want to do an operation on a specific different thread but you need the result of that operation. You cannot do the operation asynchronously because your code will proceed before the operation on the other thread completes.
Apple has a very nice example:
func asset() -> AVAsset? {
var theAsset : AVAsset!
self.assetQueue.sync {
theAsset = self.getAssetInternal().copy() as! AVAsset
}
return theAsset
}
Any thread might call the asset method; but to avoid problems with shared data, we require that only functions that are executed from a particular queue (self.assetQueue) may touch an AVAsset, so when we call getAssetInternal we do it on self.assetQueue. But we also need the result returned by our call to getAssetInternal; hence the call to sync rather than async.

printing the stack of a task in FreeRTOS

I am working on a STM32F4-discovery board, i installed FreeRTOS on the board and was able to run two tasks created by main function.
Now i want task 1 to access the local variables of task 2 with any passing of variable by reference or by value.
I thought it would be good to print the stack content of task 2 and then locate the local variables and use that in task1
Can somebody guide me with this?
I tried to print the address of each variable and tried to use in task1, but my program did not compile and returned -1.
It is not clear to me what you are trying to achieve, or what you mean by the program returning -1 because it didn't compile, but it would not be normal for one task to access a stack variable of another task.
Each task has its own stack, and the stack is private to the task. There are lots of ways tasks can communicate with each other though, without the need to access each other's stack. The simplest way is just to make the variable global, although global variables are rarely a good thing. Other than that you could send the value from one task to another on a queue (http://www.freertos.org/Inter-Task-Communication.html), or even using a task notification as a mailbox (http://www.freertos.org/RTOS_Task_Notification_As_Mailbox.html).
First, a cautionary note: what you're trying to do -- access local variables of one task from another -- can be error-prone. Particularly if the local is declared in Task A and goes out of scope before Task B accesses it. Since stack memory can be reused for different variables in different functions, Task B might be accessing some other variable.
But I've actually used this pattern in practice -- specifically, to allow one task to stack-allocate a buffer for communication serviced by another task.
So I'll just assume that you know what you're doing. :-)
It's difficult to compute the address of a local variable ahead of time. If you derive it today, it's likely to change if you change the code or compiler version. What you probably want to do is to capture its address at runtime and somehow make it available to the other task. This can be be tricky, however: it's possible for the other task to try to use the local before your task starts up, and nothing prevents other tasks from getting to it.
A slightly cleaner approach would be to provide the address to the other task through a queue shard by the two tasks.
QueueHandle_t shared_queue;
void common_startup() {
// This code might go in main, or wherever you initialize things.
shared_queue = xQueueCreate(1, sizeof(unsigned *));
}
void task_a() {
// This task wants to share the address of 'local' with task_b.
unsigned local;
// Stuff the address of our local in the queue. We use a
// non-blocking send here because the queue will be empty (nobody
// else puts things in it). In real code you'd probably do some
// error checking!
unsigned * ptr = &local;
xQueueSend(shared_queue, &ptr, 0);
while (1) {
do_stuff();
}
}
void task_b() {
// This task wants to use task_a's 'local'.
// Real code would do error checking!
unsigned * ptr;
xQueueReceive(shared_queue, &ptr, portMAX_DELAY);
while (1) {
// Just increment the shared variable
(*ptr)++;
}
}

Need explanation for an excerpt from Apple's documentation on NSRunLoop

Apple's official documentation is sometimes difficult for understanding, especially for non-native speakers. This is an excerpt from Anatomy of NSRunLoop
A run loop is very much like its name sounds. It is a loop your thread enters and uses to run event handlers in response to incoming events. Your code provides the control statements used to implement the actual loop portion of the run loop—in other words, your code provides the while or for loop that drives the run loop. Within your loop, you use a run loop object to "run” the event-processing code that receives events and calls the installed handlers.
This confuses me. My code never provides while or for loops even for non-main threads. What is being meant here? Can anyone explain?
Keep reading until Using Run Loop Objects and Apple’s code samples do show control statements like while loops.
Listing 3-1
NSInteger loopCount = 10;
do
{
// Run the run loop 10 times to let the timer fire.
[myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
loopCount--;
}
while (loopCount);
Listing 3-2
do
{
// Start the run loop but return after each source is handled.
SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);
// If a source explicitly stopped the run loop, or if there are no
// sources or timers, go ahead and exit.
if ((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished))
done = YES;
// Check for any other exit conditions here and set the
// done variable as needed.
}
while (!done);
The intended way to use NSRunLoop does require you to invoke the next run, again and again until a certain condition is met.
But if you start your run loop with -[NSRunLoop run], it runs indefinitely without help. That’s what the main thread does.
In case you’re wondering why Apple lets (or wants) you to control every loop, NeXTSTEP shipped in the 80s when every CPU cycle counts. Functions like -[NSRunLoop runMode:beforeDate:] lets you fine tune the frequency and behaviour of your run loops down to every run.
Oh, you do run a loop on the main thread, but you don't know.
Set a breakpoint on an action method and look at the stack trace. There will be something like:
#9 0x00007fff912eaa29 in -[NSApplication run] ()
That's the loop.
In another thread you very often do not need a instance of NSRunLoop. Its primary ability is to receive events and to dispatch them. But in an additional thread you want to process calculations straight forwarded in most cases. To have a term for it: Additional threads are usually not event-driven.
So you have a run loop (and have to run it) only rarely, especially when you have networking or file access that is dispatched using a run loop.In such a case it is a common mistake that one does not run the thread's run loop.

Resart a task in FreeRTOS

I have a specific task routine which performs some operations in a specific order, and these operations handle few volatile variables. There is a specific interrupt which updates these volatile variables asynchronously. Hence, the task routine should restart if such an interrupt occurs. Normally FreeRTOS will resume the task, but this will result in wrong derived values, hence the requirement for restarting the routine. I also cannot keep the task routine under critical section, because I should not be missing any interrupts.
Is there a way in FreeRTOS with which I can achieve this? Like a vtaskRestart API. I could have deleted the task and re-created it, but this adds a lot of memory management complications, which I would like to avoid. Currently my only option is to add checks in the routine on a flag to see if a context switch have occured and if yes, restart, else continue.
Googling did not fetch any clue on this. Seems like people never faced such a problem or may be its that this design is poor. In FreeRTOS forum, few who asked for a task-restart didn't seem to have this same problem. stackOverflow didn't have a result on freertos + task + restart. So, this could be the first post with this tag combination ;)
Can someone please tell me if this is directly possible in FreeRTOS?
You can use semaphore for this purpose. If you decide using semaphore, you should do the steps below.
Firstly, you should create a binary semaphore.
The semaphore must be given in the interrupt routine with
xSemaphoreGiveFromISR( Example_xSemaphore, &xHigherPriorityTaskWoken
);
And, you must check taking semaphore in the task.
void vExample_Task( void * pvParameters )
{
for( ;; )
{
if (xSemaphoreTake( Example_xSemaphore, Example_PROCESS_TIME)==pdTRUE)
{
}
}
}
For this purpose you should use a queue and use the queue peek function to yield at your volatile data.
I'm using it as I have a real time timer and this way I make the time available to all my task, without any blocking.
Here it how it goes:
Declare the queue:
xQueueHandle RTC_Time_Queue;
Create the queue of 1 element:
RTC_Time_Queue = xQueueCreate( 1, sizeof(your volatile struct) );
Overwrite the queue everytime your interrupt occurs:
xQueueOverwriteFromISR(RTC_Time_Queue, (void*) &time);
And from other task peek the queue:
xQueuePeek(RTC_GetReadQueue(), (void*) &TheTime, 0);
The 0 at the end of xQueuePeek means you don't want to wait if the queue is empty. The queue peek won't delete the value in the queue so it will be present every time you peek and the code will never stop.
Also you should avoid having variable being accessed from ISR and the RTOS code as you may get unexpected corruption.

Resources