上半部在屏蔽中断情况下完成必要的功能,如清除中断标志等,时间尽可能短,从而可更快地响应更多的中断请求。下半部在开中断的情况下执行不急需且耗时的操作,在适当时候再被调度运行。
中断处理程序的设计对系统的时间性能有很大的影响,也应该对中断响应时间进行测试验证。中断响应时间可以用下图6(王蕾,等,2011)中的T4-T3来近似表示。
中断产生上下文保存中断返回任务重新调度新任务CPU获取中断向量T3用户ISRT4时间
图6 中断响应时序图
3.2 嵌入式Linux的实时化方法
为使嵌入式Linux应用于实时场合,Linux实时化实现方法主要可以分为内核内部改造和内核外部实时扩展两类(杨卫辉,2005): (1) 内核内部实时改造
Linux内核的内部实时改造就是对内核原有的数据结构、调度算法、中断方法等进行修改,使其能及时处理实时任务。下面从时间机制、抢占机制和调度算法三方面进行分析。
首先,时钟机制方面的改造主要是细化时钟粒度(Robert Love,2004)。Linux系统中,每个时钟中断发生时,由schedule()、do_timer()、ret_from_sys_call()三个函数共同完成进程的选择和切换(杨卫辉,2005)。可以看出,定时器的频率直接影响系统响应速度和上下文切换的系统开销。Linux 2.4内核定时器提供的10毫秒的调度粒度,远远达不到实时任务对响应速度的要求。Linux 2.6内核中,时钟中断频率已被提高到1000Hz,虽增加了一定的系统开销,却加快了调度响应时间。
其次,内核抢占性方面的改造有在内核中增加抢占点和将内核修改成为抢占式内核两种方法(杨卫辉,2005;杨中良,等,2008)。其一,抢占点就是内核在某个合适的地方调用schedul()函数,以检查是否有高优先级的任务已处于就绪状态,并让这个高优先级任务运行。其二,抢占式内核就是允许处于系统调用状态的用户进程被高优先级的实
11
时进程所抢占,但在临界区内不能抢占。它不存在最大路径问题,但要考虑采取关中断或使用新号量来保护临界区(杨中良,等,2008)。
最后是改进优化实时调度算法。Linux 2.6内核重写了调度器,并采用O(1) 调度算法,但它的实时调度算法还是可以再改进的(杨卫辉,2005;王海珍,等,2010;关斌斌,等,2010)。例如MontaVista Linux直接修改了Linux内核代码中的调度机制和算法。 (2) 外部实时扩展
外部实时扩展通常是指采用双内核结构,加入实时内核模块(黄廷辉,等,2002;杨卫辉,2005)。双内核策略既增强了实时功能,又充分兼容了标准的Linux,将代码的修改降低到最小。同时,由于有效优先级通用框架调度法的采用,使得用户可以方便地选择不同的调度策略。程序甚至可以根据需要动态地改变调度策略。下图7是Linux双内核结构示意图。
Linux任务Syscall标准Linux内核Linux任务RT实时任务Linux任务FIFO用户级实时任务内核级实时内核硬件设备
图7 Linux双内核结构示意图
3.3 MontaVista Linux的实时性分析
MontaVista一直坚持在开放和兼容社区内核发展的前提下,发展和开发Linux的实时技术,并应用在MontaVista Linux产品里面。pro 5.0使用稳定和全新的2.6.18内核,加入了内核和用户态的实时技术(何小庆,2007),包括支持Priority Queuing,Priority Inheritance,Robust Mutexs和新的HR Ktimers等,并支持ARM Jazelle(java硬件加速虚拟机优化技术,可提高java应用的启动运行及反应速度)。pro 5.0还包含了Montavista以前在CEE3.1和Mobilinux 4里面使用的XIP技术,可以提高Linux系统引导速度。下面将从内核时钟机制、可抢占性内核和实时调度程序三方面对MontaVista Linux的实时
12
性分析。 (1) 内核时钟机制
在Linux 2.6标准内核之前的版本中,时钟分辨率为10毫秒,非常粗糙。MontaVista Linux在3.1版本中加入了毫秒级的定时时钟。在Linux 2.6中,时钟粒度从10ms提升到1ms,一定程度上提高了实时性能(Robert Love,2004;张帆,等,2011)。
MontaVista Linux实时抢占内核的时钟系统重新进行了设计,实现了高精度定时器。时钟精度不再依赖jiffies,使POSIX定时器和nanosleep精度由具体硬件所能提供的精度决定,使得gettimeofday能够提供实时系统所需的精确时间值。 (2) 可抢占性内核
绝大多数实时操作系统内核都使用基于优先级的可抢占式调度算法,而Linux的内核是非抢占式的。Linux有用户态和核心态两种模式,当进程运行在用户态时,很容易被优先级更高的进程抢占,但当它进入核心态时,则其他的用户态的进程优先级再高,也不能抢占处于核心态的低于优先级的普通进程(杨卫辉,2005)。即使是Linux 2.6标准内核也不是真正的 RTOS,仅是在内核代码中插入抢占点,从而实现一定程度上的抢占,但是并不是所有的内核代码段都可以通过插入抢占点来实现抢占(吴东超,2010)。同时Linux2.6内核中普遍使用自旋锁(spin lock),也导致了抢占延时。
MontaVista Linux 2.1版本已经实现了Preemptible kernel,从而根本上改变了传统Linux无论有那个进程和线程占有多少时间不能抢占和按照优先级调度的历史,后来成为标准Linux的一部分(何小庆,2007)。Pro 5.0已实现了内核的完全可抢占,实时内核临界区用互斥锁(mutex lock)和抢占锁(preempt lock)替换原来自旋锁(spin lock)来进行保护,使得在临界区内的执行也可被抢占。为了实现抢占锁,在Linux的进程结构task_struct中增加了一项抢占计数器preempt_count(杨中良,等,2008)。当进程执行时,抢占锁时抢占计数器加1;当进程释放时,抢占锁时抢占计数器减1;如果进程的抢占计数器值为0,则该进程在内核态下执行时可以被抢占。只有当线程想访问一个其他线程正在访问的临界区时,才被调度至睡眠,直到所保护的临界区被释放时被唤醒。 (3) 实时调度程序
同样地,MontaVista Linux 2.1版本已经实现了Real time scheduler。MontaVista Linux的实时任务调度程序是符合GPL协议且完全开源的,图8是其示意图:
13
Linux KernelContext SwitchMontaVista Real-Time Scheduler128 Fixed Priorities, Low OverheadNo Real Time ThreadStandard Linux SchedulerExhaustive, Fairness-Based图8 MontaVista Linux实时调度程序示意图
Real-TimeThreadOtherThread
如上图所示,实时调度程序运行在标准调度程序之前,通过SCHED_FIFO和SCHED_RR策略负责管理调度实时进程。当没有实时任务时,实时调度程序迅速地把控制权交给标准调度程序,几乎不影响标准调度程序的性能。进程的优先级可以被配置成99到2047(默认是128)。
另外,Linux 2.6重写了调度器和相关支持代码,采用了O(1)的调度算法,大大提高了进程调度的效率(Robert Love,2004)。 3.4 本章小结
本章介绍了衡量嵌入Linux的实时性能指标,详细阐述了任务切换时间和中断响应时间两个关键时间参数。从Linux内核内部改造和外部扩展两个角度介绍了主要的实时化方法。最后从内核时钟机制、可抢占性内核和实时调度程序三方面分析了MontaVista Linux的实时性。
14
4 MontaVista Linux时间性能测试方案设计
前面,已对嵌入式Linux的时间性能进行了比较深入的分析,为了对其有直观的认知和理解,接下来将从任务切换时间和中断响应时间两方面对MontaVista Linux的实时性能设计测试方案进行验证。本章先总体介绍整个测试方案,再阐述常用的几种系统实时性能测试方法和工具,最后详细介绍实验平台和测试方案的设计。 4.1 总体测试方案介绍
为了对MontaVista Linux的实时性能进行测试验证,测试方案的设计包括两部分:实验平台设计与时间性能测试方案设计: (1) 实验平台设计
实验平台设计包括硬件平台和软件平台。硬件平台指的是整个测试系统平台中所有硬件的有机组成,软件平台则是指所有软件的有机组成。在本文中,硬件平台由有开发主机、DM6441目标板、串行通信接口与示波器组成;软件平台由开发主机的开发环境、串口终端软件、目标板软件系统和测试程序等组成。 (2) 时间性能测试方案的确定
对MontaVista Linux的实时性能进行测试验证,主要是对任务切换时间和中断响应时间两个关键时间参数,分别采用软件编程和结合示波器的方式进行测试。实际上,对系统的实时性能测试已有一些比较好的测试工具,如Timepegs,Intlat,Schedat,Amlatt和Lmbench等,但这些工具大部分都是从内核层测试,需要对测试工具进行相应移植并整合到内核中,这对系统调试与测试工作带来了较大的挑战和困难(李庆诚,等,2005)。因此,本文主要是从用户层设计相应的测试程序对MontaVista Linux的时间性能进行测试。
对于任务切换时间测试,创建两个进程,并在两进程间通过管道发送和读取令牌,阻塞引起任务切换,然后通过编程读取计算系统时间和示波器观测GPIO引脚电平持续时间,从而测得任务切换时间。对于中断响应时间测试,将一个GPIO引脚置为输出,另一个置为中断输入,两引脚相连。通过控制引脚输出电平产生中断,通过记录中断响应前后时间来测得中断响应时间。
4.2 常用的几种系统实时性能测试方法和测试工具
人们在研究和评估Linux的时间性能过程中,提出了各种测试方法,并开发相应的测试工具。目前主流的测试方法有Rhealstone法,进程分派延迟时间法和三维表示法等
15