当前位置: 首页 > 科技观察

如何选择合适的嵌入式操作系统?

时间:2023-03-21 14:29:19 科技观察

要选择合适的嵌入式操作系统,可以考虑以下几个因素:首先是应用。如果你要开发的嵌入式设备与网络应用密切相关或者是网络设备,那么你应该选择使用嵌入式Linux或者uCLinux而不是uC/OS-II。二是实时性。没有一个绝对的数字可以告诉你什么是硬实时,什么是软实时,它们之间的界限也很模糊。这个跟你选择什么样的CPU,它的主频,内存等参数都有关系。如果使用加入了实时补丁等技术的嵌入式Linux,如MontaVistaLinux(2.4.17版),最坏情况下只有436微秒,99.9%的情况都在195微秒以内。考虑到最新Linux的实时性改进,可适用于90~95%的各种嵌入式系统应用。当然,如果你想要更快的实时响应,比如高速A/D转换需要几微秒以内的中断延迟,使用uC/OS-II可能比较合适。当然,采用像Vxworks这样的传统嵌入式操作系统,也能满足如此强的实时性要求。为什么选择Linux操作系统Linux系统作为GPOS(GeneralPurposeOperatingSystem)迄今为止已经非常成熟可靠,而且由于遵循GPL协议,开放所有系统源代码,非常容易裁剪。更重要的是,与其他开源的GPOS或RTOS相比,Linux系统支持多种处理器、开发板,并提供多种软件开发工具。同时,Linux系统对网络和图形界面的支持非常好。显然,选择Linux操作系统在产品开发周期和成本控制方面具有巨大的优势。Linux凭借其在经济和技术上的诸多优势,正在被越来越多的嵌入式设备所采用。Linux在嵌入式系统市场的占有率越来越高。以下是大多数产品选择Linux系统的原因:Linux支持的硬件设备种类繁多。Linux支持非常多的应用程序和网络协议。Linux的可扩展性很强,从小型消费电子产品到大型、笨重的运营商级交换机和路由器都可以使用Linux。与传统的专有嵌入式操作系统不同,部署Linux不需要专利费。Linux吸引了大量活跃的开发者,能够快速支持新的硬件架构、平台和设备。越来越多的硬件和软件供应商,包括几乎所有主要的芯片制造商和独立软件开发商,现在都支持Linux。什么是实时?一个典型的实时系统定义如下:“所谓实时系统就是系统中计算结果的正确性不仅取决于计算逻辑的正确性,还取决于计算的时间。结果产生了,如果完成时间不符合要求,可以说是系统出了问题。也就是说,无论实时应用程序执行什么任务,它不仅需要正确执行,而且还必须及时完成。人们很容易对实时产生误解,认为实时就是速度足够快。事实上,实时并不意味着速度快。实时的关键是保证完成时间,而不是原来的速度,因为速度性能与硬件有关,需要的性能可以通过构建快速的硬件平台(处理器、内存子系统等)来获得.实时行为是一个软件问题,其目标是使关键操作在保证时间内完成。实时进程不会影响自身在执行环境中的调度,但环境会影响实时应用程序的调度。也就是说,实时进程通常与物理事件相关联,例如来自外围设备的中断。很明显,影响实时性的原因是中断响应延迟,在Linux系统中可以细分为中断延迟、中断处理和调度延迟。一般来说,实时可以根据用户对超过时限造成的影响的接受程度分为软实时和硬实时。软实时大多数人都认为软实时意味着操作是有时间限制的。如果超过时限还没有完成操作,体验质量会有所降低,但不会有致命的后果。桌面工作站是需要软实时功能的一个很好的例子。编辑文档时,您希望在按下某个键后立即在屏幕上看到结果。在播放MP3文件时,您希望听到没有爆音、爆音或中断的高品质音乐。如果这些所谓的软实时事件错过了时间限制,结果可能不如预期,体验质量可能会受到影响,但这并不是灾难性的。硬实时硬实时的特点是错过最后期限并造成严重后果。在硬实时系统中,如果错过了最后期限,后果往往是灾难性的。当然,“灾难”是相对而言的。但是,如果您的嵌入式设备正在控制喷气发动机的燃油流量,但它无法及时响应飞行员的输入或操作特性的变化,那么致命的后果将不可避免。在这里,我们总结一下软实时和硬实时的定义。对于软实时系统,如果错过时间限制,系统的计算值或结果将不太理想。然而,对于硬实时系统,如果错过了某个截止日期,系统就会失败,后果可能是灾难性的。制约标准Linux操作系统实时性的因素虽然Linux系统功能强大、实用、易于软件二次开发,并提供程序员熟悉的标准API。但是,由于Linux系统从一开始就被设计为GPOS(通用操作系统),其目的是构建一个完整稳定的开源操作系统,尽可能缩短系统的平均响应时间,提高吞吐量,并注意操作系统的整体功能需求,以达到更好的平均性能。(在操作系统中,我们可以简单地将吞吐量理解为系统在单位时间内能够处理的事件总数。)因此,在设计Linux的进程调度算法时,主要考虑的是公平性,也就是说,调度器可以将可用资源平均分配给所有需要处理器的进程,并保证每个进程都在运行。但这种设计目标与实时进程的要求背道而驰,因此标准的Linux并没有提供强大的实时性能。Linux系统的实时性不强,因此在嵌入式应用中有一定的局限性,主要受内核抢占性、进程调度方式、中断处理机制、时钟粒度等方面的制约,如下:(1)进程调度Linux系统提供了符合POSIX标准的调度策略,包括FIFO调度策略(SCHED_FIFO)、时间片轮换实时调度策略(SCHED_RR)和静态优先级抢占式调度策略(SCHED_OTHER)。Linux进程默认的调度策略是SCHED_OTHER。这种调度方式虽然可以让进程公平地使用CPU和其他资源,但是不能保证时间要求严格或者优先级高的进程先于低优先级进程执行。严重影响系统的实时性。那么,将实时进程的调度策略设置为SCHED_FIFO或SCHED_RR,看似可以让Linux系统具备根据进程优先级进行实时调度的能力,但问题是Linux系统支持抢占式调度用户模式,而不是内核模式。全面支持抢占式调度策略。这样,运行在Linux内核态的任务(包括系统调用和中断处理)就无法被其他优先级更高的任务抢占,从而造成优先级倒置问题。(2)内核抢占机制Linux系统进程运行分为用户态和内核态两种模式。当进程运行在用户态时,优先级高的进程可以抢占进程,可以更好的完成任务;但是当进程运行在内核态时,即使是其他高优先级进程也无法抢占该进程。当进程通过系统调用进入内核态时,实时任务必须等待系统调用返回后才能获取系统资源。这与实时系统要求的高优先级任务操作相矛盾。当然,自从Linux2.6内核发布后,这种情况已经有了明显的改善。Linux2.6之后的内核是可抢占的,也就是说进程无论是在内核态还是用户态都可能被抢占。Linux2.6以后的内核提供了以下三种抢占方式供用户选择。PREEMPT_NONE-不强制执行抢占。总体平均延迟很低,但偶尔会有一些较长的滞后。它最适合以总吞吐量为主要设计标准的应用。PREEMPT_VOLUNTARY-减少延迟的第一阶段。它在内核代码的一些关键位置放置了额外的显示抢占点,以减少延迟。但这是以整体吞吐量为代价的。PREEMPT/PREEMPT_DESKTOP-这种模式使内核在除关键部分之外的任何地方都可以被抢占。这种模式适用于需要软实时性能的应用,例如音频和多媒体。这也是以整体吞吐量为代价的。(3)中断屏蔽Linux在处理中断时会关闭中断,使其能够更快、更安全地完成自己的任务,但在此期间,即使有更高优先级的实时进程被中断,系统也无法响应。必须等到当前中断任务处理完毕。在这种情况下,会增加中断延迟和调度延迟,降低Linux系统的实时性。(4)时钟粒度较粗。时钟系统是计算机的重要组成部分,相当于整个操作系统的脉搏。系统所能提供的最小时间间隔称为时钟粒度,时钟粒度与进程响应的延迟成正比,即粒度越粗,延迟越长。但是,时钟粒度并不是越小越好。就相同的硬件环境而言,时间粒度越小,会导致系统开销增加,整体吞吐量越低。在Linux2.6内核中,时钟中断的频率范围为50~1200Hz,周期不小于0.8ms,显然不能满足几十微秒响应精度的应用要求。在嵌入式Linux系统中,为了提高整体吞吐量,时钟频率一般设置为100HZ或250HZ。此外,系统时钟负责软定时。当软定时器数量逐渐增加时,会引起定时器冲突,增加系统负载。(5)虚拟内存管理Linux采用虚拟内存技术,进程可以运行在远大于实际空间的虚拟空间中。在分时系统中,虚拟内存机制非常适合,但对于实时系统来说就难以忍受了。频繁的页面交换会使系统进程无法在规定的时间内完成。针对这个问题,Linux系统提供了内存锁定功能,避免内存页在实时处理时被换出。(6)共享资源互斥访问的差异当多个任务对同一个共享资源进行互斥访问时,需要防止数据被破坏。系统通常使用信号量机制来解决互斥问题。但是在采用优先级调度的实时系统中,信号量机制容易造成优先级倒置,即低优先级任务占用高优先级任务的资源,导致高优先级任务无法运行。虽然从2.6.12版本开始,Linux内核已经能够在更快的x86处理器上实现10毫秒以内的软实时性能。但是,如果要实现可预测、可重复的微秒级延时,使Linux系统更好地应用于嵌入式实时环境,则需要在保证Linux系统功能的基础上进行修改。下一节将介绍通过实时打补丁提高Linux实时性能的方法。常用的Linux实时改造方案根据实时系统要求和Linux的特点和性能分析,标准Linux的实时改造有多种方法。比较合理的两种方法是:直接修改Linux内核源代码。双核方法。1直接修改Linux内核源代码对Linux内核代码的小幅修改不要对内核做大规模改动。在遵循GPL协议的情况下,直接修改内核源代码,将Linux改造为一个完全可抢占的实时系统。核心修改是局部的,不会从根本上改变Linux内核,部分改变也可以通过Linux模块加载完成,即系统在需要处理实时任务时加载功能模块,动态卸载模块在不需要的时候。目前kernel.org发布的主线内核版本不支持硬实时。为了启用硬实时功能,必须对代码进行修补。实时内核补丁是为减少Linux内核延迟而做出的多项努力的共同结果。这个补丁有几个代码贡献者,目前由IngoMolnar维护。补丁网址如下:www.kernel.org/pub/linux/kernel/projects/rt/。在配置实时打补丁的内核代码时,我们发现实时打补丁增加了第四种抢占模式,称为PREEMPT_RT(实时抢占)。实时补丁为Linux内核添加了几个重要的特性,包括使用可抢占互斥锁而不是自旋锁;除了受preempt_disable()(非自愿抢占)函数保护的区域外,内核中的任何地方都启用了非自愿抢占。这种模式显着减少了抖动(延迟的变化),并为延迟关键的实时应用程序实现了可预测的低延迟。这种方法的问题在于,很难绝对保证在任何情况下,GPOS程序代码都不会妨碍RTOS的实时行为。也就是说,通过修改Linux内核,很难保证实时进程的执行不会被非实时进程执行的不可预测的活动所干扰。2双内核法事实上,之所以采用双内核设计,是因为人们不相信标准的Linux内核在任何情况下都能实现其实时承诺,因为GPOS内核本身就非常复杂,程序较多代码通常会导致更多的不确定性,这将不符合可预测性的要求。更何况Linux内核极快的发展速度使其在短时间内带来巨大的变化,直接修改Linux内核源代码的方式将很难保持同步。双内核方式是在同一个硬件平台上使用两个相互配合、协同工作的系统核心,通过在Linux系统的顶层增加一层实时核心来实现。其中一个内核提供精确的实时多任务处理,另一个内核提供复杂的非实时通用功能。双内核方法的本质是将标准Linux内核作为普通进程运行在另一个内核上。改造的关键部分是在Linux与中断控制器之间增加一个中断控制仿真层,成为其实时内核的一部分。中断仿真机制提供了一个标志位来记录Linux的中断开关。一般只在修改核心数据结构的关键代码时才关闭中断,因此中断响应很小。它的优点是可以实现硬实时,可以方便的实现新的调度策略。为了方便起见,实时内核通常由一组可以动态加载的模块提供,也可以像任何一般子系统一样直接在Linux源代码树中编译。常用的双内核实时补丁有RTLinux/GPL、RTAI、Xenomai。RTLinux/GPL只允许内核模块形式的实时应用;RTAI和Xenomai支持受MMU保护的用户空间中的实时程序。接下来,我们将分析RTAI和Xenomai。图1.Linux中RTAI(左)和Xenomai(右)实时内核的层次结构图1显示了分别由RTAI和Xenomai实时内核以及标准Linux内核组成的双内核系统的层次结构。可见两者的组织形式略有不同。与Xenomai让ADEOS控制所有中断源不同,RTAI拦截它们并使用ADEOS向Linux发送RTAI不感兴趣的中断通知(即中断不影响实时时序)。这种混合过程的目的是提高性能,因为在这种情况下,如果中断是唤醒实时任务,则可以避免ADEOS管理中断的开销。从这里可以看出RTAI的实时性应该比Xenomai更好。RTAI(Real-TimeLinuxApplicationInterface)虽然实时性好,但对ARM的支持不够,更新速度极慢,导致项目开发周期长,研发成本高。与RTAI相比,Xenomai更注重用户态的实时性,提供多套兼容主流商用RTOS的API,支持丰富的硬件。建立在其上的应用系统可以保持较高的实时性,稳定性能和兼容性更好;另外Xenomai社区活跃,紧跟主流内核更新,支持多种架构,对ARM的支持非常好。Xenomai是Linux内核的实时开发框架。它希望无缝集成到Linux环境中,为用户空间应用程序提供全面的、接口无关的硬实时性能。Xenomai基于一个抽象的实时操作系统核心,可以用来在一个通用的实时操作系统调用核心上构建任意数量的不同实时接口。Xenomai项目于2001年8月启动,2003年与RTAI项目合并推出RTAI/fusion。2005年,由于发展理念不同,RTAI/fusion项目从RTAI中分离出来,成为Xenomai项目。相比之下,RTAI项目致力于技术上可行的最低延迟;Xenomai还关注可扩展性、可移植性和可维护性。Xenomai项目将支持IngoMolnar的PREEMPT_PT实时抢占补丁,这是与RTAI项目的另一个显着区别。RTAI和Xenomai都有开发者社区支持,都可以作为VxWorks的开源替代品。Xenomai是基于Adeos(AdaptiveDomainEnvironmentforOperatingSystem)实现的。Adeos的目标是为操作系统提供灵活、可扩展的自适应环境;在这种环境下,多个相同或不同的操作系统可以共存,共享硬件资源。在基于Adeos的系统中,每个操作系统都运行在一个独立的域中。每个域都可以有独立的地址空间和类似进程、虚拟内存等的软件抽象层,这些资源也可以被不同的域共享。不同于以往传统的操作系统共存方式,Adeos在现有操作系统下插入了一个软件层,通过为上层的多个操作系统提供一定的原语和机制来实现硬件共享。该应用程序主要为“硬件-内核”接口提供了一个超微内核(nanokernel),使得基于Linux环境的系统能够满足硬实时的要求。Xenomai充分利用了Adeos技术。它的主要目标是帮助人们尽可能顺利地将依赖传统RTOS的应用程序迁移到GNU/Linux环境,避免完全重写应用程序。它提供了一个模拟器来模拟传统实时操作系统的API,使应用程序很容易移植到GNU/Linux环境,同时保持良好的实时性能。Xenomai的核心技术是使用实时微内核来构建这些实时API,也称为“皮肤”。Xenomai通过这种接口变体技术实现了各种传统RTOS的应用程序编程接口,方便了传统RTOS应用程序向GNU/Linux的移植。图2描述了XenomaiwithSkin的分层架构。图2Xenomai分层结构与皮肤界面从图2可以看出,Xenomai系统包含多个抽象层:Adeosnano-core直接在硬件上工作;Adeos之上是与处理器架构相关的硬件抽象层(HardwareAbstractionLayer,HAL);系统的核心部分是运行在硬件抽象层上的抽象实时内核,实时内核实现了通用实时操作系统的一系列基本服务。这些基础服务可以由Xenomai的原生API(Native)提供,也可以由其他基于实时内核构建的传统RTOS的客户端API提供,如RTAI、POSIX、VxWorks、uITRON、pSOS+等。客户端API被设计为兼容传统RTOS应用在Xenomai上的移植,使应用程序在移植到Xenomai/Linux系统的过程中不需要完全重写。这个特性保证了Xenomai系统的健壮性。Xenomai/Linux系统为用户程序提供两种模式:用户空间和内核空间。前者通过系统调用接口实现,后者通过实时内核实现。用户空间的执行方式保证了系统的可靠性和良好的软实时性能,而内核空间程序可以提供优秀的硬实时性能。