RTOS priority in infinite loops

I am having a confusion regarding the tasks in an RTOS. consider I am using a single core and it has two tasks. Both tasks have infinte loops as I want Blinking LEDs in these loops. The first tasks has infinite loops and both blink leds at 1s delay on different GPIO pins. Considering task 1 have higher priority then the other.
In this case since no task is being ended and are running continously then how does the code work. Will it only run the loop with the highest priority and leave the second task??
In case I am using delay() command for blink rather than vtaskdelay in the task loops.

How will it execute now??? Kindly help me in this

I assume that you're talking about FreeRTOS on the ESP32. The scheduling algorithm is very simple. As task that is running will continue to run unless one of three things happens:

  1. A task of higher priority enters the Ready to Run state.

  2. The running task’s time slice has expired and there are one or more tasks of equal priority that’s in the Ready to Run state. If so, these tasks will run next.

  3. The running task enters the Blocked state.

delay() calls vTaskDelay(). So, that is a distinction without a difference.

what do you mean by a task is ready. Both are infinite loops and they are involved in a continous process and not idle. So how does it change between the two loops?

I suggest that you study Mastering the FreeRTOS Real Time Kernel - A Hands On Tutorial Guide to gain an understanding of task states.

delay(), or equivalently vTaskDelay(), will cause a task to enter the blocked state for the specified amount of time.

That means that each task takes a pause of 1s after each LED state change.

In contrast to smaller controllers on RTOS all delays should be implemented by vTaskDelay() or delay(), not by polling the time.

yes I mean to say that since both loops are working at the same time then how does the RTOS decide to move into the second task. as previous one had higher priority and it is still in loop

It does so as soon as a task calls vTaskDelay() and is paused (blocked) for that time.

suppose I donot use any such statement then how does it respond??

The watchdog will bite you!

Sir can you please explain this to me abit as I have seen many sources but couldnt find an answer.

If I don't know your question then I can not answer better.

We're 13 posts into this thread already and haven't seen your code. Post it. Use Code Tags.

put another way, when both a task does delay(), it STOPS running. When both tasks are delaying for a second, there are NO tasks running. (delay() is known as a "blocking" function; when you call it, the task calling it is "blocked", which in the context of an OS is "not running.")

What IS running is the "scheduler." It's job is to constantly check all the non-running tasks to see if they have become runnable. In your case, each task becomes runnable after it has been NOT running for about 1 seconds. Since the tasks didn't "start" at exactly the same time, probably one of them will consistently run first.

Hi @mhaza

In a non-RTOS system the program instructions are executed sequentially.

In a RTOS the program's flow is determined by a scheduler. The scheduler is some clever code that checks to see which tasks are in the "ready" state and whether their priority is higher than the task currently in "running" state.

If so, it swiches context, or in other works saves the currently "running" task's position (aka context) to memory, relegating it to the "ready" state. It then loads the context of the highest priority "ready" task from memory, elevating it to the status of "running" state, allowing the task to run from its last know position.

If not, and the current task remains the highest priority, it is allowed to continue executing.

The scheduler itself can be called in a number of different ways:

Firstly, it can be called by a hardware timer interrupt, this can be a standard or watchdog timer (depending on the RTOS implementation). This is known as a "time slice" and allows the scheduler a window of opportunity to periodically "switch context" in order to prioritise the highest priority tasks. The scheduler is essentially called from the timer's interrupt service routine (ISR).

Secondly, it can be called whenever a task currently in the "running" state enters a "blocked" state, for example due to a delay, or to wait for synchronisation with another task, for example a semaphore or some other form of task-to-task based communication. These delay and synchronisation RTOS functions call on the scheduler behind the scenes.

Finally, it can be called whenever a hardware interrupt occurs. Hardware interrupts again provide an opportunity to invoke the scheduler in order to re-prioritise tasks. This is implemented by employing special RTOS functions within the interrupt handler function's ISR itself.

In summary, the RTOS is essentially a software construct that operates at higher level than the underlying hardware. However, hardware interrupts allow the scheduler to call on high priorty, service tasks that override the lower priority time-sliced ones. Thereby creating an interrupt driven, prioritised, multi-tasking system.

Pretty much what I said but with more words :rofl:

There’s one sub-case when the scheduler runs that you didn’t mention. It’s when a running task calls an RTOS API that causes another task to exit the Blocked state and enter the Ready to Run state (such as freeing a mutex or posting data to a queue). If that task has a higher priority than the currently running one, the context switch will occur and the higher-priority task will start running immediately. It doesn’t have to wait until the current time slice expires or an interrupt occurs.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.