嗨,我是RTOS的新手,在我阅读的几乎每个文档中,它都表明任务必须处于无限循环中,但没有说明原因。谁能帮忙解释一下?谢谢
我认为说"RTOS任务必须是无限循环"并不完全准确。 我认为更正确的说法是"对于许多 RTOS,任务一定不能返回"。 这样做的原因是最初调用任务的 RTOS 调度程序不是为处理任务的返回而设计的。 如果任务确实返回,则 RTOS 调度程序可能会断言错误。
我可以猜测为什么许多RTOS调度程序不处理任务返回的几个原因。 首先,无限循环是在嵌入式系统中实现的最典型的任务类型。 结束的任务不太常见。 其次,RTOS调度程序可能必须更复杂才能处理返回任务。 第三,RTOS 设计者可能不想假设任务返回时应该做什么,而是希望任务设计者显式调用适当的任务终止例程。
对于许多不允许任务返回的RTOS,无限循环并不是唯一的解决方案。 RTOS 可能会提供一个任务终止例程,该例程从任务列表中删除任务,以便永远不会再次计划该任务。 如果任务调用任务终止例程,则该任务不必是无限循环,也不会返回到其调用方。(即,RTOS 任务终止例程不返回,因此调用它的任务也不会返回。 例如,FreeRTOS 有 vTaskDelete(),uC/OS-II 有 OSTaskDel() 用于删除非无限循环的任务。
无限循环是嵌入式系统中常见的任务类型,因为许多嵌入式系统只是一遍又一遍地做同样的事情。 许多嵌入式系统与PC不同,因为它们没有用户与它们交互,启动和终止各种任务或应用程序。
它们不会,但如果任务函数运行到完成,则任务将终止。
您可以选择在每次需要时实例化一个新的运行到完成任务,但实例化任务非常耗时且可能不确定,因此不适合硬实时响应。 让任务等待某些阻塞对象(如事件、信号量或计时器)更有效、响应更快,这样它就可以在每次需要时确定性地响应。 另一方面,如果您有许多不同的非实时任务,只需要偶尔运行,则运行到完成模式可以节省资源。
然而,至少有一个任务需要无限期运行 - 如果一切都停止了,你的系统将什么都不做,直到电源被重启或复位断位(例如通过看门狗定时器)。
RTOS 实现各不相同,您需要检查 RTOS 如何处理终止线程功能。 您可能需要显式终止调用来确保内核释放资源。
如果你有一个需要某种形式的受控优雅关闭的系统,你不需要将任务编码为无限循环,而是有条件地退出循环,以便任务可以根据请求终止,例如;
while( (event_flags & TERMINATE) == 0 )
{
event_flags = eventWait( WAIT_FOREVER ) ;
// handle events
...
}
在随任何GPOS(通用操作系统)一起提供的普通C语言实现中,如Linux,Windows,Mac OSX,C运行时库负责启动任务(可以在GPOS上下文中称为线程/进程)以及在任务结束时充当收集器。
这意味着,crt(C 运行时)将调用任务的main()
来启动它,当任务返回 return
语句时,控件将传递回操作系统的 crt。
在RTOS中,虽然您可以使用C语言进行编程,但CRT本身没有特定的实现。"启动"函数(通常用汇编编写)调用main。但是,此 Startup 代码没有任何机制来收集任务的返回值,因此任务需要在无限循环中运行,以将控件保留在任务本身内。否则,CPU/MCU 将没有任何返回地址可转到。
但是,可以使用 RTOS 提供的任务管理 API 结束任务。 在这种情况下,控件将转到从 RTOS 调用task_kill()
(具象)API 的代码。