为什么实时操作系统(RTOS)任务必须在无限循环中执行?

10

您好,我是一个在RTOS中刚刚入门的新手。在我阅读的几乎所有文档中,都指出任务必须处于无限循环状态,但没有解释为什么。请问有人能够帮忙说明原因吗?谢谢。


1
因为否则它们将会掉落并终止或崩溃,什么也不会做。 - Martin James
这取决于RTOS。您可以拥有一个优雅地处理任务函数返回的RTOS。但是微控制器设计声称节省资源。跳过此任务结束处理可能更便宜。 - harper
你的断言是错误的。RTOS可以同时拥有无限循环任务和终止任务。任何嵌入式系统的主循环肯定是一个无限循环的例子。另一个例子:时钟任务很可能是一个无限循环。相反,发送电子邮件通知的任务很可能被实现为终止任务,在需要再次发送电子邮件时重新启动--可能是几个小时或几天后。(作为轮询待处理电子邮件的无限循环的电子邮件任务会浪费资源,因为它的任务槽可以被另一个临时任务使用。) - tonypdmtr
请勿在评论区发布答案。如果您有答案,请直接发布。 - Clifford
3个回答

10
我认为说“RTOS任务必须是无限循环”并不完全准确。更正确的说法应该是“对于许多RTOS,任务不能返回”。原因是RTOS调度程序最初调用任务时,并不设计处理任务返回的情况。如果任务返回,则RTOS调度程序可能会断言出错。
我猜测许多RTOS调度程序不处理任务返回的原因有几个。首先,在嵌入式系统中实现的任务类型中,无限循环是最典型的类型。结束的任务要少得多。其次,为了处理返回任务,RTOS调度程序可能需要更复杂。第三,RTOS设计者可能不想假设任务返回时应该执行什么操作,而希望任务设计者显式地调用适当的任务终止例程。
无限循环并不是许多不允许任务返回的RTOS的唯一解决方案。RTOS可以提供一个任务终止例程,从任务列表中删除任务,以便永远不再调度它。如果任务调用任务终止例程,则任务不必是无限循环,也不会返回到其调用者。(即,RTOS任务终止例程不返回,因此调用它的任务也不返回。)例如,FreeRTOS具有vTaskDelete(),uC/OS-II具有OSTaskDel(),用于删除不是无限循环的任务。
无限循环是嵌入式系统中常见的任务类型,因为许多嵌入式系统只是一遍又一遍地做同样的事情。许多嵌入式系统与PC不同,它们没有用户与之交互,启动和终止各种任务或应用程序。

5
他们不会,但如果任务函数运行完成,任务将被终止。
您可以选择在每次需要时实例化一个新的“运行到完成”的任务,但是实例化任务很耗时且可能是非确定性的,因此不适合硬实时响应。更有效和响应的方法是让任务等待某些阻塞对象,例如事件、信号量或计时器,以便每次需要时都可以确定性地响应。另一方面,如果您有许多不同的非实时任务只需要偶尔运行,则“运行到完成”模式可以节省资源。
但是至少需要一个任务无限期运行-如果所有东西都停止了,您的系统将什么也不做,直到电源被循环或通过看门狗定时器等方式进行复位。
RTOS实现各不相同,您需要检查您的RTOS如何处理终止线程函数。您可能需要显式终止调用以确保内核释放资源。
如果您有一个需要某种形式的控制优雅关闭的系统,则不需要将任务编码为无限循环,而是使循环有条件退出,以便任务可以根据请求终止,例如;
while( (event_flags & TERMINATE) == 0 )
{
    event_flags = eventWait( WAIT_FOREVER ) ;

    // handle events
    ...
}

4
在任何GPOS(通用操作系统)中随附的普通C语言实现(如Linux、Windows、Mac OSX)中,C运行时库负责启动任务(在GPOS上下文中可以称为线程/进程),并在任务结束时充当收集器。
意思是,crt(C运行时)将调用任务的main()函数来初始化它,当任务使用return语句返回时,控制权会传递回操作系统的crt。
在RTOS中,虽然可以使用C语言编程,但没有特定的crt实现。"启动"函数(通常用汇编语言编写)调用main。但是,此启动代码没有任何机制来收集任务的返回值,因此需要使任务在无限循环中运行,以保持控制权在任务本身内部。如果不这样做,CPU / MCU将没有任何返回地址可供使用。
但是,可以使用RTOS提供的任务管理API结束任务。在这种情况下,控制权将转移到调用了来自RTOS的task_kill()(仅代表性)API的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接