实时操作系统
实时应用是指对数据、事件或操作的处理必须在特定的时间范围内完成,以满足特定的功能要求。这些要求包括:
时间敏感性:实时应用必须在规定的时间内响应并处理事件或数据,通常以毫秒或微秒级的时间范围为目标;
及时性:实时应用需要按照特定的时间表或周期执行任务,以确保系统的稳定性和预测性;
正确性:实时应用对于处理的结果必须是准确和正确的,特别是在需要高度可靠性的系统中,如航空航天、医疗等领域;
实时任务调度:实时应用可能涉及多个任务的处理,任务的调度必须遵循特定的优先级和时间约束。
随着实时应用对功能要求的不断增加,以及实时应用越来越倾向于将不同类型的任务集成在一个平台上运行,业界对采用商用硬件的兴趣越来越高。另外,降低开发和维护成本的需要也是采用现有商用硬件的驱动力。在这种情况下,得益于对硬件设备和外围设备的广泛支持,以及良好的编程环境,Linux内核在软件方面正在成为一个宝贵的解决方案[1]。
从开发的角度上来说,实时程序可以在裸金属设备上直接运行(没有操作系统),然而,为了在系统上并行多个任务,特别的,因为多核设备的出现,在多核系统上并行多个任务,我们需要引入实时操作系统用以在多个任务之间共享内存和处理器等资源。
实时操作系统(Real-Time Operating System,RTOS)是一种专门设计用于处理实时任务和应用程序的操作系统。实时任务是指必须在严格的时间约束下完成的任务,通常有严格的时间截止日期。实时操作系统能够确保任务在规定的时间内得到处理,以满足实时性的要求。
实时操作系统分类
硬实时操作系统(Hard Real-Time Operating System)
在硬实时系统中,任务必须在规定的时间截止日期之前完成。对于硬实时任务,时间的可预测性和保证性非常重要,因为任务未能按时完成可能会导致系统故障或严重事故。硬实时系统通常用于控制和嵌入式系统,如飞行控制系统、医疗设备、工业自动化等。
软实时操作系统(Soft Real-Time Operating System)
在软实时系统中,任务的时间约束是存在的,但是在某些情况下,偶尔的违约是可以接受的,只要大多数任务能够按时完成。软实时系统通常用于一些多媒体应用、实时通信和游戏等领域。
实时操作系统特点
快速响应:实时操作系统需要尽可能快速地对任务做出响应,以满足时间约束。
可预测性:实时任务的执行时间应该是可预测的,使得系统可以合理地安排任务的优先级和调度。
任务调度:实时操作系统使用各种调度算法来决定哪个任务优先执行,以保证关键任务及时得到处理。
中断处理:实时操作系统能够有效地处理硬件中断和软件中断,确保关键事件的及时响应。
低延迟:实时操作系统通常具有较低的上下文切换延迟,从而提高任务响应性能。
货架商用硬件的优势与Linux操作系统
实时系统可以构建在专有硬件上,也可以构建在货架商用硬件(Commercial-off-the-Shelf COTS)上。对比专有硬件,货架商用硬件的优势在于:
经济规模:COTS产品通常由大规模的厂商生产和销售,因此可以实现大规模生产和采购,从而降低了单个产品的制造成本。这些成本节约可以传递给最终用户,使得COTS产品在价格上更具有竞争力。
降低开发成本:自行开发和定制软件或硬件产品通常需要大量的人力、时间和资源投入。使用COTS产品可以节省开发过程中的研发成本和周期,因为COTS产品已经经过测试和验证,可以立即投入使用。
技术支持:COTS产品通常由专业的厂商提供技术支持和维护服务。这意味着用户不需要自行承担大部分维护和支持成本,可以专注于业务需求。
标准化和兼容性:COTS产品通常遵循行业标准和规范,这使得它们更易于集成到现有系统中,降低了集成和兼容性测试的成本。
快速上市:使用COTS产品可以加快产品的上市时间,因为不需要从头开始开发所有组件。这对于需要快速推出产品的项目尤其重要。
熟性和稳定性:COTS产品通常经过长时间的市场验证和改进,其稳定性和性能已经得到验证,相比自行开发的产品,有较低的风险和不确定性。
另外一方面,Linux是与货架商用硬件匹配的优秀操作系统候选者。这是因为Linux作为一个开源操作系统,具有极大的生态优势和强大的平台可移植性[2]。具体来说,Linux的如下特点让其非常适合货架商用硬件:
开源自由:Linux是一个开源的操作系统,硬件厂商可以自由地访问、使用和修改其源代码。这使得他们可以根据自己的需求进行定制和优化,使得系统更适合于特定的硬件设备。并且Linux对现有商用硬件的支持使厂商能以较低的成本对硬件平台进行组合。
大量的软件支持:Linux拥有丰富的开源软件生态系统,这意味着货架商可以从各种开源应用程序中选择,以满足他们的需求。这些软件可以提供例如工业控制、图像处理、科学计算[3]等功能。科学界普遍使用Linux进行科研工作。Linux为科学家提供了一个灵活、强大的工作环境,可以满足各种科学计算需求。在高能物理、天文学、生物信息学等领域,Linux被广泛应用于数据处理、模拟实验和科学研究。
可靠性和稳定性:因为人们对Linux的参与程度很高,所以测试和验证全面而充分。对其安全性的测试也验证也很全面。
跨平台支持:Linux支持多种处理器体系结构,是支持平台种类最多的操作系统,这有利于厂商对其进行移植[2]。
运行在货架商用硬件上的Linux操作系统以其可靠、经济、稳定、扩展性强,成为实时应用系统广为认可的解决方案。Linux已经被欧洲空间局(ESA),美国国家航空航天局(NASA)考虑用于太空和地面应用,包括关键任务的软件。SpaceX的龙飞船和猎鹰火箭的关键控制系统已经采用Linux PREEMPT-RT作为关键控制操作系统[4]。
另外,我国的北京国科环宇科技股份有限公司是隶属于中国科学院的高新技术企业,为航天、航空和军用领域,提供先进的电子学产品及系统解决方案。国科环宇望获Linux,作为一款实时Linux操作系统,能为航空、航天、车、船以及工业控制设备提供安全可靠稳定的实时计算和控制服务。
实时Linux的两种解决方案
多内核(Dual Kernel)解决方案
在多内核解决方案中,实时性与普通Linux内核的功能被分割成两个独立的内核。一个是普通Linux内核,负责运行通常的任务和应用程序。另一个是专门为实时性而设计的轻量级内核,通常被称为实时内核。实时内核负责处理实时任务,其调度和中断处理机制被优化以满足实时性要求。多内核的解决方案能够在一定程度上提供较好的实时性能,但同时也增加了系统的复杂性和维护成本。因为需要同时管理和维护两个内核,且两个内核之间的通信和数据交换可能存在一些开销。
PREEMPT-RT(Real-Time)解决方案
PREEMPT-RT(Real-Time)是一个Linux内核的扩展补丁,旨在将Linux内核转变为实时操作系统。它通过引入可抢占性和实时调度策略来提供更好的实时性能,使Linux能够满足一些对实时性要求较高的应用场景。PREEMPT-RT补丁的主要目标是减少Linux内核的抢占延迟(Preemption Latency)和中断延迟(Interrupt Latency)。抢占延迟是指一个高优先级的任务能够打断正在运行的低优先级任务所需的时间,中断延迟是指内核响应硬件中断的时间。在实时应用中,这些延迟必须尽可能地小,以确保实时任务能够及时地获得处理器时间,从而满足实时性要求。
对比多内核方案与PREEMPT-RT方案[1]
多内核方案天然地需要对Linux内核代码进行破坏性修改,并且从功能和时间角度来分析多内核之间的交互并不是轻松的任务。多内核方案对内核的修改需求还引入了一个严格的依赖性,即多内核方案与Linux内核版本紧耦合,这对多内核方案的可维护性和可移植性方面带来了障碍。这个问题并不影响PREEMPT-RT,PREMPT-RT由Linux社区直接开发。相反,多内核方案通常基于旧版Linux内核。此外,在多内核方案中,由于两个内核之间复杂的交互,此方法通常较不稳定且不安全,这需要实时开发人员额外的努力。总而言之,PREEMPT-RT补丁允许开发人员在一个真实的Linux环境中操作,他们可以轻松重用大部分现有的库和工具,包括POSIX标准指定的所有函数集。国科环宇望获Linux就是在PREEMPT-RT的基础上对实时性进行进一步增强,并利用自动化的方法把函数集向POSIX标准以外进行扩展。可抢占
内核PREEMPT-RT的实现原理
本节介绍PREEMPT-RT的实现原理。PREEMPT-RT的研发周期较长,对实时性的支持主要由相辅相成的如下几个部分组成[5]。
高精度时钟
因为实时应用需要对时间进行精准计量与控制,所以Linux内核引入了高精度时钟用来作为之前低精度时钟的补充。
PREEMPT-RT最重要的成就之一是能够以纳秒级的精度实例化计时器。在此之前,计时器的间隔精度由配置的Tick Rate(通常简写为HZ)决定,其数值可以在10Hz到1,000Hz之间变化,从而将计时器的精度降低到毫秒级。赫兹用于计算从系统启动开始发生的时钟滴答数(通常称为jiffies)。2006年,在内核版本2.6.16中引入了高分辨率定时器(High-Resolution Timers,简称HRTs)或Hrtimers,应用程序可以请求具有纳秒级分辨率的计时器。实际的分辨率取决于计时器的硬件实现。
中断线程化
中断具有最高的优先级,当有中断产生时,CPU会暂停当前的执行流程,转而去执行中断处理程序。硬件中断处理过程中会关掉中断,如果此时有其它中断产生,那么这些中断将无法及时得到处理,这也是导致内核延迟的一个重要原因。另外,中断优先级比进程高,一旦有中断产生,无论是普通进程还是实时进程都要给中断让路,如果中断处理耗时过长,则会严重影响到系统的实时性。因此内核设计的目标是将关中断状态下需要执行的工作量尽量压缩到最低限度。传统的中断处理流程由两部分处理逻辑协同完成,“上半部(top half)”负责实际的对硬件中断的响应处理,“下半部(bottom half)”由 上半部负责调度并执行额外的处理。上半部在禁用中断的情况下执行,因此必须尽可能地快,从而不会给系统响应造成太大的延迟。比如说网卡驱动在上半部完成一些硬件设置或数据收发,在下半部完成网络数据处理。但是这种设计,上半部的运行时长也是不够确定的,受各驱动实现的影响。
中断线程化后进一步压缩了上半部的工作量,上半部的工作仅仅需要完成 “快速检查”,譬如确保中断的确来自期望的设备;如果检查通过,它将对硬件中断完成确认并通知内核唤醒中断处理线程完成中断处理的下半部。降低内核中的延迟只是中断线程化带来的好处之一,除此之外它还具备其他方面的优点。其中最突出的一点是:由于中断线程化后简化乃至避免了整个中断处理流程中 “关中断处理(术语上称之为 “hard” 部分)” 和 “开中断处理(术语上称之为 “soft” 部分)” 两个阶段之间可能涉及的锁同步机制,从而降低了整体实现上的复杂性。中断处理线程化还有助于内核的调试[6]。
进程优先级继承
由于多进程共享资源,具有最高优先权的进程被低优先级进程阻塞,反而使具有中优先级的进程先于高优先级的进程执行,导致系统的崩溃。这就是所谓的优先级反转(Priority Inversion)。
其实,优先级反转是在高优级(假设为A)的任务要访问一个被低优先级任务(假设为C)占有的资源时,被阻塞。而此时又有优先级高于占有资源的任务(C)而低于被阻塞的任务(A)的优先级的任务(假设为B)时,于是,占有资源的任务就被挂起(占有的资源仍为它占有),因为占有资源的任务优先级很低,所以,它可能一直被另外的任务挂起,而它占有的资源也就一直不能释放,这样,引起任务A一直没办法执行,而比它优先低的任务却可以执行。 所以,一个解决办法就是提高占有资源任务的优先级,让它正常执行,然后释放资源,以让任务A能正常获取资源而得以执行。
优先级继承是指将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级。当高优先级任务由于等待资源而被阻塞时,此时资源的拥有者的优先级将会自动被提升。Linux操作系统的优先级继承机制最早由PREEMPT-RT实现。另外,2012年提出的优先级天花板也是可供参考的技术路线。 优先级天花板是指将申请某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级(这个优先级称为该资源的优先级天花板)。
Read-Copy-Update (RCU)
RCU 同步机制由Paul E. McKenney 等人在 Linux 内核版本 2.6 中引入,然后由 Desnoyers 等人移植。由于同步性能的改进,RCU 取得了令人印象深刻的成功。因此,RCU 目前广泛应用于所有内核子系统。基本思想是用RCU原语取代标准的读写锁,以防止对读取端的阻塞,并且维护更新对象的多个版本。
为了提高Linux的实时性,RCU实现了可抢占 RCU 和无回调 CPU。前者允许实时内核抢占在关键部分运行的读取器。后者指的是RCU“移除”阶段的管理。当所有读者退出临界区时,调用RCU回调释放内存会降低实时性,引入不可忽略的调度延迟,特别时当回调发生在中断上下文中。无回调CPU技术将回调移动到对实时性要求不高的处理器核上,保证了无回调CPU的实时性。
完全无滴答运行
完全无滴答运行是Linux内核中的一种特性。在传统的Linux内核中,存在一个固定的时钟中断(tick),该中断以固定的频率触发操作系统的主要事件处理。这个频率由内核配置参数HZ来决定。
完全无滴答运行的目标是通过使用高精度定时器(如hrtimers)和RCU(Read-Copy-Update)机制,在特定情况下关闭周期性的定时器中断。这样,内核可以更灵活地进行调度,并只在需要处理任务时才会唤醒处理器,从而提高系统的响应性和性能,并降低系统的能耗。
特别的完全无滴答运行一定程度上消除了时钟滴答中断对处理器的抢占,减小了进程操作的延迟,提高了实时性。
国科环宇望获Linux通过插桩的方法,动态监控中断等对进程延迟的影响,让实时更为可测,可控。
进程调度器
SCHED_DEADLINE调度器是Linux内核中的一个实时进程调度器,它是Linux对实时性的支持的一部分。与传统的CFS(Completely Fair Scheduler)调度器不同,SCHED_DEADLINE调度器专注于提供对实时任务的高精度和可预测性调度。SCHED_DEADLINE调度器的设计目标是为实时任务提供严格的截止时间保证,使得实时任务能够在特定的期限内完成,同时尽量避免任务饥饿的问题。这对于实时系统非常重要,例如实时控制系统和多媒体应用等领域,要求任务能够按时完成以确保系统的可靠性和实时性。
SCHED_DEADLINE调度器引入了三个主要概念:
Period(周期):每个实时任务有一个固定的周期,在该周期内任务必须完成。周期可以看作是实时任务需要完成一轮工作的时间间隔。
Deadline(截止时间):每个实时任务也有一个截止时间,在这个时间点之前任务必须完成。截止时间通常设置为每个周期的末尾,这样任务在周期结束时应该完成。
Runtime(运行时间):每个实时任务在每个周期内被允许的最大执行时间。这个值定义了任务在一个周期内可以运行的时间总量。
SCHED_DEADLINE调度器通过这些概念来调度实时任务。它根据任务的截止时间和运行时间来进行优先级排序,确保任务能够在规定的时间内完成,并按时响应。
需要注意的是,SCHED_DEADLINE调度器适用于实时任务的调度,对于非实时任务,Linux仍然使用其他调度器,如CFS调度器。由于SCHED_DEADLINE调度器是为实时任务而设计的,因此在非实时任务方面可能不如CFS调度器表现得那么好。因此,在选择调度器时,需要根据系统的实际需求和特性进行适当的选择。
内存分配器
PREEMPT-RT采用slab内存分配器,减少了内存的碎片化,进而降低了内存分配带来的延迟。
国科环宇望获Linux通过插桩的方法监控到在与进程创建有关的内核操作时,进程控制块、堆、栈相关的内存分配带了数微秒的延迟。国科环宇望获Linux通过内存块预分配的方法,消除了这些延迟。
可抢占自旋锁
自旋锁是一种用于保护临界区(一段在同一时刻只允许一个线程执行的代码段)的同步机制。在使用自旋锁时,如果自旋锁已经被占用,线程将会忙等待(即自旋),直到自旋锁被释放。这意味着线程会一直占用CPU资源,直到自旋锁可用为止。这种机制在低延迟的情况下是有效的,但在高负载情况下可能会导致性能问题,因为忙等待会消耗大量CPU时间。PREEMPT-RT可抢占自旋锁是结合了PREEMPT-RT实时补丁和自旋锁的概念。通过使用这种可抢占的自旋锁,内核可以在自旋锁被占用时,将正在等待获取自旋锁的线程置于睡眠状态(阻塞),并让其他任务获得执行机会。当自旋锁释放时,内核会唤醒之前阻塞的线程,使它们有机会再次尝试获取自旋锁。这种机制有效地减少了忙等待带来的CPU资源浪费,因为当一个线程不能获得锁时,它会被放入睡眠状态,让其他任务有机会执行。这有助于提高系统的响应性和实时性能,尤其对于那些对低延迟和可靠性要求较高的实时应用程序。
总结
总体而言,Linux PREEMPT-RT通过提供更好的抢占能力、改进锁机制、优化调度策略和中断处理等方式,显著提升了Linux内核在实时应用场景下的表现。这使得Linux系统能够更好地适应实时性要求较高的应用,如工控系统、嵌入式实时控制、机器人控制等领域。与此同时,Linux PREEMPT-RT与Linux主干同步开发的方式,也是基于Linux PREEMPT-RT的实时系统继承了Linux操作系统丰富的应用生态和平台可移植性。国科环宇望获Linux在PREEMPT-RT的基础之上,以模块化,动态可定义化的方式对实时性进行进一步调优,在保证了开发者良好体验度的情况下,使实时性更为可测,可控。
参考文献
[1] Federico Reghenzani, Giuseppe Massari, William Fornaciari. The Real-Time Linux Kernel: A Survey on PREEMPT_RT. ACM Computing SurveysVolume 52Issue 121 February 2019.
[2] GK Adam, N Petrellis, PA Kontaxis, T Stylianos .COTS-Based Real-Time System Development: An Effective Application in Pump Motor Control. Computers 9 (4), 97 2020
[3] Joachim Henkel. 2006. Selective revealing in open innovation processes: The case of embedded Linux. Research Policy 35, 7 (2006), 953–969.
[4] https://blog.desdelinux.net/en/spacex-lleva-astronautas-espacio-usando-linux/
[5] “零”智享丨Preempt-RT实时patch介绍. https://zhuanlan.zhihu.com/p/586668309
[6] 中断线程化与强制中断线程化. http://www.cnblogs.com/bigfish0506/p/16220669.html
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/whh_bjqy/article/details/137136527