Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FreeRTOS context switching

Tags:

c

freertos

I'm using FreeRTOS for a project of mine and I'm reading the documentation and there's something I can't understand. I know that context switching happens as the tick interrupt is triggered, so the scheduler performs its work and unblocks tasks that were waiting for an event and chooses the higher priority task that's in the ready state. But what happens when a task blocks before the tick interrupt? The documentation seems to hint that a context switch takes immediately place (for example,two task with different priorities each calling vTaskDelay() to free the CPU time slice). How does it happen? I searched but I couldn't find any answer to my question.

EDIT in my port of FreeRTOS (SAMD21 Cortex-M0+) the portYIELD() macro is used that simply request a SVCall exception, so is this the mechanism that is used to perform context switching (aside from the scheduler running on tick interrupts)?

like image 674
Luca Avatar asked Dec 06 '25 06:12

Luca


1 Answers

There is documentation about taskYIELD. This function can be used to request context switch so no need to wait for the tick. Context switching is privileged operation so it is often done by software interrupt. In your case by PendSV and SVCall.

If all tasks are blocked (e.g by vTaskDelay) then FreeRTOS is running Idle Task. vTaskDelay uses portYIELD internally to request context switch, because there is no way how to continue current task.

You also need some knowledge about Preemptive multitasking to understand FreeRTOS in that mode.

Edit 2016-01-29:

  • Calling delay function causes calling taskYIELD/portYIELD internally. So your current task is blocked and FreeRTOS reschedule to highest priority task, that can run (is not also blocked) or to Idle task if there is no task able to run.
  • Calling e.g. xQueueReceive can have two possibilities. There is some element in the queue, so it is POPed. There is no element in the queue, so the task is switched to blocked state and YIELD is called for you, so FreeRTOS reshedule to another task.
  • Calling e.g. xQueueSend can have two possibilities. There is no room in the queue, so the task is blocked until there is some space. There is at least one free element, so you can push to the queue.

Receiving element from the queue or sending element to the queue can wake other higher priority task, that is doing oposite but is currently blocked. FreeRTOS will reschedule it immediately.

This can be also done from interrupt handler. You can have handler task, that is waiting on some queue. From the interrupt, you put some element to the queue. After the interrupt ends, FreeRTOS reschedules to the task waiting on that queue. There is just prerequisite to have enough high priority on that task. This has benefit, that you are not doing much in the interrupt - just some cleanup and sending item to the queue - which is short operation. Handling interrupt can be also done by xTimerPendFunctionCallFromISR, which is another interresting way how to handle interrupts.

Please also read about FreeRTOS fundamentals. There are several chapters about it and it is interresting reading.

like image 131
j123b567 Avatar answered Dec 07 '25 21:12

j123b567



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!