网站搜索:
第5节 嵌入式操作系统的基本概念
文章出处:与非网
更新于2008-05-15 11:07:34

任务
一个任务,也称作一个线程,是一个简单的程序,该任务可以认为CPU完全只属该任务自己。实时应用程序的设计过程,包括如何把问题分割成多个任务,每个任务都是整个应用的某一部分,每个任务被赋予一定的优先级,有它自己的一套CPU寄存器和自己的栈空间。

 

 
多任务
多任务运行的实现实际上是靠CPU(中央处理单元)在许多任务之间转换、调度。CPU只有一个,轮番服务于一系列任务中的某一个。
多任务运行使CPU的利用率得到最大的发挥,并使应用程序模块化。在实时应用中,多任务化的最大特点是,开发人员可以将很复杂的应用程序层次化。
资源与共享
任何为任务所占用的实体都可称为资源。资源可以是输入输出设备,例如打印机、键盘、显示器,资源也可以是一个变量,一个结构或一个数组等。
可以被一个以上任务使用的资源叫做共享资源。为了防止数据被破坏,每个任务在与共享资源打交道时,必须独占该资源。
任务的状态
休眠态相当于该任务驻留在内存中,但并不被多任务内核所调度。
就绪意味着该任务已经准备好,可以运行了,但由于该任务的优先级比正在运行的任务的优先级低,还暂时不能运行。
运行态的任务是指该任务掌握了CPU的控制权,正在运行中。
挂起状态也可以叫做等待(WAITING)事件态,指该任务在等待,等待某一事件的发生,(例如等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用,等待定时脉冲的到来或等待超时信号的到来以结束目前的等待,等等)。
发生中断时,CPU 提供相应的中断服务,原来正在运行的任务暂不能运行,就进入了中断状态。

 

 
任务切换
任务切换(Context Switch or Task Switch)
当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(Context),即CPU寄存器中的全部内容。这些内容保存在任务的当前状况保存区(Task’s Context Storage area),也就是任务自己的栈区之中。入栈工作完成以后,就是把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行。这个过程叫做任务切换。
任务切换过程增加了应用程序的额外负荷。CPU的内部寄存器越多,额外负荷就越重。做任务切换所需要的时间取决于CPU有多少寄存器要入栈。
老板※行政※教师※工程师※Task Graph
内核(Kernel)
多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。
内核提供的基本服务是任务切换。之所以使用实时内核可以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。
内核本身也增加了应用程序的额外负荷,代码空间增加ROM的用量,内核本身的数据结构增加了RAM的用量。但更主要的是,每个任务要有自己的栈空间,这一块吃起内存来是相当厉害的。
内核本身对CPU的占用时间一般在2到5个百分点之间。
单片机一般不能运行实时内核,因为单片机的RAM很有限。通过提供必不可缺少 的系统服务,诸如信号量管理,邮箱、消息队列、延时等,实时内核使得CPU的利用更为有效。
调度(Scheduler)
调度就是要决定该轮到哪个任务运行了。
多数实时内核是基于优先级调度法的。每个任务根据其重要程度的不同被赋予一定的优先级。
基于优先级的调度法,指CPU总是让处在就绪态的优先级最高的任务先运行。
究竟何时让高优先级任务掌握CPU的使用权,有两种不同的情况,这要看用的是什么类型的内核,是不可剥夺型的还是可剥夺型内核。
不可剥夺型内核
不可剥夺型内核(或非抢占式内核,Non-Preemptive Kernel)
不可剥夺型内核要求每个任务自我放弃CPU的所有权。
不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。
异步事件还是由中断服务来处理。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。
不可剥夺型内核运行原理
任务正在运行
中断到来,中断原来任务
执行中断服务子程序,使一个高优先级任务进入就绪状态由于是不可剥夺型内核,低优先级任务未执行完毕,高优先级任务不能立即执行
中断返回
继续执行原来任务
任务执行完毕,控制权交给高优先级、已就绪任务
高优先级任务开始执行

 


不可剥夺型内核缺点
不可剥夺型内核的最大缺陷在于其响应时间。高优先级的任务已经进入就绪态,但还不能运行,也许要等很长时间,直到当前运行着的任务释放CPU。
不可剥夺型内核的任务级响应时间是不确定的,不知道什么时候最高优先级的任务才能拿到CPU的控制权,完全取决于应用程序什么时候释放CPU。
可剥夺型内核
当系统响应时间很重要时,要使用可剥夺型内核(或抢占式内核,Preemptive Kernel)。
最高优先级的任务一旦就绪,总能得到CPU的控制权。
当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。
如果是中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的那个任务开始运行。
可剥夺型内核运行原理
低优先级任务正在运行
中断到来,中断当前任务
执行中断服务,把另一个任务置为高优先级、就绪状态
中断服务完成,退出中断进入新的优先级更高的任务
新任务执行
新任务执行完毕,控制权还给原来的任务
继续执行原来的任务

 

 
可剥夺型内核
使用可剥夺型内核,最高优先级的任务什么时候可以执行,可以得到CPU的控制权是可知的。
使用可剥夺型内核使得任务级响应时间得以最优化。
使用可剥夺型内核时,应用程序不应直接使用不可重入型函数。调用不可重入型函数时,要满足互斥条件,这一点可以用互斥型信号量来实现。如果调用不可重入型函数时,低优先级的任务CPU的使用权被高优先级任务剥夺,不可重入型函数中数据有可能被破坏。
可重入性(Reentrancy)
可重入型函数可以被一个以上的任务调用而不必担心数据的破坏。
可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。
可重入型函数只使用局部变量,即变量保存在CPU寄存器中或堆栈中。如使用全局变量,则要对全局变量予以保护。
可重入型函数

不可重入型函数

任务调度策略-抢占方式

任务调度策略-时间片轮转方式


任务优先级
每个任务都有其优先级。任务越重要,赋予的优先级应越高。
 静态优先级
  应用程序执行过程中诸任务优先级不变,则称之为静态优先级。在静态优先级系统中,诸任务以及它们的时间约束在程序编译时是已知的。
 动态优先级
  应用程序执行过程中,任务的优先级是可变的,则称之为动态优先级。实时内核用之避免出现优先级反转问题。
任务优先级举例


优先级翻转与优先级继承
如果完全按照优先级来进行任务调度,则会发生如下情况:
 低优先级任务TaskB首先运行,调用 semTake()获得资源;
 高优先级任务TaskA就绪运行,调用semTake()申请资源,被阻塞;
 只有当taskB调用semGive()释放资源后,taskA才能继续运行
解决方法
Priority inheritance protocol(优先级继承协议)
 让低优先级任务提高任务优先级,提高到和被阻塞高优先级任务同样的级别。
Priority ceiling protocol (优先级限高协议).
 低优先级任务这次不是获得高优先级相同的优先级,而是获得某个预先设置好的优先级。而这个预先设置好优先级肯定不会比当前所有的存在的优先级低。在实现中,这个优先级一般被设置为实时系统中最高可能的优先级。

<<上一节   下一节>> 



关于OpenHW | OpenHW使用说明 | FAQ | 相关法律 | 版权声明 | 网站地图
联系邮件:xiaoquan@eefocus.com  联系电话: 010-58859035-8012
Powered by eefocus.com