-
扩充“非运行状态”-ri5cy_user_manual
资源介绍
1.6 扩充“非运行态”
到目前为止所有用到的示例中,创建的每个任务都只顾不停地处理自己的事情而没
有其它任何事情需要等待——由于它们不需要等待所以总是能够进入运行态。这种”不
停处理”类型的任务限制了其有用性,因为它们只可能被创建在 低优先级上。如何它
们运行在其它任何优先级上,那么比它们优先级更低的任务将永远没有执行的机会。
为了使我们的任务切实有用,我们需要通过某种方式来进行事件驱动。一个事件驱
动任务只会在事件发生后触发工作(处理),而在事件没有发生时是不能进入运行态的。
调度器总是选择所有能够进入运行态的任务中具有 高优先级的任务。一个高优先级但
不能够运行的任务意味着不会被调度器选中,而代之以另一个优先级虽然更低但能够运
行的任务。因此,采用事件驱动任务的意义就在于任务可以被创建在许多不同的优先级
上,并且 高优先级任务不会把所有的低优先级任务饿死。
阻塞状态
如果一个任务正在等待某个事件,则称这个任务处于”阻塞态(blocked)”。阻塞态是
非运行态的一个子状态。
任务可以进入阻塞态以等待以下两种不同类型的事件:
1. 定时(时间相关)事件——这类事件可以是延迟到期或是绝对时间到点。比如
说某个任务可以进入阻塞态以延迟 10ms。
2. 同步事件——源于其它任务或中断的事件。比如说,某个任务可以进入阻塞
态以等待队列中有数据到来。同步事件囊括了所有板级范围内的事件类型。
FreeRTOS 的队列,二值信号量,计数信号量,互斥信号量(recursive semaphore,
递归信号量,本文一律称为互斥信号量,因为其主要用于实现互斥访问)和互斥量都可
以用来实现同步事件。第二章和第三章涵盖了有关这些的详细内容。
任务可以在进入阻塞态以等待同步事件时指定一个等待超时时间,这样可以有效地
实现阻塞状态下同时等待两种类型的事件。比如说,某个任务可以等待队列中有数据到
来,但 多只等 10ms。如果 10ms 内有数据到来,或是 10ms 过去了还没有数据到来,
这两种情况下该任务都将退出阻塞态。