Context switching as I understood it, is when a highier priority task becomes ready and the schedular immediately selects it to run saving the context of the previous task so it continues once this new high priority task is blocking.
So what happens when a task calls a blocking function ex: vTaskDelay()
mid task, does context switching happens the same way as described or will the task start from the start.
按照我的理解,上下文切换是指当一个较高优先级的任务准备就绪,调度程序立即选择它来运行,以保存前一个任务的上下文,这样一旦这个新的高优先级任务被阻塞,它就会继续。那么,当任务在任务中间调用阻塞函数ex:vTaskDelay()时会发生什么,上下文切换是以所述的方式发生还是任务将从头开始。
Take this code for example
以下面的代码为例
int i = 0;
while( c != EOF ){
printf("%c",c);
if( i == 10 ){vTaskDelay(100/portTICK_PERIOD_MS); }
i++;
}
Does the loop continue or start from i=0
循环是继续还是从i=0开始
更多回答
It will continue, but it will never end since you never change c
(assuming c
is not EOF
already when the loop starts).
它将继续,但它永远不会结束,因为您永远不会更改c(假设循环开始时c不是EOF)。
@Ted Lyngmo True but i just came up with an example from the top of my head it should be while((c = fgetc(some_file
)) != EOF)....
@Ted Lyngmo True,但我只是从我的头顶想出了一个例子,应该是While((c=fgetc(Ome_File))!=EOF)...
@TedLyngmo it does not matter. Imagine while(1)
instead.
@TedLyngmo,这并不重要。想象一下While(1)。
so what happens when a task calls a blocking function ex: vTaskDelay()
vTaskDelay()
is not blocking. The task is put into the BLOCKED state and control is passed to another task and your processor will execute other tasks. The control is passed back to the task at some point when delay passes.
VTaskDelay()没有阻止。该任务被置于阻塞状态,控制权被传递给另一个任务,您的处理器将执行其他任务。当延迟过去时,控制在某个点被传递回任务。
Context switching as I understood it, is when a highier priority task
becomes ready
It you do not enable round-robin in the freeRTOS configuration the control will only passed to another task when you allow it (by [for example] calling vTaskDelay()
function, semaphore, queue etc functions). freeRTOS is not like big OSes.
如果您没有在自由RTOS配置中启用循环调度,则只有当您允许时(例如,通过调用vTaskDelay()函数、信号量、队列等函数),控制权才会传递给另一个任务。免费实时操作系统与大型操作系统不同。
mid task, does context switching happens the same way as described or
will the task start from the start.
The execution will continue from from the next statement after the vTaskDelay()
.
执行将从vTaskDelay()之后的下一条语句开始。
In a pre-remptive priority based RTOS (including FreeRTOS) context switches occur as a result of the scheduler running. The scheduler will run on exit from the interrupt context (including but not only the system tick interrupt), or when a call is made to an RTOS function that either pends the current task (yields) or which may change the state of a currently blocked task (pre-empts).
在基于预留优先级的RTOS(包括自由RTOS)中,上下文切换是调度程序运行的结果。调度器将在从中断上下文(包括但不仅是系统计时中断)退出时运行,或者在调用RTOS函数时运行,该RTOS函数将挂起当前任务(屈服)或可能改变当前被阻止任务的状态(抢占)。
An RTOS delay is an example of a yielding function - the task voluntarily gives up the CPU and causes the scheduler to run. Yielding functions include:
RTOS延迟是一个让步函数的例子-任务自愿放弃CPU并导致调度程序运行。屈服函数包括:
- delay
- semaphore take
- message queue receive
- event flag wait
- mutex resource release
Functions that may cause preemption
可能导致抢占的功能
- semaphore give
- message queue send
- event flag trigger
- mutex resource lock
Delay is distinct in that it appears to have no pre-empt counterpart, but in fact the delay expiry (on system tick interrupt) causes pre-emption by the task issuing the the delay.
延迟的不同之处在于,它看起来没有抢占的对应项,但实际上延迟过期(在系统计时中断时)会导致发出延迟的任务抢占。
Some RTOS have a specific yield function, essentially equivalent to a zero length delay. Such a function is useful only when round-robin scheduling of same-priority tasks is supported, since a higher priority task becoming ready will pre-empt, and a lower-priority ready task will not be scheduled on a zero length delay (at least it shouldn't). A yield or zero-delay can be used for co-operative multitasking or where time-slicing is supported it allows a thread to voluntarily "give-up" the remainder of its slice.
一些RTOS具有特定的屈服函数,基本上相当于零长度延迟。这种功能仅在支持相同优先级任务的循环调度时才有用,因为准备就绪的较高优先级任务将抢占,而不会以零长度延迟调度较低优先级就绪任务(至少不应该如此)。屈服或零延迟可用于协作式多任务处理,或者在支持时间切片的情况下,它允许线程自愿“放弃”其切片的剩余部分。
更多回答
So a task that is approximated to take some time, a delay is the solution so it doesnt starve the cpu? Or is there a better workflow. Since im working with the esp-idf the watchdog gets triggered if starvation occurs
所以,一个接近花费一些时间的任务,延迟就是解决方案,这样它就不会让CPU挨饿?还是有更好的工作流程。因为我与esp-idf一起工作,所以如果发生饥饿,就会触发看门狗。
Yes delay in RTOS is something different than in the arduino and it does not starve the CPU. The control is taken from the task and it is not given back until the delay passes. The rest of the program (other tasks) will continue to be executed. But you have to remember that the delay will not be precise as the control might not be passed immediately after the time. It will be passed when the scheduler does the switch and there are no tasks with higher priority in the READY state
是的,RTOS中的延迟与Arduino中的有所不同,它不会导致CPU资源匮乏。控制权从任务中获得,直到延迟过去才会归还。程序的其余部分(其他任务)将继续执行。但你必须记住,延迟不会是精确的,因为控制可能不会在时间过后立即通过。当调度程序进行切换并且在就绪状态下没有具有更高优先级的任务时,它将被传递
Got you..so the delay mentioned is not precise maybe for more precision vTaskDelayUntil() could be used. The point i wanted to understand is clarified that context is restored from where it last stopped. Thank you
明白了..所以提到的延迟不是精确的,如果需要更精确的延迟,可以使用vTaskDelayUntil()。我想要理解的一点是澄清上下文从它上次停止的地方恢复。谢谢
"vTaskDelay()
is not blocking. The task is put into the BLOCKED state..." So it is blocking.
“vTaskDelay()未阻塞。任务被置于BLOCKED状态.“所以它是阻塞的。
I was thinking in general terms (I don't know anything about freeRTOS). A task that is blocked is one that cannot continue for any reason. A blocking function is one that blocks the task it is in, which waiting for period of time clearly does. On the other hand, if you mean that vTaskDelay()
doesn't block everything else that makes a lot more sense.
我只是泛泛而谈(我对免费实时操作系统一无所知)。被阻止的任务是指由于任何原因无法继续执行的任务。阻塞函数是阻塞它所在的任务的函数,等待一段时间显然可以做到这一点。另一方面,如果您的意思是vTaskDelay()不会阻止其他所有内容,那么这就更有意义了。
我是一名优秀的程序员,十分优秀!