你好,这位朋友。你应该是一位初学者,在看到RTOS关于任务的一些特性时,对概念有些混淆了。 我的表达能力也有限,我尝试解释一下,看看能不能帮你理清楚它们之间的关系。
中断:从最底层来说,中断是一种硬件机制,中断的触发源是硬件。
举例:你在正常运行一段代码,此时硬件定时器中断时间到了,触发了中断。 接下来会发生的事情是,硬件机制会自动保存当前正在运行的代码的上下文(比如程序计数器、寄存器值等,在51核上体现为硬件自动入栈了返回地址), 然后跳转到中断入口,运行中断服务代码。中断代码运行结束后,再恢复之前保存的上下文,返回到原来的地方继续运行。
从整个过程来理解,中断行为正如其名,就是中断当前在做的事情,优先去处理一个更紧急的硬件事件。
任务:任务是一个软件概念,也可以理解为一种代码组织结构。
举例来说:现在CPU有两个独立的事情要处理,比如同时驱动显示屏显示动画和驱动喇叭发出声音。 但是CPU核只有一个,作为程序员的你,就得想办法,这怎么办呢?
于是你想到了一个办法,让CPU先花一小段时间(比如10ms)驱动显示屏, 再花一小段时间驱动喇叭,在这两件事情之间来回切换。因为CPU运行速度足够快,切换频率很高,这样就两个事情都兼顾了。
并行(并发)的概念:
以刚才的任务驱动为例,程序员为每个任务分配了一个小片段的运行时间,这个叫时间片。 把时间片做得足够短(比如毫秒级),由于人的反应能力有限,就感觉不到任务在两个时间片之间的切换。 从外部看起来,就好像两个任务在同时运行一样,这就是任务“并行”运行的原理。严谨地说,在单核CPU上这并非真正的并行,而是并发或伪并行。
任务优先级:
任务是软件概念,在实际运用中,任务可以分配不同的优先级。即如果任务A的优先级 > 任务B的优先级,那么当任务A就绪时,它可以打断任务B的执行。
从外部看,它的结果和中断很像,但它是软件行为,是操作系统用软件模拟中断的抢占行为。所以,高优先级任务可以看作一种“软件中断”。
对比中断和任务:
从外部看,任务和中断有一个共同的属性:抢占属性。具体体现是,它们都能打断当前正在执行的低优先级代码。这种抢占机制,正是实现“并发”的核心方式。
举个例子:我们先抛开任务,现在只有中断。在中断里定时让一个LED闪烁(对端口取反), 然后主循环代码里延时让另一个LED闪烁。当程序运行起来以后, 看到的结果是两个LED好像在同时闪烁。这就对了,抢占给人的感觉就是“并行运行”。
从它们都具有抢占性这个共同属性来看,在特定的软件设计下,中断服务程序(ISR)里的一部分工作,可以和某个高优先级任务互换角色。 比如程序员经常干的事:“把一段比较耗时的、非紧急的代码从中断中移出去,放到一个优先级较高的任务中去做”。
但是:请注意,这个“但是”才是重点。 本质上,中断属于硬件机制层,而任务属于软件调度层。它们的根本区别在于: 创建方式不一样:中断通常需要用特定的关键字(如 interrupt)告诉编译器,这是一个中断服务函数,或者需要在启动代码/链接脚本中配置中断向量表。而创建任务则是通过调用RTOS提供的API函数(如 xTaskCreate)在运行时动态创建的。 权限不对等:一定要记住:“中断是硬件机制”。具体表现为,在绝大多数RTOS中,中断可以打断任务,但任务绝对无法打断中断。中断的响应是最高优先级的硬件行为。(注意:有些系统支持中断嵌套,即高优先级中断可以打断低优先级中断的执行,但这依然是硬件机制。) 占用的资源和管理方式不一样:这涉及到系统底层规划。例如:
中断通常使用一个专用的中断栈,而每个任务都有自己独立的任务栈。 中断的响应延迟由硬件决定,非常短且固定;任务调度的延迟则由RTOS内核决定,受其他任务影响。 中断服务程序(ISR)中能调用的函数受限(通常不能调用可能导致阻塞的函数),而任务中则自由得多。
正因为这些区别,才有了那个经典的做法:“把冗余或耗时的代码从中断中移出,放到高优先级任务中执行”,以保证系统的实时性和稳定性。
希望这些解释对你有帮助!当你实际使用RTOS做一两个小项目后,对这些概念的理解会更加深刻。
|