分类: 嵌入式
2009-07-28 22:31:41
第二章 实时操作系统概念
实时操作系统的特点是:如果逻辑和时序出现了偏差,将会引起严重后果。
软实时系统和硬实时系统:在软实时系统的宗旨里面,各个任务尽快的运行,而不要求限定某一个任务在多长时间内完成;在硬实时系统中,各任务不仅必须执行无误,而且要做到准时。
大多数实际的系统都是两者的结合。
前后台系统(超循环系统):应用程序是个无限的循环,循环中调用相应的函数完成相应的操作,这部分可以看成后台行为。中断服务程序处理异步事件,这部分可以看成前台行为。后台叫做任务级,前台叫做中断级。
代码的临界段(临界区):指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。
资源:任何为任务所占用的实体都可以称为资源。
共享资源:可以被一个以上任务使用的资源叫做共享资源。
互斥:为了防止数据被破坏,每个任务在与共享资源打交道时,必须独占该资源。
多任务:多任务运行的实际上是靠CPU在许多任务之间转换和调度。CPU只有一个,轮流服务于一系列任务中的某一个。
任务:一个任务,也称做一个线程,是一个简单的程序,该程序可以认为CPU完全只属于该程序自己。实时应用程序的设计过程包括如何把问题分割成多个任务。
任务的状态:
(1) 休眠态:任务驻留在内存,却不被多任务内核所调度;
(2) 就绪态:任务已经准备好,可以运行,但优先级比当前任务低;
(3) 运行态:指任务掌握了CPU的使用权,正在运行中;
(4) 挂起态(等待事件态):指任务在等待,等待某一事件的发生;
(5) 被中断状态:发生中断时,CPU会中断原来正在运行的任务,该任务就进入被中断状态。
任务切换(上下文切换):context switch实际含义是任务切换,或CPU寄存器内容切换。当多任务内核决定运行另外的任务时,它保存正在运行的任务的当前状态(context),即CPU的全部内容,这些内容保存在任务的当前状况保存区(task’s context storage area)中。入栈工作完成后,就把下一个将要运行的任务的当前状态从该任务的堆栈中重新装入CPU的寄存器,并开始下一个任务的运行,这一个过程叫做任务切换。
任务切换过程增加了应用程序的额外负荷,CPU的内部寄存器越多,额外负荷就越重。
内核:多任务系统中,内核(kernel)负责管理多个任务,或者说为每个任务分配CPU时间,并且负责任务间的通信。内核提供的基本服务是任务切换。使用内核可以大大简化应用系统的设计,因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。内核本身也增加了应用程序的额外负荷,因为内核提供的服务需要一定的执行时间。额外负荷的量取决于用户多久调用一次这类服务。
设计的好的应用系统,内核占用2%-5%,内核会增加ROM的用量,内核的数据结构会增加RAM(数据空间的用量),更主要的是,每个任务自己的栈空间,这部分占用内存相当多。
调度(schedulers):英文还有一词dispatcher,也是调度的意思。这是内核的主要职责之一,就是决定该轮到哪个任务运行了。多数实时内核是基于优先级调度的。
不可剥夺型内核(non-preemptive kernel):要求每个任务主动放弃CPU的使用权。不可剥夺型调度法也叫合作型多任务。优点:(1)响应中断块;(2)几乎无须使用信号量保护共享数据;最大缺陷:响应时间。
可剥夺型内核:最高任务一但就绪,总能得到CPU的使用权。
注意:使用可剥夺型内核的时候,应用程序不可直接使用不可重入函数。
可重入函数:可以被一个或以上的任务调用,而不必担心数据被破坏。
使用一下技术之一,可以使一个函数变成可重入:
局部变量;函数调用前关中断,调用后开中断;用信号量。
时间片轮转调度法:当2个或2个以上任务有同样的优先级时,内核允许1个任务运行事先确定的一段时间,这段时间叫做时间额度(quantum),然后切换给另一个任务。
静态优先级:任务优先级不变;
动态优先级:任务的优先级可变;
优先级反转:优先级反转问题是实时内核出现的最多的一个问题;(任务1 高于2 高于3; 3 执行,1、2挂起,事件触发1,1要等待3的资源,1挂起,3继续执行,事件触发2,2执行,3执行,1执行)
纠正的方法:在3使用共享资源时,提升3的优先级,任务完成后,恢复。
任务优先级分配:一个方法——单调执行调度法(RMS rate monotonic scheduling),用于分配任务的优先级。基于任务执行的次数。RMS假设:所有任务都是周期性的;任务间不需要同步,没共享资源,没数据交换;可剥夺型内核。
互斥条件:实现任务间通信的最简便的方法是使用共享数据结构。但必须保证任务在处理共享数据时的排它性,以避免竞争和数据的破坏。使之满足互斥的一般的方法有:关中断;使用测试并置位指令;禁止做任务切换;利用信号量。
关中断的时间不能太长,否则会影响系统的中断响应时间。
测试并置位操作:
Disable interrupts; 关中断
if (‘Access Variable’ is 0) { 如果资源不可用,标志为0
Set variable to 1; 置资源不可用,标志为1
Reenable interrupts; 重开中断
Access the resource; 处理该资源
Disable interrupts; 关中断
Set the ‘Access Variable’ back to 0; 清资源不可使用,标志为0
Reenable interrupts; 重新开中断
} else { 否则
Reenable interrupts; 开中断
/* You don’t have access to the resource, try back later; */
/* 资源不可使用,以后再试; */
}
禁止,然后允许任务切换:
void Function (void)
{
OSSchedLock();
.
. /* You can access shared data in here (interrupts are recognized) */
. /*在这里处理共享数据(中断是开着的)*/
OSSchedUnlock();
}