Linux在嵌入式系统中有关进程调度算法的实时性改进
引言
Linux 作为一种通用的操作系统,它最初的设计是用于桌面系统或者小型服务器。 要将Linux 用于嵌入式系统中,需要对Linux 内核作一些改进,使它能更好地为嵌入式系统服务。 在这些改进中,进程管理是相当重要的一块。
嵌入式系统的硬件设备与普通PC 有较大的差别。 由于要节省成本、降低功耗,嵌入式系统的CPU 可能不带MMU ,使用的存储设备ROM、Flach 、RAM 的容量较小,这些因素决定了需要改变Linux 进程管理,来适应存储系统方面的变化。进程管理中另一个与嵌入式系统密切相关的方面就是实时性了。尽管不是所有的嵌入式系统都需要具有实时能力,但实时性确实是嵌入式系统最重要的特点之一。 两者的关系如图1 所示。
图1 嵌入式系统与实时性的关系
目前市场上商用的嵌入式操作系统,如VxWork、pSOS 和QNX 等都具有良好的实时性能。因此本文主要着手讨论Linux 实时性方面的改造。
Linux 在实时应用中的不足之处
虽然目前Linux 内核在实时性方面有所增强,但它仍然不是实时操作系统,Linux 内核的设计关注于应用程序的吞吐量连同内核整体设计的完善。作为提高吞吐量的必然要求,Linux 的调度器试图提供一种“公平分配”策略来保证所有的进程可以均衡地享有CPU 的资源。 普通Linux 内核提供三种调度策略,分别为SCHEDRR、SCHEDFIFO、SCHEDOTHER。 其中第一个策略为实时进程的基于优先级的轮转法, schedfifo 为实时进程的先进先出算法,schedother 为非实时进程的基于优先级的轮转法。前两种为软实时进程调度策略,后者为普通实时进程调度策略。
普通时分进程调度策略保证了每个进程相对于其静态优先级可以公平地获取CPU 资源。 由于调度器按照优先级驱动的方式,因此软实时进程的优先级要高于普通进程,通常软实时进程的优先级在1000 以上而普通进程的优先级在0~999之间。 由调度器调用的goodness ( ) 函数保证实时进程先于普通进程获得CPU。
函数goodness() 如下:
static inline int goodness ( struct task struct 3 p ,int this
cpu ,struct mm struct 3 this mm)
int weight ;
weight=-1;
if (p->policy SCHED YIELD) goto out ;
/ 3 非实时进程3 /
if (p=>policy==SCHED OTHER)
{weight =p->counter ;
if ( ! weight) goto out ;
if (p-> mm==this mm !!! p->mm)
weight+=1 ;
weight+=20-p->nice ;
goto out ;
}
/ 3 软实时进程3 /
weight=1000+p->rt priority ;
goto out ;
return weight ;
} -
从上面的goodness() 函数可以看出普通Linux 内核的进程调度算法只是软实时的,并不是硬实时的。 尤其不能作为硬实时应用,主要有以下几个原因:
(1) L INUX 内核的实时进程的调度算法当中,SCHED RR 和SCHED RR 调度策略的主要不同点在于,SCHED RR 进程在一个时间片运行完以后被放到运行队列的最后。 L INUX的每一个进程都有一个调度策略,在进程描述结构task struct 中规定policy 属性。 所有的进程不管采用哪一种调度策略,都放在同一个运行队列中。这样做,就对实时进程的响应产生了影响。
(2) Linux 的内核是非抢占式的( non-preemptive) 。
(3) Linux 的进程调度策略不是完全抢占式的。
(4) Linux 的虚拟内存技术(virtual memory)增加了系统的不确定性。
(5) Linux 采用的时钟中断的精度不高。
(6) Linux 系统的一些额外操作会延迟实时进程的执行。
综上所述,不经处理的Linux 是不适合做实时操作系统的,即便是软实时,在系统负荷重的情况下也不能保证其实时性。 但通过对Linux 内核的改造完全可以提高Linux 的实时性,甚至可以满足实时的要求。
LINUX 实时性改造的实现方法
实现LINUX 的实时性一般有两种方法: 一种是对普通的LINUX 的内核的数据结构、调度函数、中断方式等进行修改使其能够处理实时进程。另一种是在LINUX 内核之外,进行实时性扩展。 也就是在普通LINUX 的基础之上再设计一个用于专门处理实时进程的内核。 为了提高LINUX 的实时性,并且使之能够在嵌入式系统中更好地满足硬实时系统的要求,采用上述两种方法结合的两种方式来提高系统的实时性。
外部实时性扩展
对LINUX 做外部实时性扩展最主要的思想是在硬件中断与原来的LINUX 内核之间增加一个实时内核。 在原来的LINUX 内核的基础上,增加一个实时内核可以解决LINUX 原有内核的关中断的问题。
对于实时内核来说,它始终不关闭硬件中断,可以接受所有的中断信号。 当中断信号需要实时进程来处理时,实时进程将抢占LINUX 内核,在RTLINUX中把原来的LINUX 内核作为一个普通进程来对待,并且它的优先级是最低的。 如果中断信号需要原来的LINUX 内核来处理,则由实时内核信号传递给LINUX 内核。 同时内核中提供一个标志位用来模拟原来的LINUX 内核的关中断情况。这个标志字在LINUX 打开中断的时候置1 ,关中断的时候置0。 实时内核在中断到来的时候检查这个标志位,如果是置1 的,那立刻将中断传给LINUX 内核,否则的话,将所有待处理的中断放入一个队列中,一直到LINUX 打开中断时才将它们一起传给内核。
内部实时性改造
- REDIce-Linux--灵活的实时Linux内核(11-12)
- linux文件系统基础(02-09)
- Linux标准趋向统一(11-12)
- linux基础技术(02-09)
- LINUX的目录树(02-09)
- 在Windows下启动Linux(02-09)