FreeRTOS task interrupting other tasks - c

I am learning about mutex and semaphore. And got a quick question to clarify:
void task1(void* parameter){
while(1){
global_var++;
}
}
void task2(void* parameter){
while(1){
global_var++;
}
}
xTaskCreate(task1,"task1",10000,NULL,1,NULL); // receiving modem input
xTaskCreate(task2,"task2",10000,NULL,1,NULL); // receiving modem input
If I have 2 tasks that are accessing one global variable. Is there a possibility if one task will interrupt another task if both are the same priority? Or the issues only start happening when one command is different priority or the task is being interrupted via the timer or other interrupts?

The tasks are getting scheduled by the operating system (f.e.: freertos). It depends on which scheduling technique is used. If it uses Round-Robin, the tasks are scheduled fairly, which means task2 will be scheduled after (defined timeslice) task1. Which means no starvation.
But as you mentioned if there is a interrupt, the ISR will be executed instead of task1 or task2.
A example can be found on: freertos page
There are two sheduling policies:
FreeRTOS kernel supports two types of scheduling policy:
Time Slicing Scheduling Policy: This is also known as a round-robin algorithm. In this algorithm, all equal priority tasks get CPU in equal portions of CPU time.
Fixed Priority Preemptive Scheduling: This scheduling algorithm selects tasks according to their priority. In other words, a high priority task always gets the CPU before a low priority task. A low priority task gets to execute only when there is no high priority task in the ready state. (from https://microcontrollerslab.com/freertos-scheduler-learn-to-configure-scheduling-algorithm/)
You can select scheduling algorithms by setting corresponding configuration bits (flags/defines) in theFreeRTOSConfig.h file.
For synchronization you should use a mutex (SO answer mutex). As wovano said semaphores are not exactly the same as a mutex (see semaphores vs. mutex).

Yes, both tasks will be scheduled alternately and thus can "interrupt" each other. By default, the tasks will be switched every millisecond.
Since both tasks share a resource (the global variable) and the increment operation is (in general) not atomic, you should indeed use a mutex to prevent possible errors.
NB: A mutex is not the same as a semaphore. Since you want MUTual EXclusion in this case, a mutex is the right solution.
(Note: this is only true if FreeRTOS is configured to use preemptive scheduling with time slicing, i.e. configUSE_PREEMPTION == 1 amd configUSE_TIME_SLICING == 1, which is the default.)

Related

FreeRTOS simultaneous tasks

I want to create two tasks that run simultaneously in FreeRTOS. The first task will deal with the LED, the second task will monitor the temperature.
I have two questions:
Will this code create two tasks that run simultaneously?
How do I send the data between the tasks, for example: if the temperature is more than x degrees, turn on the LED?
void firstTask(void *pvParameters) {
while (1) {
puts("firstTask");
}
}
void secondTask(void *pvParameters) {
while (1) {
puts("secondTask");
}
}
int main() {
xTaskCreate(firstTask, "firstTask", STACK_SIZE, NULL, TASK_PRIORITY, NULL);
xTaskCreate(secondTask, "secondTask", STACK_SIZE, NULL, TASK_PRIORITY, NULL);
vTaskStartScheduler();
}
Tasks of equal priority are round-robin scheduled. This means that firstTask will run continuously until the end of its time-slice or until it is blocked, then secondTask will run for a complete timeslice or until it is blocked then back to firstTask repeating indefinitely.
On the face of it you have no blocking calls, but it is possible that if you have implemented RTOS aware buffered I/O for stdio, then puts() may well be blocking when its buffer is full.
The tasks on a single core processor are never truly concurrent, but are scheduled to run as necessary depending on the scheduling algorithm. FreeRTOS is a priority-based preemptive scheduler.
Your example may or not behave as you intend, but both tasks will get CPU time and run in some fashion. It is probably largely academic as this is not a very practical or useful use of an RTOS.
Tasks never really run simultaneously - assuming you only have one core. In you case you are creating the tasks with the same priority and they never block (although they do output strings, probably in a way that is not thread safe), so they will 'share' CPU time by time slicing. Each task will execute up to the next tick interrupt, at which point it will switch to the other.
I recommend reading the free pdf version of the FreeRTOS book for a gentle introduction into the basics https://www.freertos.org/Documentation/RTOS_book.html

Preemption in FreeRTOS

I am starting to use FreeRTOS and I would like a interrupt to preempt whatever task was about to run and run the task I need to run critically.
Is there a way to do this in FreeRTOS? (Is this achieved through task priority?)
NO! Both the above answers are DANGEROUS.
Do NOT use taskENTER_CRITICAL() or taskEXIT_CRITICAL() inside an ISR - it is unusual to need a critical section in an ISR but if you do then use taskENTER_CRITICAL_FROM_ISR()/taskEXIT_CRITICAL_FROM_ISR(). (possible the AVR32 port is an exception to that rule?)
Do NOT use xTaskResumeFromISR() to synchronise a task with an interrupt. The link already posted to the documentation for that function even says this.
If my understanding of your question is correct you want the ability to have an interrupt unblock a task, and then if that task is the highest priority task in that is able to run, have the interrupt return directly to the unblocked task. If my understanding is right then there is an example of how to do that in an efficient way on the following page: http://www.freertos.org/RTOS_Task_Notification_As_Counting_Semaphore.html
The short answer would be: Yes, this is achieved through task priority.
The FreeRTOS kernel will consider swapping in any task in ready-state after an ISR has completed so it would preempt the current running task if a higher priority task is now ready.
It should be mentioned that this is really only true if the handler is called through FreeRTOS. On a Cortex-A processor there is a common IRQ entry-point in the IRQ or FIQ exception handler which is most likely handled by FreeRTOS or otherwise by an IRQ dispatcher which is easily wrapped by FreeRTOS, usually by a function in the port-layer called vApplicationIRQHandler().
On a Cortex-M this is not necessarily the case as the vector is usually manipulated by the vendor's MCU API. On a Cortex-M I'd safe-guard against this using portYIELD_FROM_ISR() in the ISR which should be implemented to provide the kernel with an opportunity to perform a context switch.
You can use xTaskResumeFromISR to do this.
There is a number of conditions to be met for the yielded task not to be interrupted by other tasks (like it's priority must be high enough) and a number of other conditions to be met to ensure that no interrupt can go un-serviced (like the yielded task must guarantee to be done before the next interrupt)
1. enable preemption:
This is very simple to do.
All the configuration options of FreeRTOS are under "FreeRTOSConfig.h"
#define configUSE_PREEMPTION 1
You can set this to 1 to use the preemptive RTOS scheduler, or 0 to use the cooperative RTOS scheduler.
Check this link for more info
2. Use critical section inside ISR
void taskENTER_CRITICAL( void );
//action
void taskEXIT_CRITICAL( void );
RTOS wont do anythis extra inside this critical part
ref: here

How do I decide between taskSpawn(), period(), and watchdogs?

We are using embedded C for the VxWorks real time operating system.
Currently, all of our UDP connections are started with TaskSpawn().
This routine creates and activates a new task with a specified
priority and options and returns a system-assigned ID.
We specify the task size, a priority, and pass in an entry point.
These are continuous connections, and thus every entry point contains an infinite loop where we delay before the next iteration.
Then I discovered period().
period spawns a task to call a function periodically.
Period sounds like what we should be using instead, but I can't find any information on when you would prefer this function over TaskSpawn. Period also doesn't allow specifying the task size or the priority, so how is it decided? Is the task size dynamic? What will the priority be?
There are also watchdogs.
Any task may create a watchdog timer and use it to run a specified
routine in the context of the system-clock ISR, after a specified
delay.
Again, this seems to be in line with the goal of processing data at a particular rate. Which do I choose when a task must continuously execute code at the same rate (i.e. in real time)?
What are the differences between these 3 methods?
Here is a little clarification:
taskSpawn(..) creates a task with which you're free to do anything with you like.
Watchdogs shall only be used to monitor time constraints. Remember that the callback of the watchdog is executed within the context of the system clock ISR which has many limitations (e.g. free stack size, never use blocking function calls in an ISR, ...). Additionally executing "a lot of code" in the system clock ISR slows down your entire system.
period(..) is intended to be a helper for the VxWorks shell and not to be used by a program.
With that being said your only option is to use taskSpawn(..) unless you're doing some very simple stuff in which case period(..) might be ok to use.
If you need to do things cyclically in a specific time frame you might look at timers or taskDelay(..) in combination with sysClkRateSet(..).
Another option is to create two tasks. One that is setting a semaphore after a specific time intervall and the other "worker" tasks waits for this semaphore to do something. With that approach you separate "timing" from "action" which proved to be benefitial according to my experience. You also might want to monitor excution time of the "worker" task by using a watchdog.

Need suggestion for handling large number of timers/timeouts

I am working on redesign an existing L2TP(Layer 2 tunneling protocol) code.
For L2TP , the number of tunnels we support is 96K. L2TP protocol has a keep-alive mechanism where it needs to send HELLO msges.
Say if we have 96,000 tunnels for which L2TPd needs to send HELLO msg after configured timeout value , what is the best way to implement it ?
Right now , we have a timer thread , where for every 1sec , we iterate and send HELLO msges. This design is a old design which is not scaling now.
Please suggest me a design to handle large number of timers.
There are a couple of ways to implement timers:
1) select: this system call allows you to wait on a file descriptor, and then wake up. You can wait on a file descriptor that does nothing as a timeout
2) Posix Condition Variables: similar to select, they have a time out mechanism built in.
3) If you are using UNIX, you can set a UNIX signal to wake up.
Those are basic ideas. You can see how well they scale to multiple timers; I would guess you'd have to have multiple condvars/selects for some handful of the threads.
Dependingo on the behaviour you want, you would probably want a thread for every 100 timers or so, and use one of the mechanisms above to wake up
one of the timers. You'd have a thread sitting in a loop, and keeping
track on each of the 100 timeouts, then waking up.
Once you exceed 100 timers, you would simply create a new thread and have it manage the next 100 timers and so on.
I don't know if 100 is the right granularity, but it's something you'd play with.
Hopefully that's what you are looking for.
Typically, such requirements are met with a delta-queue. When a timeout is required, get the system tick count and add the timeout interval to it. This gives the Timeout Expiry Tick Count, (TETC). Insert the socket object into a queue that is sorted by decreasing TETC and have the thread wait for the TETC of the item at the head of the queue.
Typically, with asocket timeouts, queue insertion is cheap because there are many timeouts with the same interval and so new timeout insertion will normally take place at the queue tail.
Management of the queue, (actually, since insertion into the sorted queue could take place anywhere, it's more like a list than a queue, but whatever:), is best kept to one timeout thread that is normally performing a timed wait on a condvar or semaphore for the lowest TETC. New timeout-objects can then be queued to the thread on a thread-safe concurrent queue and signaled to the timeout-handler thread by the sema/condvar.
When the timeout thread becomes ready on TETC timeout, it could call some 'OnTimeout' method of the object itself, or it might put the timed-out object onto a threadpool input queue.
Such a delta-queue is much more efficient for handling large numbers of timeouts than any polling scheme, especially for requirements with longish intervals. No polling is required, no CPU/memory bandwidth wasted on continual iterations and the typical latency is going to be a system clock-tick or two.
It is dependent on the processor/OS, kernel version, architecture.
In linux, one of the option is to use its timer functionality for multiple timers. Addition of timer can be done using add_timer in linux. You can define it using timer_list and initilialize internal values of timer using init_timer.
Followed by it register it using add_timer after filling timer_list(timeout(expire), function to execute after timeout(function), parameter to the function(data)) appropriately for respective timer. If jiffies is more than or equal to timeout(expire), then the respective timer handler(function) shall be triggered.
Some processors have provisioning for timer wheels(that consists of a number of queues that are placed equally in time in slots) which can be configured for a wide range of timers,timeouts as per the requirement.

Can I set up the priority of a workqueue?

Can I set up the priority of a workqueue?
I am modifying the SPI kernel module "spidev" so it can communicate faster with my hardware.
The external hardware is a CAN controller with a very small buffer, so I must read any incoming data quickly to avoid loosing data.
I have configured a GPIO interrupt to inform me of the new data, but I cannot read the SPI hardware in the interrupt handler.
My interrupt handler basically sets up a workqueue that will read the SPI data.
It works fine when there is only one active process in the kernel.
As soon as I open any other process (even the process viewer top) at the same time, I start loosing data in bunches, i.e., I might receive 1000 packects of data with no problems and then loose 15 packets in a row and so on.
I suspect that the cause of my problem is that when the other process (top, in this case) has control over the cpu the interrupt handler runs, but the work in the workqueue doesn't until the scheduler is called again.
I tried to increase the priority of my process with no success.
I wonder if there is a way to tell the kernel to execute the work in workqueue immediatelly after the interrupt handling function.
Suggestions are welcome.
As an alternative you could consider using a tasklet, which will tell the kernel execute more immediate, but be aware you are unable to sleep in tasklets
A good ibm article on deffering work in the kernel
http://www.ibm.com/developerworks/linux/library/l-tasklets/
http://www.makelinux.net/ldd3/chp-7-sect-5
A tasklet is run at the next timer tick as long as the CPU is busy running a process, but it is run immediately when the CPU is otherwise idle. The kernel provides a set of ksoftirqd kernel threads, one per CPU, just to run "soft interrupt" handlers, such as the tasklet_action function. Thus, the final three runs of the tasklet take place in the context of the ksoftirqd kernel thread associated to CPU 0. The jitasklethi implementation uses a high-priority tasklet, explained in an upcoming list of functions.

Resources