内核
多任务系统中,内核(kernel)负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务间的通信。内核提供的基本服务是任务切换。使用实时内核可以大大简化应用系统的设计,因为实时内核允许将应用分成若干个任务,由实时内核来管理他们。
调度
调度(schedulers)是内核的主要职责之一,就是决定该轮到哪个任务运行了。多数实时内核是基于优先级调度法的。每个任务根据重要程度的不同,被赋予一定的优先级。基于优先级的调度法是指,CPU总是让处于就绪态的,优先级最高的任务先运行。基于优先级的内核有2种类型:不可剥夺型和可剥夺型。
不可剥夺型内核
不可剥夺型内核(nan-preemptive kernel)要求每个任务主动放弃CPU的使用权。不可剥夺型调度法也称合作型多任务,各任务彼此合作共享一个CPU。异步事件还是有中断服务来处理。中断服务可使一个高优先级的任务由挂起态变为就绪态,但中断服务以后,CPU使用权还是回到了原来被中断的那个任务,直到该任务主动放弃CPU的使用权,一个新的高优先级的任务才能获得CPU的使用权。
不可剥夺型内核的一个优点是响应中断快。不可剥夺型内核最大的缺陷在于其响应时间。不可剥夺型内核的任务级响应时间是不确定的,无法确定何时最高优先级的任务能获得CPU的使用权,这完全取决于应用程序何时释放CPU。
总之,不可剥夺型内核允许每个任务运行,直到该任务自愿放弃CPU的使用权。中断可以打入运行着的任务。中断服务完成后,将CPU使用权还给被中断了的任务。
可剥夺型内核
当系统响应时间很重要是,须使用可剥夺型内核;因此uc/OS-II以及绝大多数商业的实时内核都是可剥夺型内核。最高优先级的任务一旦就绪,总能得到CPU的使用权。当一个运行着的任务使一个比它优先级高的任务进入了就绪态时,当前任务的CPU使用权就被剥夺了,或者说被挂起了,更高优先级的任务立刻得到了CPU的使用权。如果是中断子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的任务开始运行。
使用可剥夺型内核,最高优先级的任务何时可以执行,何时可以得到CPU的使用权,这些是可知的。可剥夺型内核使得任务级响应时间得以最优化。
使用可剥夺型内核时,应用程序不应直接使用不可重入函数。调用不可重入函数时,应满足互斥条件。这一点可以用互斥型信号量来实现,因为优先级低的和优先级高的2个任务可能会同时调用同一个函数。如果调用不可重入函数时,低优先级任务的CPU使用权被高优先级任务剥夺,不可重入函数中的数据有可能被破坏。
综上所述,可剥夺型内核总是让就绪态的高优先级的任务先运行,中断服务程序可以抢占CPU。中断服务完成时,内核让此时优先级最高的任务运行(不一定是那个被中断了的任务)。任务级系统响应时间得到了最优化,且是可知的。
可重入函数
可重入函数可以被一个以上的任务调用,而不必担心数据被破环。可重入函数任何时候都可以被中断,一段时间以后又可以运行,而相应的数据不会丢失。可重入函数或者只使用局部变量,即变量保存在CPU寄存器中或堆栈中;或者使用全局变量,则要对全局变量予以保护。
可重入函数例子:
void strcpy(char *dest, char *src)
{
while (*dest++ = *src++)
{
;
}
*dest = NULL;
}
不可重入函数例子:
int Temp;
void swap(int *x, int *y)
{
Temp = *x;
*x = *y;
*y = Temp;
}
//说明:来源于邵贝贝的《嵌入式实时操作系统uC/OX-II》一书
阅读(642) | 评论(0) | 转发(0) |