[1]石伟民. 基于ARM9的嵌入式实时linux系统平台构建[D].中北大学,2010.
现在的实时嵌入式系统几乎都是由实时操作系统支持的。工业应用的嵌入式系统对实时处理的需求是多种多样的,没有那一套嵌入式系统可以应用在所有的工业测控中。对于一些具体的工程应用,只有特定的嵌入式系统来为其服务才能保证其实时和高效。
所谓实时,就是一个特定任务的执行时间必须是确定的,可预测的。它要保证的不仅仅是速度快,更要求其结果是确定的。
Linux 本身并不是一个实时系统,但是可以利用 Linux 具备的特性对 Linux 进行实时化改造,要将 Linux 用于嵌入式实时领域,需要对 Linux 内核进行实时化改造。
一个系统的实时性能与硬件、操作系统和应用程序三方面都有关系,当硬件条件确定后,嵌入式系统的性能主要由操作系统来决定,其中实时内核起着关键作用。
1. 硬件平台的选用和设计
2. linux操作系统的实时化设计
3. 对设备驱动的开发和系统的移植
实时化改造:1. 定时器、2. 中断改进、3. 任务调度改进、4. 设备驱动方面
测试实时性:主台软件和应用软件通讯,请求某类数据应用软件和嵌入式平台通讯,要求读取某类数据嵌入式平台通过驱动相关模块读取所要求的数据。然后逐次返回。其中主台软件和应用软件都相同,只有嵌入式平台不同。
[1]刘涛. 一种嵌入式实时Linux的设计与实现[D].电子科技大学,2007.
标准 Linux 是一个通用操作系统,将它应用于实时环境有许多缺点和不足:特别是 Linux 常常关闭中断,其他问题包括分时的调度、虚拟文件系统的时间不确定性、缺乏高精度的计时器等。
通常,对 Linux 进行实时化,主要有以下两种技术方案: 1、对标准 Linux 内核进行直接修改,优化 Linux 的实时性能; 2、采用双内核方案,增加一个实时内核,有实时要求的任务都在这个实时内核上运行,标准 Linux 内核作为这个实时内核优先级最低的一个进程。
方案一:
最主要的就是提高时钟精度,解决关中断和内核态不能被抢占的问题等等。
1. RED-Linux
RED-Linux 是加州大学 Irvine 分校开发的实时 Linux 系统,它将对实时调度的支持和 Linux 很好地实现在同一个操作系统内核中。
- 时钟频率与关中断问题,中断问题的解决。从 RTLinux 借鉴了软件模拟中断管理器的机制,并且提高了时钟频率。当中断来临时,RED-Linux 的中断模拟程序仅仅是简单地将到来的中断放到一个队列中进行排队,并不执行真正的中断处理程序。
- 内核态不可被抢占问题的解决。RED-Linux 在内核的很多函数中插入了抢占点原语,使得内核在进程态时,也可以在一定程度上被抢占。
- 调度算法的改进。为每个任务增加了属性,作为进程调度的依据,通过调整这些属性的取值,调度程序就可以按照一定的优先顺序来使用这些属性值从而实现所有的调度算法(实时调度框架)。
2. Hard-hat Linux
Hard-hat Linux 是 MontaVista 公司所发布的一款主要面向各种嵌入式应用的 Linux。
对于内核态抢占过程进行了改进。
其最大贡献在于:为了解决 Linux 在内核态不可被抢占的问题,它开发了一种抢占式的内核(通过修改自旋锁的宏定义以及中断返回处理代码)。
3. Kurt-Linux
Kurt-Linux 由 Kansas 大学开发,它可以提供微秒级的实时精度。不同于 RTLinux 单独实现一个实时内核的做法,Kurt -Linux 是在通用 Linux 系统的基础上实现的,它也是第一个可以使用普通 Linux 系统调用的基于 Linux 的实时系统。
在系统所支持的时钟精度上做了改进,将 Linux 的调度器用一个简单的时间驱动的调度器所取代,其实时进程的调度容易受到其它非实时任务的影响。将实时时钟编程为单次触发的状态,然后利用 CPU 的时钟计数寄存器提供高达 CPU 时钟频率的定时精度。
Kurt-Linux 将系统分为三种状态:正常态、实时态和混合态,在正常态时它采用普通的 Linux 的调度策略,在实时态时只运行实时任务,在混合态实时任务和非实时任务都可以执行,实时态可以用于对实时性要求比较严格的情况。
可以使用 Linux 系统自身的系统调用
提供对于硬实时的支持,具体办法有:提高时钟精度、解决关中断和内核态不能被抢占的问题,代表系统有 RTLinux、Kurt-Linux,其实大部分实时 Linux 都使用了类似与 RTLinux 的提高时钟精度和软件中断管理器的思想。总的来说,内核支持硬实时和使用传统的 Linux 系统调用之间存在着矛盾,但由于软件模拟终端控制器、提高时钟精度以及可抢占内核等思想的引入,这个矛盾慢慢地得到化解。
在实际的系统中,具体使用哪种实时 Linux 技术,需要根据具体的系统需求而定。如果目标系统是像机床控制或者导弹飞行姿态控制这样的硬实时系统,那基于 RTLinux 是一个不错的方案;如果一个系统对于实时性的要求不是那么严格,但又不是软实时系统,那么可以借鉴Kurt-Linux 的思想以及一些为了提高 Linux响应速度而提出的可抢占内核的想法;如果目标系统是一个像实时多媒体系统这样的软实时应用,或者一个希望能够在高负载状态下提供更好的吞吐率的服务器系统,那么 RED-Linux 的思想提供了很好的参考。
[1]朱春飞. 基于Linux操作系统的实时性研究和改进[D].西安电子科技大学,2009.
Linux 实时性能不佳的主要原因:
Linux 本身作为通用操作系统,设计目标是取得最优平均性能。
- 内核不可抢占的问题。高优先级的进程只能等待低优先级的进程完成系统调用,导致实时应用响应时间的不可预测性。
- 内存换出的问题。当一个实时任务被换出内存,当再次调度它运行时,必须经历一个时间不确定的换入过程。
- 关中断问题。为了保护临界区资源,Linux 会长时间关中断,这样会加大中断延迟,阻塞高优先级的中断立即被处理。
- 时钟精度问题。操作系统必须对时间精度和时钟中断处理的时间开销进行折中考虑,时间精度越高,意味着时钟中断越频繁,而花在中断处理上的时间越多,Linux 通过硬件时钟编程产生周期为 100Hz 的时钟中断,因此任务调度的时间精度最高能达到 10ms,无法满足一些对时间精度要求苛刻的实时应用。
- 实时任务没有质量保证。虽然 Linux 内核具有一定的实时性特征,但是还不能达到硬实时的要求,Linux 允许一个进程被定义为实时进程,但对于这种实时进程,调度器只是简单地给它赋予一个比非实时进程优先级高地优先级,而没有保证对实时进程的响应时间。
Linux 实时性能改进的主要方法:
- 增强Linux内核抢占性。当进程运行在内核态下时,有两种实现 Linux 内核抢占的思想:一种是完全剥夺抢占方式,另一种是插入抢占点的方式。
- 细化 Linux 时钟粒度。标准 Linux 系统的时钟粒度为 10ms,不能满足系统实时调度的需求,因此需要细化其时钟粒度。一种是将系统实时时钟芯片置于单次触发模式,提供十几个微秒级的调度粒度。另一种是通过修改 Linux 内核中宏的定义来细化时钟粒度,这种方式虽然会增加许多的系统开销,但在强周期性环境下,对定时器的设置只需进行一次初始化,这样就在一定程度上保证了处理效率。
- 屏蔽中断的处理。通常使用中断抽象层方法加以解决,尽量不对 Linux 内核源代码进行修改,增加的中断抽象层可以用来截获硬件发出的中断请求,从而完全控制硬件中断,并产生模拟中断信号,发送给linux内核,在系统中有独立的调度器,Linux内核作为优先级最低的任务被调度器调度,从而增强Linux系统实时调度功能。
- 改善linux内核实时调度算法及其策略。
[1]刘海涛. 两种嵌入式实时Linux实现技术研究及实时多核应用[D].西南交通大学,2009.
一些实时系统,为了满足实时需求,都失效cache或没有使用cache的cpu,同时也不使用虚拟内存技术。
preempt-RT 实时补丁,正是通过直接修改Linux内核来满足实时要求,而且其中不少实时技术已经并入官方内核,其上的应用程序开发与标准Linux的应用开发毫无区别,可以完全利用 Linux 提供的丰富系统调用。
我们可以在用户空间和内核空间来创建实时进程或任务。用户空间实时进程的好处在于它受操作系统的保护,不会引起整个系统的崩溃,同时也便于调试;内核空间实时任务由于减少了用户态到内核态切换的开销,效率相对要高,但编程错误易引起系统的崩溃,同时也难于调试。
通过对 Linux2.6 内核打上实时补丁之后,可以配置为完全可抢占模式,这种模式使能了所有实时功能,因此完全能够满足软实时需求,它适合用于延迟要求稍低的实时系统,在一定程度上还能满足硬实时的要求,技术改进有如下几点:
- 高精度定时器 hrtimer 实现;
- 中断线程化;
- spinlock 自旋锁转换为 mutex 可抢占;
- 优先级继承;
Preempt_RT 实时补丁是直接对标准 Linux2.6 内核进行改造的,所使用的实现技术容易被理解掌握,上层的实时应用开发也完全可以利用 Linux 丰富的 API,该实时补丁下的内核驱动程序也必须考虑实时需求,该实时补丁能够完全满足软实时的需求,对于硬实时系统而言,由于Linux内核的庞大,并不能保证其中不存在bug,尽管其实现技术可以满足大部分硬实时系统的要求,但是对于性命攸关的硬实时应用通常不会采用它。
Preempt_RT 实时补丁与 Linux 官方内核几乎同步,在不断地进行维护与更新。不少公司和机构都采用 Preempt_RT 实时补丁构建稳定的版本,并且提供相应的服务和支持。
[1]于晓锋. 嵌入式实时Linux系统的构建[D].电子科技大学,2008.
Linux 内核的内部改造通过改进内核(仅仅是剔除一些标准内核的功能)而并不去改变或增加内核 API,使应用程序可以获得更快的响应速度。它一般采用为标准内核打实时补丁的方法,直接修改原有 Linux 内核的数据结构、调度函数、中断方 式等,以满足实时要求。
例如,可以重新编写一个有优先级驱动的实时调度(Real-timeScheduler),替换原有内核中的进程调度器,使其能够处理实时进程,实现实时扩展。典型的系统有 Kansas 大学研制开发的 KURT-Linux、MontaVista 公司的 MontaVista Linux、TimeSys 公司的 TimeSys Linux/RT,以及 IngoMolnar 编写的 RT patch(实时补丁)等。对 Linux 内部的实时性改造可从时钟机制和内核的抢占性两个方面来进行,改造的目的都是为了缩短 Linux 内核的响应时间。例如在内核代码中增加抢占点,从而减少内核抢占延迟来提高系统的快速反应能力。内部改造 Linux 内核的优势很明显,因为基于 Linux 的第三方软件开发商不需要为不同的实时要求开发不同版本的系统。比如,DVD 播放器可以在一个改进过的内核上更稳定的运行,而它不必知道该内核是经过改进的版本。但是,由于这些修改是局部,属于软实时,而非硬实时。
对 Linux 内核进行内部改造实现方式(TimeSys Linux/RT、MontaVistaLinux 以及 Ingo’s RT patch)的好处是保持了全部的 Linux 应用编程模式,实时应用和普通的应用采用同样的编程方式,使用同样的 API,不同的是只有实时任务需要明确指定自己的优先级与调度策略。但是这种实现方式也有弊病,那就是 TimeSys Linux/RT 满足硬实时性的要求还有一定的困难,这是因为,即使中断关闭和不可抢占区域大大减少,但还是存在的,而一些中断还是无法线程化,例如时钟中断等。
Linux 用于嵌入式系统的主要优势:
(1)Linux 是免费操作系统,使用它来开发系统,成本低,投资效益高。 (2)内核源代码公开,可根据应用的情况灵活地进行剪裁、配置,可修改性强。由于 Linux 的开源性,任何人可对其代码进行修改,利于开发人员根据特定需求特殊定制。 (3)内核精简而高效。与微软公司的 Windows 操作系统或普通的 Unix 系统不同,Linux 内核的核心部分很小,再加上对不需要功能的裁剪,Linux 内核完全可以小到 1MB 以下。 (4) Linux 具有广泛的硬件支持。同时支持不同种类的嵌入式微处理器,具有良好的可移植性。Linux 符合 IEEE POSIX.I 标准,有非常好的可移植性,对多种 CPU 都能很好的支持,众多的应用程序稍加修改就可以应用到嵌入式环境中的 Linux 平台上。 (5)具有稳定、功能强大、易于开发等特点。实践证明 Linux 内核是高度可靠、稳定的,它充分挖掘硬件部分特点,使系统非常快、非常稳定。另外,Linux 的开发者遍布全球,更容易发现系统中的漏洞。 (6) 强大的网络功能。Linux 实现了多数的网络协议和网络接口,强大的网络支持使得开发人员可以利用 Linux 的网络协议栈将其开发成为嵌入式的 TCP/IP 网络协议栈。 (7) 丰富的开发工具。Linux 所使用的基于 GNU 的工具链,从编译器到调试环境,提供了支持多种处理器的无缝交叉开发工具。 (8)可以在网站上找到大量的从入门级到内核级的开发应用文档以及很多的可以参与开发讨论的邮件列表以及论坛。
嵌入式 Linux 应用的缺陷:
(1) 内核不可抢占 在 Linux2.4 以及之前的版本中,内核不具可抢占性。也就是说,若任务运行在内核态,即使当前有更紧急的任务需要运行,当前任务也不能被抢占,因此紧急的任务必须等到当前任务执行完内核态的操作并返回到用户态后,或者当前任务因需要等待某条件满足而主动让出 CPU 才能够被执行,这严重影响到系统的实时性。
在 Linux2.6 系列的内核中,内核具备可抢占性,实时性得到增强。只要重新调度是安全的,即若没有持有锁(锁是非抢占区域的标志),内核中任何高优先级的就绪任务就可以在任何时间抢占正在执行的任务。由于 2.6 内核是支持对称多处理器(SMP,Symmetric Multiple Processor)的,所以,如果没有持有锁,那么正在执行的代码就是可重新导入的,也就是可以抢占的。但是,内核中仍然有大量不可抢占区域,如自旋锁保护的临界区、一些显式使用 preempt_disable 失效抢占的临界区等。这些不可抢占区域大多是共享资源,系统中实现这些资源的互斥访问导致了不可抢占。
(2) 中断关闭 Linux 在一些同步操作中使用了中断关闭指令,中断关闭将增大中断延迟,降低系统的实时性。
(3)自旋锁(spinlock) 自旋锁是在可抢占内核和 SMP 情况下对共享资源的一种同步机制,一般地一个任务对共享资源的访问是非常短暂的,如果两个任务竞争一个共享的资源时,没有得到资源的任务将自旋以等待另一个任务使用完该共享资源。 这种锁机制是非常高效的,但是在保持自旋锁期间将失效抢占,这意味着抢占延迟将增加。在 2.6 内核中,自旋锁的使用非常普遍,有的甚至对整个一个数组或链表的遍历过程都使用自旋锁。因此抢占延迟非常不确定。
(4)大内核锁 由于历史原因,内核一直保留有几个大内核锁,大内核锁实质上也是一种自旋锁,但是它与一般的自旋锁的区别是,它是用于同步整个内核的,而且一般该锁的保持时间较长,也即抢占失效时间长,因此它的使用将严重地影响抢占延迟。
(5)中断总是最高优先级的 在 Linux 中,中断(包括软中断)是最高优先级的,不论在任何时刻,只要产生中断事件,内核将立即执行相应的中断处理函数以及软中断,等到所有挂起的中断和软中断处理完毕才执行正常的任务。因此在标准的 Linux 系统中,实时任务根本不可能得到实时性保证。例如,假设在一个标准 Linux 系统上运行了一个实时任务(即使用了 SCHED_FIFO 调度策略并且设定了最高的实时优先级),但是该系统有非常繁重的网络负载和 I/O 负载,那么系统可能一直处在中断处理状态而没有机会运行任何任务,这样实时任务将永远无法运行,抢占延迟将是无穷大。 因此,如果这种机制不改,实时 Linux 将永远无法实现。本文提出的实时化方案就是针对这种缺陷而设计的。
(6)调度算法和调度点 在 Linux2.4 和以前的版本,调度器的时间复杂度是 O(n)的,而且在 SMP 的情况下性能更低,因为所有的 CPU 共享一个任务链表,任何时刻只能有一个调度器运行。因此,抢占延迟很大程度上来自于当前系统的任务数,具有非常大的不确定性和不可预测性。在 2.6 内核中引入的 O(1)调度器很好地解决了这些问题。此外,即使内核是可抢占的,也不是在任何地方都可以发生调度,例如在中断上下文,一个中断处理函数可能唤醒了某一高优先级进程,但是该进程并不能立即运行,因为在中断上下文不能发生调度,中断处理完了之后内核还要执行挂起的软中断,等它们处理完之后才有机会调度刚才唤醒的进程。 在标准 Linux 内核中,调度点(有意安排的执行任务调度的点)并不多,对 2.4 和 2.6 内核测试的结果表明,缺乏调度点是影响 Linux 实时性的一个重要因素。
(7)定时器精度 时钟是操作系统基本活动的基准,系统用它来维持系统时间、监督系统运作。Linux 内核缺乏高精度的时钟,而依赖低精度时钟无法分辨高精度实时任务的到来,实时应用得不到满足。
在标准 Linux 的最新版本 2.6 中,定时器精度已经有所改善,例如 X86 体系结构下 Linux 将 HZ 变量的值从 100 提高到 1000,使定时器精度提高到 1~2ms 的精度。但是如 ARM 等其他体系结构下 HZ 变量的值依然为 100,而简单地提高 HZ 值将使时钟中断更频繁地产生,这样必定引起调度负载的增加,减少处理器处理其他工作的时间,频繁打乱处理器的高速缓存,所以在嵌入式领域中使用这种方法并不见效。 因此标准 Linux 下的时钟精度仍然达不到实时任务的要求。究其原因,主要是由于 Linux 内核采用周期性触发中断的机制。这个周期时钟并不能提供要求的定时器的定时精度,因此系统设计者必须在时钟中断处理函数开销与定时精度之间做一个折衷。开源的嵌入式操作系统对改进定时器精度提出了一些方案和设想,主要有 KURT-Linux、RT-Linux 和 Monta Vista Linux 等。它们采用了不同的思路和技术方案,很好地满足了实时应用。
|