嵌入式Linux实时性改造技术综述
2018-05-19刘剑仲宇王琦
刘 剑 仲 宇 王 琦
北京航天自动控制研究所,北京100854
Linux作为一个免费、源码开放、可裁剪且可移植的操作系统,在嵌入式领域应用广泛。2016年,Linux操作系统在嵌入式市场上占到了55%的份额,遥遥领先于其它嵌入式软件开发平台,基于Linux开发的嵌入式应用产品也非常丰富。但是,嵌入式领域的很多应用程序被要求在限定时间内能够及时响应,而Linux和Windows一样是一个通用的分时操作系统,尚不能满足高实时性任务场景的需要。目前,WindRiver公司生产的VxWorks、微软公司生产的WindowsCE等商业实时操作系统在嵌入式实时领域占据了统治地位[1-2]。
但是,这些商用实时操作系统价格昂贵、源码不开放,无法满足我国关键行业对实时操作系统的自主可控要求。另外,国内自主研发的实时操作系统主要有中航工业计算所的天脉操作系统、翼辉信息的SylixOS实时操作系统等,这些实时操作系统既不基于linux也不开源。因此,将Linux操作系统改造成实时操作系统已经成为一个重要的研究方向,国外很多科研机构都对Linux的实时性进行了深入研究,提出了一些有效的实时性改造方法。本文对主流的Linux实时改造方案进行分类总结,并比较了这些方案的优势和不足。
1 Linux内核的实时性现状[3]
Linux遵循通用操作系统的设计思想,追求高吞吐量和公平性,没有进行专门的实时性设计。虽然Linux定义了实时进程,但只能达到软实时操作系统的指标。因此,必须对Linux内核的某些体制进行改造,才能将Linux改造成一个硬实时操作系统。
1.1 内核不完全可抢占
Linux运行时分为用户态和内核态2种模式,进程通过系统调用从用户态切换到内核态。2.6版本之后的Linux内核已经支持可抢占式进程调度,Linux操作系统的实时性得到了加强,但是内核中很多由自旋锁(sPinlock)保护的临界区仍然不能抢占。
1.2 中断不可抢占
Linux操作系统把中断分为top-halves和bottom-halves两部分,当中断级别为top-halves时,操作系统会禁止其它任务抢占和中断抢占,当中断级别处于bottom-halves时,才允许其它中断打断。Linux操作系统设计之初就是作为通用操作系统供用户使用,所以在关闭中断时,系统外部事件无法得到响应,造成任务响应延迟,这在实时系统中是无法接受的。另外,如果外部I/O中断频繁发生,实时任务就很难得到调度。
1.3 时钟粒度过粗
Linux2.6内核把时钟Tick的频率提高到了1000Hz,即Linux的最小时钟粒度为1ms,对于任务周期小于1ms的实时任务来说,仍然无法满足需求。在嵌入式领域,一些周期性的实时任务对实时性要求更高,可能会达到几十μs到几百μs。如果单纯地提高时钟频率,比如106Hz,可以达到1μs的时钟分辨率,但是这样做会使得时钟中断过于频繁,导致大部分时间都浪费在上下文切换,从而严重影响操作系统的性能。
1.4 实时调度策略不足
Linux操作系统将进程分为实时进程和普通进程,实时进程比普通进程优先调度。因为Linux早期版本中的实时调度策略只有先到先服务(FIFO)和时间片轮转(Round Robin)2种实时调度策略[4],缺少基于截止期的实时调度策略[5],所以无法处理突发型计算和完成时间高度敏感的任务。Linux中普通进程的调度策略为完全公平调度算法(Completely Fair Schedule,CFS)。虽然实时进程总是优先于普通进程运行,但只能实现软实时,还不能满足高实时性要求的应用。
1.5 优先级反转
当一个低优先级的进程A抢先占用了某种临界区资源,从而导致同样需要这个资源的高优先级进程C被阻塞,而另一个不需要此临界区资源的就绪进程B(B的优先级在A与B之间)获得了CPU的控制权,于是高优先级进程C需要等待比它低优先级的进程B,这种现象被称为优先级反转[6]。优先级反转是影响Linux实时性的重要因素,严重时会导致系统崩溃。Linux内核尚未实现应对优先级反转的机制。
1.6 虚拟内存
Linux操作系统使用了虚拟内存管理方案[7-8]。由于页面交换处于最高中断优先级,且与慢速硬盘进行页面交换的耗时较长,导致输入请求无法获得及时响应。对于实时任务而言,这种内存与外存之间页面交换带来的响应时间不确定性是不能容忍的。
2 Linux实时性改造方法
经过国内外研究人员几十年的研究,提出了很多有效的Linux实时性改造方法,这些方法不断改进、融合,逐渐形成了2种典型的改进技术路线:双内核技术路线和直接修改内核技术路线[9]。
2.1 双内核技术路线
双内核的核心思想是在原Linux内核的基础上增加一个实时内核,实时任务在实时内核中运行,原来的内核作为运行在实时内核上的优先级最低的一个任务。
2.1.1 RT-Linux(Real Time Linux)[10]
美国新墨西哥州立大学在标准Linux内核上增加一个实时内核,将非实时进程以及原Linux内核作为实时内核上的低优先级进程,而其它实时进程作为实时内核上的高优先级进程,形成了RT-Linux操作系统。原Linux系统的任务可以通过FIFO或共享内存与实时任务进行通信。为了达到Linux实时化的目的,RT-Linux主要采用如下方式[11]:
1)将标准Linux内核与中断控制器隔离,禁止其任意关闭中断,系统中的所有中断均由实时内核进行处理,然后再传给原来的标准Linux内核。这样就保证了实时内核中的实时任务有效执行,不受标准Linux内核的干扰。尽管对标准Linux内核进行了这样的改动,但是原内核的数据结构完整性并没有被破坏;
2)改变时钟中断机制。RT-Linux需要粒度更细的时钟,所以它将时钟中断设置为单次触发模式,根据最近需要执行进程的时间需求,不断调整定时器的时间间隔;
3)提供用户定制化实时调度程序的机制。RT-Linux用一种灵活的做法在内部实现了一个通用的调度模块。用户可以开发符合自己具体需求的调度模块,然后加入到RT-Linux系统中;
4)RT-Linux通过共享内存、命名管道(RTFIFO)等通信机制高效率地实现了实时进程与普通进程之间的通信。
RT-Linux是一种比较有代表性的Linux实时性改造方案,但是已被WindRiver公司收购并商业化。RT-Linux系统结构图见图1。
图1 RT-Linux结构图
2.1.2 RTAI(Real-Time Application Interface)[12]
意大利米兰理工学院研制的RTAI源于RT-Linux,它在设计思想上和RT-Linux完全相同。RTAI和RT-Linux最大的不同在于它在Linux上定义了一组实时硬件抽象层RTHAL或者ADEOS,接管了Linux对硬件平台的控制权。这种方式能够避免大量修改Linux内核代码,便于RTAI移植到新版Linux内核上。RTHAL和ADEOS这2种技术本质上是相同的,只是因为版权问题,使得RTAI后来的实现转向了ADEOS。RTAI按照模块机制设计,它的实时内核有3个基本组成部分:中断分发器、实时调度器和实时通信器。如上面提到的实时调度器,也可以加载FIFO,共享内存等实现实时通信器。基于模块机制的设计使得RTAI可以根据实际要求进行扩展和裁剪。另外,RTAI虽然实时性能较好、移植难度小且开源,但是更新速度比较慢,对ARM硬件平台支持也不够。RTAI系统结构见图2。
图2 RTAI体系结构图
2.1.3 Xenomai[13]
Xenomai和RTAI的实现本质上是相同的。 Xenomai不能绕过ADEOS与硬件交互,而RTAI可以,所以Xenomai的中断延迟长于RTAI。但是Xenomai更加关注的是用户态下的实时性、提供与VxWorks、RTAI及POSIX等多套与主流商业实时操作系统兼容的API接口。Xenomai的目标是将那些依赖商业实时操作系统的应用程序尽可能平滑地移植到GNU/Linux环境。最后,Xenomai社区活跃,紧跟Linux内核最新官方版本,对硬件支持广泛,支持多种架构,在Linux实时化改造方案中也是一个研究热点。Xenomai系统结构图见图3。
图3 Xenomai系统架构图
2.2 直接修改内核技术路线
直接修改内核技术路线的共同思想是针对Linux内核制约实时性的因素,直接修改Linux内核源代码,使其本身具有实时能力。
2.2.1 RED-Linux(Real-Time and Embedded Linux)[14]
加州大学Irvine分校开发的RED-Linux是一个软实时操作系统。RED-Linux从RT-Linux那里借鉴了软件模拟中断管理器的机制,并且提高了时钟中断频率。在实现内核可抢占之后,RED-Linux为Linux又添加了3个特性:1)源自于RT-Linux的高精度时钟;2)软件模拟中断管理器;3)通用实时调度器框架。它同时支持3种类型的进程调度算法:基于时间驱动的进程调度算法(Time-driven Scheduling)、基于优先级的进程调度算法(Priority-driven Scheduling)和基于CPU的进程调度算法(Share-driven Scheduling)[15-16]。RED-Linux的设计目标是提供一个可以支持各种调度算法的通用调度框架,该系统为每个任务增加了Priority(任务优先级)、Start-Time(任务开始时间)、Finish-Time(任务完成时间)和Budget(任务在运行期间所要使用的资源多少)这几项属性,并将它们作为进程调度的依据。通过合理地调整这些属性的取值及调度程序按照什么样的优先顺序来使用这些属性值,从而实现所有的调度算法。但是,Red-Linux是一个软实时操作系统,所以在硬实时指标实现方面还需要进一步完善。RED-Linux系统结构见图4。
图4 RED-Linux调度框架图
2.2.2 Kurt-Linux(Kansas University Real-Time Linux)[17]
美国Kansas大学开发的Kurt-Linux是第一个支持标准Linux系统调用的实时系统,它可以提供μs级的实时精度。Kurt-Linux将系统分为3种状态:正常态、实时态和混合态。在正常态时,它采用普通的Linux的调度策略,此时与标准Linux内核相同,但是时钟粒度由时钟中断机制UTIME决定,可以达到μs级。在混合态时,系统同时运行实时任务和非实时任务,但是此时内核不能被抢占,不能完全保证实时任务的及时调度。实时态时只调度实时任务,普通任务被挂起。Kurt-Linux相对于RT-Linux的一个优点就是支持Linux系统自身的系统调用。但是,由于它在实现上只是简单地用一个简单的时间驱动调度器替代原来的Linux调度器,造成实时进程的调度很容易受到其它非实时任务的影响。目前Kurt-Linux的应用比较广泛,比如多媒体播放软件、ARTS(ATM Reference Traffic System)等。
2.2.3 RT-patch(Realtime Preemption Patch)
实时抢占补丁(RT-patch)是由Ingo Molnar和Thomas Gleixner更新维护[18-19],由开源自动化开发实验室(OS-ADL)对其稳定性测试,OS-ADL于2015年10月将RT-patch控制权转移给了Linux基金会。每隔2个Linux版本,RT-patch就会更新一次,目前,RT-patch近80%的内容被官方Linux项目接收[20],融入到发行版的Linux内核中。和其它在标准Linux内核中增加实时抢占方法不同,RT-patch在原有的低延迟补丁和抢占补丁的基础上,加入中断线程化、高精度时钟、优先级继承和互斥锁替换自旋锁等新的特性,将Linux内核修改成完全可抢占式内核,使其具有硬实时能力。RT-patch相比于双内核方案最大的优势在于它遵循POSIX标准,使用该补丁时,实时系统的应用程序和驱动程序与非实时系统的应用程序和驱动程序差异很小。因此,在使用该补丁的平台上做相应的开发比双内核机制的方案更容易。另外,该补丁与硬件平台相关性小,可移植性高,拥有庞大的社区支持,如果开发人员编写一个实时应用程序,不需要知道太多关于RT-patch的知识,也不需要任何特殊的库和API,只需要标准的C库、Linux驱动程序和POSIX程序即可。
2.3 Linux实时性改造技术比较
除上述几种实时性Linux产品技术方案外,还有德州大学和马萨诸塞大学的Qlinux、TimeSys公司的TimeSys Linux及卡耐基梅隆大学的Linux/RK等,但是均未得到广泛应用,受到的关注程度较小,因此本文不再赘述。
通过对上文各种Linux实时性改造技术的研究探讨,论述了各种Linux实时性改造技术的基本原理和实现细节。表1对各种Linux实时性改造技术的优缺点进行了对比。
表1 Linux实时性改造技术优缺点比较
3 总结与展望
设本文在分析Linux内核实时性不足的基础上,论述了6种主流的Linux实时性改造技术,并分别对这6种Linux实时性改造技术的适用性、优缺点进行分析比较。从现阶段研究成果来看,RTAI、Xenomai和RT-patch等Linux实时性改造技术的研究相对比较深入,在工程领域也得到了成熟应用。而由于RT-patch已经得到了Linux的官方认可,其近80%的内容已经加入了Linux内核主线,所以在RT-patch的助力下,未来Linux内核本身将会向满足硬实时要求的方向发展。向用户提供可配置的实时性备选方案。
参 考 文 献
[1] 王金刚. 基于VxWorks的嵌入式实时系统设计[M]. 北京:清华大学出版社, 2004:1-14.
[2] 王学龙. 嵌入式VxWorks系统开发与应用[M]. 北京:人民邮电出版社, 2003:1-15.
[3] Shui Oikawa, Rag Rajkumar. Linux/RK:A Portable Resource Kernel in Linux [J]. IEEE Real-Time Systems Symposium Work-In-Progress, 1998, 43-47.
[4] Ankita Garg. Real-Time Linux Kernel Scheduler [J]. Linux Journal. 2009, Aug 01.
[5] Dario Faggioli, Fabio Checconi, Michaei Trimarchi and Claudio Scordino. An EDF Scheduling Class for the Linux Kernel [C]. Proceedings of Eleventh Real-Time Linux Workshop, 2009, 197-204.
[6] Luil Sha, Ragunathan Rajkimar, John Rlehoczky. Priority Inheritance Protocols:An Approach to Real-Time Synchronization [J]. IEEE Transactions on Computers, 1990:1175-1184.
[7] Matt Mackall. slob: Introduce the SLOB Allocator[EB/OL]. http//lwn.net/Articles/157944/. 2005, Nov 1.
[8] 杨峰. 基于Linux内核的动态内存管理机制的实现[J]. 计算机工程, 2010,36(9):85-88.(Yang Feng. Implementation of Dynamic Memory Management Mechanism Based on Linux Kernel[J]. Computer Engineering, 2010, 3-6(9):85-88.)
[9] Kushal Koolwal. Myths and Realities of Real-Time Linux Software Systems[C]. Proceedings of Eleventh Real-Time Linux Workshop, 2009:13-18.
[10] Barabanov M. A Linux-based Real-time Operating System:(master thesis) [J]. New Mexico:New Mexico Institute of Mining and Technology,1997.
[11] 吴一民. RT-Linux的实时机制分析[J]. 计算机应用, 2002, 22(12):100-111.(Wu Yimin. Analysis of Real-time Mechanism of RT -Linux[J]. Computer Application, 2002, 22(12):100-111.)
[12] Karim Yaghmour. The Real-Time Application Interface [C]. In Proceedings of the Linux Symposium, Boston, Massachusetts,USA, 2001, 245-260.
[13] Intel Corportation. Hard Real Time Linux Using Xenomai on Intel Multi-Core Processors [Z]. 2009.
[14] Lin Kwei-Jay, Wang Yuchung. The Design and Implementation of Real-Time Schedulers in RED-Linux [J]. Proceedings of the IEEE, 2003, 91(7):1114-1129.
[15] 张焕强. 基于Linux的实时系统[EB/OL]. http://www.ibm.com/developerworks/-cn/linux/embed/l-realtime/index.html, 2003.
[16] 赖娟. Linux内核分析及实时性改造[D]. 电子科技大学, 2007.
[17] Srinivasan B. A Firm Shelf Hard Ware and Free Real-time System Implementation Using Commercial Off-the-software:(master thesis) [J]. American:University of Kansas, 1998.
[18] Betz W, Cereia M, Bertolotti C. Experimental Evaluation of the Linux RT Patch for Real-time Applications[C]//Proc. of IEEE Conference on Emerging Technologies & Factory Automation,2009:1-4.
[19] William von Hagen. Real-time and Performance Improvements in the 2.6 Linux Kernel [J]. Linux Journal, 2005, (134):8-13.
[20] 吴章金. Linux 实时抢占补丁的研究与实践[D]. 兰州:兰州大学, 2010.