RTOS论文笔记(一)

刘剑. 基于国产平台的Linux实时性优化技术研究[D].中国航天科技集团公司第一研究院,2018.

引言

因为嵌入式领域对操作系统的实时性有较高要求,所以对RTOS的研究一直有较高的热度。RTOS更重视平均响应时间,这方面与通用操作系统看重系统整体平均性能不同。只有同时保证计算结果的正确性和和计算结果输出的时效性,才能保证RTOS逻辑的正确性。

虽然Linux内核提供实时支持,但仅支持软实时,尚不具备硬实时能力。所以,为了实现自主可控的实时操作系统,需要在了解Linux内核的基础上,对Linux内核进行实时性改造,从而使Linux操作系统符合RTOS的标准。

实时并不意味着任务执行的速度快,而是指任务的完成时间是可确定的,不会超过规定的时间延迟限制。无论系统负载有多重,实时系统必须保证时间要求。

研究现状和趋势

根据时间约束的重要性和计算结果带来后果的严重程度,RTOS通常有两种分类:软实时操作系统(soft-RTOS)和硬实时操作系统(hard-RTOS)两类,sof-RTOS则只要求任务按照优先级尽可能快地完成操作即可;硬实时操作系统要求任务在提前规定的时间内必须完成。

国外商用RTOS价格昂贵,且不安全

现在嵌入式领域有很多商用的RTOS,例如vxWorks,Windows CE,pSOS,QNX等。这几种RTOS基本可以满足实时系统的一般要求,但是这些商用的实时操作系统价格高昂,会额外增加不少的成本。另外,由于这些实时操作系统的内核代码并不是开源的,用户难以根据自身需要对其进行裁剪,所以在大范围推广和自主可控方面受到了很大的限制。

长期以来,航天领域的软件以应用软件、驱动软件、系统集成等作为软件主要研究方向,对基础软件的设计和研究投入相对较少。操作系统和编译器等真正体现软件核心技术能力的产品在自主可控方面有待大幅度提高,目前还是以国外的产品为主。国内操作系统在航天领域地面计算机操作系统中的使用相对较少,现有武器型号中地面计算机系统大多选用了美国WindRiver公司的vxWorks或Microsoft公司的Windows系列操作系统,导致武器装备系统软件难以达到完全自主可控的程度。另外,最近美国对中兴通讯的出口制裁已经向我们敲响了警钟,实现基础软件和芯片的自主可控迫在眉睫。

这些国外公司开发的实时操作系统使得建立在其上的应用系统和产品都会被国外势力牢牢控制,出现安全风险的机会就高很多,因此自主可控的国产处理器和操作系统一直是相关研究的重点。

国产RTOS专用性较强,一般用于专用领域

目前在中国比较成熟的RTOS有翼辉信息(北京翼辉信息技术有限公司)的Sylixos和中航工业计算所的天脉1、天脉2等。

  • 翼辉信息的Sylixos不基于任何开源代码,是完全原创的操作系统,这款完全自主可控操作系统已经用在导弹、卫星、医疗、公交等多种行业控制中。

  • 天脉1是一款面向多任务应用的强实时嵌入式系统,提供的调度方式有优先级抢占式调度和优先级时间片轮转调度,优先级管理算法基于位图以及高效的上下文切换算法,保证用户的实时应用需求,支持中断嵌套,为用户紧急事件处理提供了更有效的机制,高效的汇编级中断/异常响应过程能够保证用户外部事件的实时处理需求。C919国产大型客机中的机载信息系统计算机在其安全级别最高的模块中使用了天脉1操作系统。

  • 天脉2是一款分区实时操作系统,具有完全自主的知识产权,可以处理多应用和多任务,既满足综合化又满足模块化航空电子系统的应用要求。

此外还有Reworks,DeltaOs等优秀的国产化RTOS。

但是,此类RTOS专用性较强,一般用于特定领域,适用性和可扩展性以及相关的开发工具、辅助工具、技术支持等无法与Linux生态圈相比。另外,上述实时操作系统都是属于受专利保护的商业实时操作系统,所以在测量它们的实际性能时可能存在限制。翼辉信息的Sylixos目前虽然支持源代码开放,但是其主要适用于主流的国外处理器,对国产处理器适配较差。而天脉1和天脉2代码不开源,所以很难对其进行深入研究。

对Linux的实时化改造具有可行性

另外,国内还没有基于国产平台的Linux实时操作系统,所以本文在龙芯平台上对Linux进行实时性改造意义重大。

Linux 2.6版内核开始支持可抢占式任务调度,此后随着低延迟补丁、CFS调度器、优先级继承、高精度时钟系统等改进技术进入Linux主线版本,Linux的实时性不断的提高。但Linux和Windows一样也是一个通用的分时操作系统。将Linux操作系统改造成实时操作系统仍然是一个重要的研究方向,很多国内外科研机构和科技公司都对Linux的实时性进行了深入研究和改进。

两大Linux实时性优化技术路线:

1. 直接修改内核方案:

直接修改Linux内核是让其本身具有实时能力,常见的修改方法是为Linux内核添加实时抢占补丁,主要包括高精度时钟、中断线程化、实时调度策略、优先级继承、临界区可抢占等。

首先,早期的Linux系统为了获取高精度时间,需要访问硬件平台的特定时钟计数器,例如基于x86架构处理器的TSC寄存器,短周期任务运行时,需要提高时钟频率HZ,从而造成时钟中断经常产生,但是这样CPU资源就会浪费在大量的时钟中断处理上。为了应对上述问题,Thomas Gleixner等人开发了新的时钟管理系统 [ 1 ] [ 2 ] ^{[ 1 ] [ 2 ]} [1][2],最重要的两个支持模块是时钟源clocksource和定时器clockevent。这种时钟管理系统已经在Linux2.6.16版本加入了Linux内核主线。

[1] Gleixner T,Niehaus D.Hrtimers and beyond:Transforming the linux time subsystems[J].Proceedings of the Ottawa Linux Symposium,2006.
[2] 刘冀.Tickless技术研究及其在嵌入式系统中的实现[D].电子科技大学,2009.

其次,在中断线程化技术没有进入Linux内核主线以前,中断具有最高优先级,当中断产生时,中断会被优先执行,假如外部10事件发生频率较高,实时任务的调度就无法得到保证。此外,当禁止中断后,其它更紧迫的外部事件发生时,也无法得到处理。为了解决这个问题,Ingo Molnar等人提出了中断线程化技术,把中断变为一个线程,不仅可以避免大量关闭中断的区域,让调度器能够更及时地启动,而且根据任务的实时要求给中断线程安排优先级。需要注意的是,并不是所有的中断都能被线程化,比如时钟中断、Bus Error等中断,所以需要结合实际情况线程化对系统的实时性提高有帮助作用的中断。

再次,Linux系统中主要的实时调度策略是SCHED-FIFO和SCHED-RR,但是对于某些特殊的应用环境,这两种实时调度策略并不能满足所有的实际需求。比如,一些有明确截止时间要求的任务的情况可以使用最早截止时间优先调度策略(EDF) [ 6 ] ^{[6]} [6],EDF算法使用比较普遍,这种算法根据任务的截止时限动态的分配优先级,所以是一种动态优先级调度算法。另外,该算法的实现可以提高Linux系统的实时性。

[6] sha L, Rajkumar R, Lehoczky J P. Priority inheritance protocols: an approach to real-time synchronization[J]. IEEE Transactions on Computers, 2002, 39(9):1175-1185.

最后,早期Linux内核中临界区是被禁止抢占的,系统中的临界区主要使用了自旋锁、大内核锁等,这些临界区不可抢占严重影响了系统的实时性,所以可以用优先级继承的mutex代替自旋锁和大内核锁,从而其它没有使用该共享资源的高优先级任务可以抢占用mutex锁保护的临界区。当然并不是所有的临界区都能被抢占,如寄存器存在的临界区,与之相关的锁也不进行互斥锁转换。mutex锁机制下的优先级反转是一个不可避免的问题,一般使用优先级置顶协议和优先级继承协议阻止不可预期的优先级反转问题。

除此之外,虚拟内存管理方式也是影响Linux实时性能的一个重要因素,进程运行在一个比实际内存大的虚拟内存中,虚拟内存引起的不确定性对实时系统是不能忍受的。实时操作系统一般采用在原有虚拟内存机制之上将实时任务使用的内存页面锁定防止换入换出,或者采用为每个实时任务划分固定的内存区域的静态内存划分方式来解决虚拟内存技术给实时操作系统带来的不可预测性。

2. 双内核方案

双内核实时方案实现比较复杂,需要保留原Linux内核的前提下,另外开发一个新实时内核,实时内核比原内核有更高的优先级,原来的内核作为优先级最低的一个任务在实时内核上运行。

目前国际上基于双内核方案的成熟实时Linux系统有RT-Linux,RTAl,Xenomai等。RT-Linux目前已被WindRiver公司收购,成为了一种不开源的商业实时操作系统,很难对其进行进一步深入研究。RTAI和Xenomai是目前主流的Linux内核接口API改进方案,都基于RT-Linux。

实时操作系统

RTOS的主要特征如下:
(1)实时性
实时操作系统在限定的时间内必须对实时任务做出及时的响应,只有符合时间约束的结果才是正确的。
(2)可靠性
实时操作系统的可靠性指在保证实时性的前提下,实时操作系统发生错误或者遇到故障时,系统仍然可以正常运行未出现致命错误的任务。
(3)可预测性
可预测性是实时操作系统的一个至关重要特征,尤其是hard-RTOS。可预测性在实时操作系统主要是指:可以计算出潜在最坏情况下任务的时限,从而保证所有的时限都得到满足。

对RTOS而言,系统的整体性能表现不是很重要,相反其更加关注最坏情况下某一个任务在规定时间内是否能顺利执行完成。

评价RTOS通常从最大中断禁止时间、上下文切换时间、内存开销、任务通信、内存管理、任务调度等几个方面来衡量,其中最大中断禁止时间和上下文切换时间是两个相对比较重要的评价指标。

Linux内核进程调度机制

目前Linux中普通进程使用CFS调度器,实时进程使用实时调度器。

Linux3.10.84调度器中实现了三种公平调度策略和两种实时调度策略,其调度器框架图如图所示:
在这里插入图片描述

调度策略数值含义
SCHED_NORMAI0用于普通进程,由完全公平调度类处理
SCHED_IDLE5在系统空闲时使用,由完全公平调度类处理
SCHED_BATCH3用于非交互的处理器消耗性进程,由完全公平调度类处理。不会抢占CFS调度器处理的另一个进程,因此不会干扰交互式进程
SCHED_RR2轮转调度算法(实时调度策略),用来实现软实时进程,由实时调度处理
SCHED_FIFO1先进先出调度算法(实时调度策略)用来实现软实时进程,由实时调度处理

模块化调度框架

Ingo Molnar [ 20 ] ^{[20]} [20]实现了Linux调度器的模块化,方便了调度器的扩展。

[20] Saez J C, Pousa A, Castro F, et al. ACFS: a completely fair scheduler for asymmetric single-isa multicore systems[J]. 2015:2027-2032.

进程调度所需的数据结构

1. 进程调度实体

Linux为了方便调度进程,在进程描述符task_struct中保存了两个调度实体:普通进程调度实体sched_entity和实时进程调度实体sched_rt_entiy

2. 就绪队列

每个CPU都有一个就绪队列runqueue,每一个处于就绪态的进程只能选择一个runqueue加入。

runqueue是全局调度的起点,进程仍然由各个调度类直接管理,runqueue中嵌入了特定于调度器类的子就绪队列。主要的数据结构是包含了每个调度类实现的特定的子运行队列,例如CFS调度器中的cfs_rq和实时调度器中的rt_rq。

3. 优先级

Linux中使用优先级来调度任务。实时进程使用进程描述符中的rt_priority成员保存静态优先级,取值范围是0~99,值为0表示非实时进程,1~99表示实时进程。普通进程的使用static_prio成员来保存静态优先级,取值范围是100~139,与nice值的-20~19相对应。

实时进程的99和普通进程的100都是各自最大的静态优先级,所以从静态优先级数轴上进行比较,实时进程段的rt_priority是单调递增的,而在普通进程段的static_prio是单调递减。

CFS进程调度

CFS调度器没有使用传统调度器中优先级队列来管理就绪进程,而是选择更便捷的红黑树2来管理就绪进程。CFS调度器引入了虚拟时间的概念,所有的就绪进程以其虚拟时间作为键值被挂到红黑树的结点上,通常红黑树最左边叶子节点上挂载虚拟时间最小的就绪进程。进程在调度时,CFS调度器选择最左边叶子节点上的进程作为下一个运行的进程。

CFS调度器把进程的静态优先级映射成进程权重需要使用常量数组sched prio_to_weight,Linux使用权重给进程分配CPU资源,而权重就是进程应该占有CPU资源的比重。例如:系统中有2个runnable任务A和B,对应的权重分别是a和b,那么A任务将会分配到 a/(a+b) 的CPU资源。因此CFS调度器的完全公平思想就是保证所有的可运行状态的进程按照自己的权重得到应有的CPU资源。

prio_to_weight数组用来存放普通进程每个优先级应该获得的权重,所以总共有40个,nice值和权重值成反比,nice值为-20的进程拥有最大权重,为88761,默认普通进程nice值为0的权重大小为:1024,prio-to-weight数组是一个等比数列,按因子1.25递减

实时进程调度

1.SCHED_FIFO
该调度策略没有时间片的概念,当调度器把CPU分配给进程时,该进程会一直占有CPU,除非该进程自愿让出CPU或者被其它高优先级任务抢占。

2.SCHED_RR
该调度策略有时间片的概念,并且其值在进程运行时递减,和普通进程类似。时间片递减到0后,将该值重置为初始值,并把该进程放在队列的末尾。

实时调度模块中实时进程需要严格遵循优先级队列,调度器选取优先级最高队列的第一个任务运行,当该进程耗尽其时间片时,该任务放将被放到对应的优先级队列的最后面。

SMP系统上的负载均衡

SMP表示对称多处理器,现在主流的操作系统都运行在SMP系统上。但是,SMP系统需要协调和控制各个任务尽可能的平均分配到每个CPU上,即负载均衡。

通常每个CPU上都有自己的可运行队列。一旦某个进程变为可执行状态,调度器会把该进程加入到某一个可运行队列(一个可运行状态的进程只能选择加入一个可运行队列),只有加入可运行队列的进程才有机会在对应CPU上得到调度。

CPU与可运行队列一对应的设计思想,主要有以下两个方面的好处:一是考虑局部性原理,即一个进程会尽可能的在同一个CPU上运行,这样可以将与其相关的数据缓存到此CPU的cache中;二是避免了各个CPU由于访问同一个可运行队列带来的锁竞争,一定程度上减小了调度延迟。

但是,这种方法有可能造成进程分配不合理。Linux内核引入了load_balance(负载均衡)来解决这个问题。load_balance的主要任务就是在某一特定的时机,将重负载CPU可运行队列上的进程迁移到另一个轻负载可运行队列上,来实现CPU之间的负载均衡。

实时进程负载均衡

SMP系统中,如果实时任务数量大于处理器数量,需要保证优先级最高的几个实时进程分别运行在每个处理器上;如果实时任务数量小于处理器数量,在保证每个实时任务有处理器运行的前提下,普通进程在剩余的处理器上运行。

假设SMP系统中,有N个处理器,把实时进程优先级处于前N个的进程称为top-N进程。

在CFS调度中假设某个进程的权重为m,所有处于运行状态的进程的权重之和为M,假设有N个处理器,则权重=m的进程可以分配到的CPU时间为Nm/M,这就是普通进程在SMP系统上的的负载均衡。为了让进程得到Nm/M的CPU时间,Linux把所有进程的权重平均分到每个run_queue上,使得每个run_queue的权重都等于M/N,这样每个run_queue的权重就成了CPU是否均衡的判断依据。

当出现负载不均时,load_balance函数被调用。该函数工作原理相对简单,只需要从负载最高的可运行队列中迁移部分进程到当前可运行队列中,使得当前可运行队列与负载最高的可运行队列上的进程数相近。load_balance函数在设计之初用了局部影响全局的思想,即load_balance函数首先保证当前CPU上的负载均衡,必然所有CPU都会调度load_balance函数,这样全局的负载均衡自然就实现了。这样的设计思想避免了直接全局负载均衡操作带来的资源浪费。

对内核的实时性改造

马啸. 基于Zynq平台的Linux实时性研究及在数据采集中的应用[D].兰州大学,2019

与实时相关的一个概念就是“抢占”,即系统有能在许多“抢占点”中断任务的能力。不可中断的程序单元越长,优先级较高的任务在启动或恢复之前的等待时间(“延迟”)就越长。GNU/Linux是“用户空间可抢占的":它允许用户任务在任何时候被中断。但是这种抢占程度依然不能保证系统是实时的。

实时最重要的方面,就是通过内核在任何地方都可以通过抢占来控制延迟。Preempt-RT通过重新实现实时互斥锁(rt_mutex)使内核里的自旋锁(spinlocks)可被抢占。如下图所示,在一段不重要的代码之后产生了一个紧急的中断。由于紧接着不重要代码之后的是一段关键的代码部分,所以中断处理函数并不能得到马上运行,需要在关键代码执行完之后才能运行中断处理函数并唤醒另外一个进程。
请添加图片描述

如果是实时内核,则内核增加了抢占点,则如图所示,在关键代码部分依然有很多可以抢占的位置,而非重要代码结束后系统产生的紧急中断则可以在这些抢占点处得到运行。通过这种增加抢占点的方式,使高优先级任务以及中断处理能够得到及时的响应。

请添加图片描述

线程化中断也是Preempt-RT使Linux实时化的的主要工作,使用中断处理线程来处理中断,使得中断处理程序可以在普通内核线程中运行,因此可以为其配置优先级。中断处理函数可分为上半部和下半部。在中断线程化后,其上半部依然做最小的工作,即回应中断,表示已经接收到了该中断,而中断下半部,则转化为内核线程用来处理中断。

请添加图片描述

Preempt-RT使Linux支持高精度时钟。Linux系统可以在体系架构和配置支持的情况下,将时钟频率从100HZ升级为1000HZ。相应的,定时器能够以1us 的精度运行。

Preempt-RT解决了优先级反转问题。优先级反转问题如图所示。一个低优先级任务获得了一个互斥锁,然后一个高优先级任务抢占了低优先级任务。但高优先级任务在执行了一段时间后也需要之前的互斥锁,此时高优先级任务便被锁住,只能等待低优先级任务释放互斥锁。低优先级任务在继续执行时,被一个中等优先级任务抢占,该中等优先级任务不需要互斥锁,因此可以持续运行。这相当于中等优先级任务既抢占了低优先级任务,也抢占了高优先级任务,于是发生了优先级反转问题。该问题造成了高优先级任务得到响应的延时增加。
请添加图片描述
为提高系统实时性,必须解决该优先级反转问题。优先级反转问题可由优先级继承来解决,即获得互斥锁的进程会继承等待锁的更高优先级的进程的优先级。如图所示,高优先级抢占低优先级任务之后,由于无法获得互斥资源便进入等待状态。原本的低优先级进程继承了此时高优先级进程的优先级后继续执行,当该进程释放了锁之后,就被高优先级进程抢占。通过这种方式,解决了高优先级进程被中等优先级进程抢占的问题。
请添加图片描述

EDF调度算法

最早截止期优先(EDF)算法按照绝对截止期增加的方向调度任务。任何时刻,从运行队列中选择的任务都是具有最早绝对截止时间的任务。

EDF通常与抢占式调度器一起使用,当任务的截止日期早于正在运行的任务时,后者将被暂停,并将CPU分配给刚到达的最早期限任务。该算法可用于调度周期性和非周期性任务,因为任务的选择仅基于绝对截止期。

CBS调度算法

CBS是一种动态上下文非周期性请求的服务机制。

Linux性能测试与分析

测试实时操作系统的方法与工具有很多,比如在资料 [ 38 ] ^{[38]} [38]中列举了大量的可用工具,资料 [ 39 , 40 ] ^{[39,40]} [3940]则介绍了常见的实时性能指标的测试方法。

[38] Weinheber P J, Boratko E C, Contreiras K D, et al. Best Practices for Formation Testing in Low-Permeability Reservoirs[C]//Society of Petroleum Engineers, 2008

[39] Buelna A, Lizárraga M L, Amaro v, et al. A Real-Time System Using the Preempt-RT patch and the RM, PIP and EDF scheduling policies[C]//IVCongreso Internacional De Robótica y Computación. 2017.

[40] Ip B. Performance Analysis of VxWorks and RTLinux[J]. Technical report, Department of Computer Science, Columbia University, 2002.

1)Ftrace

firace的作用是帮助开发人员了解Linux内核运行时的行为,以便进行故障调试或性能分析,基于静态代码插桩技术,不需要用户通过额外的编程来定义trace行为。ftrace是一个集成的framwork,支持很多trace功能,比如有irgsofftracer:跟踪中断、schedule switch tracer:跟踪进程调度情况和function tracer:跟踪函数调用等。

2)rt-tests

rt-tests是测试Linux内核实时性的一个工具集,里面包括很多测试工具集,但是cyclictest是rt-tests下使用最广泛的测试工具,一般主要用来测试内核的延迟,从而判断内核的实时性,本文主要使用cyclictest测试Linux内核的延迟。

3)trace-cmd和kernelshark

trace-cmd是Ftrace的前端工具,通常和开源解析工具kernelshark结合使用。本文主要使用trace-cmd监测实时任务在各cpu上的运行情况:进程上下文切换、进程迁移等,然后使用kernelshark图形化分析。

4)Lmbench

Lmbench是一套简易可移植的、符合ANSI/C标准为Linux而定制的微测评工具。它衡量的两个关键特征是反应时间和带宽,本文主要使用1mbench检测Linux内核的上下文切换时间。

仿真软件SimSO
利用基于Python的仿真软件SimSO中的RM调度算法和EDF调度算法进行仿真测试

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TI RTOS学习笔记是作者在学习TI-RTOS过程中记录的学习笔记。根据引用[1],在学习TI-RTOS之前,先要了解什么是RTOS,以及什么是TI-RTOSRTOS是实时操作系统(Real-Time Operating System)的缩写,它是一种专门用于处理实时任务的操作系统。TI-RTOS是Texas Instruments(TI)公司提供的一种RTOS,适用于TI系列的处理器和微控制器。 根据引用,作者在网上没有找到TI-RTOS的学习视频,但TI公司提供了许多相关的文档资料,因此作者选择通过阅读文档并记录笔记来学习TI-RTOS。 另外,引用中提到了TI RTOS SDK编译框架的介绍。TI RTOS SDK是TI公司提供的用于开发TI-RTOS应用程序的软件开发工具包。编译框架是指用于将源代码转换为可执行文件的编译和构建过程。通过学习和了解TI RTOS SDK的编译框架,可以更好地理解和使用TI-RTOS。 所以,TI RTOS学习笔记是作者记录的关于学习TI-RTOS笔记,包括对RTOS的理解、TI-RTOS的介绍以及TI RTOS SDK的编译框架的学习和总结。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [TI-RTOS学习记录(一)——初识TI-RTOS](https://blog.csdn.net/qq_43105170/article/details/126447116)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [TI RTOS SDK编译框架介绍](https://download.csdn.net/download/embededman/86951678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值