编辑推荐: |
本文主要介绍了Linux实时化与硬实时RTOS,重点关注 CPU 资源调度。希望能够帮助大家。
本文来自于知乎 ,由火龙果软件Linda编辑、推荐。 |
|
1.背景介绍
在工业控制领域 实时(Real Time) 是一个核心要求。
实时系统的定义:实时系统是指计算的正确性不仅依赖于逻辑的正确性而且依赖于产生结果的时间,如果系统的时间限制不能得到满足,系统将会产生故障。在工业领域这种故障可能造成灾难性的结果。
实时操作系统:该操作系统有能力提供一个指定范围内的服务响应时间。
一个 OS kernel 给程序员提供了一系列的服务,例如: multitasking、 interrupt
management、 inter-task communication and signaling、
resource management、 time management、 memory partition
management 等等。OS 的主要工作就是资源封装和调度,它提供对CPU、Memory、Storage、Network等资源的封装和调度。
对于 实时(Real Time) 这个课题来说,我们重点关注其中的 CPU 资源调度。
1.1 OS 实时难题
1、CPU 调度模型
在CPU资源调度方面,OS 主要提供一个多任务(multitasking)的运行环境,以方便应用的开发。在开发某个应用时首先把工作拆解成多个任务(Task/Thread),每个任务都可以简化成一个简单的无限循环:
void MyTask
(void)
{
while (1) {
Wait for an event to occur;
Perform task operation;
}
} |
对一个任务来说它好像独占CPU,但实际上是多个任务共享一个 CPU 的,由 OS Kernel 根据任务的状态和优先级来动态调度运行的:
可以看到OS对CPU调度提供了封装,站在OS之上可以很方便的开发、移植应用,应用只需要关注自己的 Task
循环,其他复杂操作对OS都是透明。但是另一方面,OS 的这些封装不可避免带来了开销,通常来说一个 CPU
上了 OS 以后会比裸机系统更慢,在频率较低的 MCU 系统上这些开销的占比会更为明显。
2、Event Driven
另一个重要的概念:任何一个系统都是事件驱动(Event Driven)的,准确来说是中断驱动的。
如上面代码所示,任务(Task)都是等待event,然后处理事务。任何一个任务得以运行,都是因为它收到了一个
Event,这个 Event 可能是一个中断、也可能是超时到期、还有可能是其他任务发出的IPC信号,继续追查发出IPC信号的任务最后的源头
Event 肯定是一个外部设备硬件中断 或者 是内部的 Timer中断。中断引起了 Event 传递,形成了逐个运行多个任务的链条(Chain)。一个系统内部会存在很多条这种链条。
3、Real Time
对实时(Real Time)系统来说,不仅仅要求OS能提供多任务环境,更要求任务能在极短的时间之内响应外部的中断事件。这个要求也充满了挑战,即要享受
OS 带来的好处,又要把 OS 带来的开销将到最小。
OS 实时模型的时序如上图所示,实时优化就是围绕这张图来展开的。其中的时间点和可能的优化方式如下:
1.2 Linux 实时补丁
大名鼎鼎的 Linux RT-Preempt Patch 试图从以下方面改善 Linux 的实时性:
实时补丁大大改善了 Linux 的实时性能,但还是软实时的水平。
1.3 Xenomai + Linux 双内核
优先处理实时任务,linux也被视为其中一个线程,本身也有调度器,但须等到没有实时任务时(空闲状态),才会执行linux
thread。
Xenomai + Linux 双内核可以达到 RTOS 的实时水平,也有把这种称为硬实时。
但是 RTOS 的实时还是存在不确定性,因为OS API等临界区的关中断时间还是存在不确定性,和系统的负载相关联。这也是
HW-RTOS 的优化点。
1.4 HW-RTOS
HW-RTOS (hardware real-time operating system,硬件实时操作系统)是一种基于硬件实现的实时操作系统,是瑞萨电子的专有技术。HW-RTOS支持大约30个api,都是通过硬件实现的。与传统的软件RTOS相比,硬件实现提供了极高水平的实时性能。
可以把HW-RTOS看作是CPU的硬件浮点单元(FPU),加速内核常用操作的专用硬件。然而,HW-RTOS并不执行基于软件的内核中通常可用的所有操作。这类似于浮点处理器,它只提供基本的浮点运算,如加、减、乘、除、从浮点数到整型和从整型到浮点数的运算,省略了更复杂的运算,如超越运算、对数运算和其他运算。在使用HW-RTOS作为骨干时,更复杂的内核操作通常可以在软件中实现。
HW-RTOS 主要利用了以下手段:
HW-RTOS 通过并行处理的方式,把 OS 调度类的负载从 CPU 上 Offload。
当上述的调度负载由软件来完成时,受当前资源多少的影响执行时间会变得不确定(例如:往一个排序链表中插入一个成员,消耗时间是不确定的)。但是
HW-RTOS 内部的硬件处理也是并行的,它不受当前资源多少的影响,所以它处理负载的时间可以做到接近恒定。
HW-RTOS实现了以下目标:
Fast
API execution with little fluctuation
Low interrupt latency with
low jitter
Very short interrupt disable
period |
从支持的设备来说,瑞萨的 RZ 系列 和 R-IN32M3 系列支持了 HW-RTOS 功能:
从支持的 OS 来说,目前 uITRON 和 μC/OS‑III 推出了支持 HW-RTOS 的版本,但是目前找不到具体的实例代码。μC/OS‑III
HW-RTOS 号称做到和原版 μC/OS‑III 的接口和体验一致:
接下来的章节,我们来详细的分析 HW-RTOS 实现的相关优化点。
1.5 More
需要特别注意的是,就算实现了 HW-RTOS 但是还是有影响实时的硬件因素存在:Cache Miss、TLB
Miss、分支预测失败、长跳转与短跳转、DVFS 等等。
航空航天等行业会使用专业的WCET(Worst-caseExecutionTime最坏执行时间)工具,对系统的实时性做一个全面分析。
2.优化点1:API
2.1 原理介绍
传统软件 OS API 会给系统来带开销,影响系统的性能和实时性,主要体现在两方面:
(1)、OS API 开销对实时性能的影响比大多数软件工程师认为的要大得多,并且发现很难保证最坏情况下的值。核心点就是
API 的函数复杂度是 O(n) 而不是 O(1)。
(2)、OS API 在执行期间为了保证一致性大部分情况下是关中断的,如果最坏情况下它的执行时间是难以预估的,那么它带来的最坏关中断时间也是不可预估的。
2.1.1 Software API Execution time
图3-1显示了日本最常用的RTOS——ITRON的API执行时间。包含“/D”的API是通过分派执行的API进程。图3-1的测量是在静态条件下进行的。
但是由于RTOS的执行时间取决于当前的内部状态,因此它们是动态波动的:
(1)、以Set Flag API执行时间为例。如图3-2所示。图中显示了所有Set Flag API的执行时间。但是,等待同一事件的任务越多,执行时间就越长。换句话说,执行时间会根据RTOS的内部状态而波动:
(2)、Wait队列的基本原理。如图3-3所示,RTOS的Wait队列运行在基于优先级的FCFS (First
Come, First Served)算法上。具体来说,每个对象为每个任务优先级级别都有一个队列(在本例中,优先级0被指定为最高优先级,优先级n被指定为最低优先级)。例如,要实现信号量,每个信号量标识符必须有n个队列。每个希望获取信号量的任务必须在队列中等待。当一个任务释放它的信号量时,优先级最高的队列头的任务被选中,该信号量被该任务获取:
(3)、Set Flag API 的关键流程如下。对于标志控制,系统必须在设置后比较等待标志模式和事件表中的标志模式,以确定释放等待的条件是否满足。换句话说,RTOS必须从图3-3中队列的头部开始依次检查每个任务,并比较标志模式。结果,Set
Flag系统调用的处理时间与等待相同标志的任务数量成比例显著增加,如图3-2所示。
因此,API执行时发生的RTOS开销会动态变化,以响应RTOS执行时的内部状态。通常,大多数设计人员希望系统调用执行在几百个时钟周期内得到结果。然而,现在很多人都没有意识到,某些条件的重叠可能会花费更多的时间。因此,当上面讨论的这些条件堆积起来时,开销会突然增加,这意味着某些过程不能在指定的时间限制内完成,从而导致实时系统的整体故障。
2.1.2 Software Influence of Queue Handling
如图3-3中Wait队列的逻辑结构所示,RTOS的每个对象都需要优先级队列。通常,软件中实现的队列使用列表结构。在RTOS中,TCB通过一个列表体系结构相互连接,以实现一个等待队列(TCB:
Task Control Block),图3-3中的队列实现如图3-4所示。当一个任务从Wait队列中取出时,优先级最高的队列头的任务将首先取出。因此,软件必须检查任务是否被添加到从最高优先级开始的队列中,以找到任务正在等待的最高优先级队列。作为结果,所需的处理时间会因队列条件的不同而有很大差异。
另一个问题出现了。在RTOS中存在大量的队列。例如,如果有64个信号量标识符、64个事件标识符和16个优先级级别,那么总数量将是64×2×16
= 2048个队列。因此,即使对象的数量相对较低,也需要大量的资源。图3-5显示了一个可能的改进。每个队列的尾部连接到下一个优先级下降的队列(即下一个较低的队列)头部的TCB。这个结构允许很容易地从Wait队列中删除任务,只需选择指针所指示的任务。它还大大减少了指针的数量。然而,如果仔细考虑,这种改进思想会导致在将任务添加到队列时进行大量处理。例如,当将优先级为7的任务添加到队列中时,搜索从队列头部开始,然后当搜索到达优先级为7的任务时,它将新任务添加到最后一个7级任务的末尾。
不管怎样,很明显,队列处理需要大量的处理时间,而时间将根据队列的条件而变化。此外,队列处理是一个非常重要的过程,因此在每个过程期间都禁用中断。
下面我们将探讨队列处理需要多少时间,并评估这对实时性能有多大影响。测试模型如图3-6 所示:
测试结果如下图所示:
伴随队列处理的API执行时间会根据RTOS中队列的状态急剧波动。此外,由此导致的中断禁用周期几乎与api执行时间一样长,因此中断禁用周期也可以根据RTOS队列内部状态动态波动。
因此,当大量任务被添加到队列中时,队列处理可能会产生意想不到的开销和意想不到的长中断禁用周期,从而可能导致实时系统中出现意想不到的错误。很有可能,应用程序和软件设计人员通常不会考虑RTOS中连接到队列的任务数量,但提前了解这些任务可能导致的问题真的很重要。
2.1.3 HW-RTOS API Execution time
HW-RTOS中调用api的方法如图4-1所示。如图所示,应用程序调用的API通过库软件作为硬件信号传递给HW-RTOS,返回值也通过库软件接收。库软件还根据HW-RTOS的指令执行调度过程。在图4-2中,我们可以看到HW-RTOS和传统软件RTOS(现在称为SW
RTOS)执行时间测量的比较。
HW-RTOS中的API执行时间非常快,大多数系统调用可以在10个周期内执行。然而,库软件的开销确实会增加执行时间,如图4-2所示。在HW-RTOS中,相同的API的执行时间不会因为内部状态而改变,就像在SW
RTOS中显示的设置标志一样。另一个巨大的优点是系统调用的最坏情况值可以在数据表中指定。
2.1.4 HW-RTOS Influence of Queue Handling
HW-RTOS使用瑞萨特有的“虚拟队列”技术实现硬件队列。Virtual Queue可以将任务添加到队列中,从队列中删除任务,也可以从队列中间删除任务,每个操作周期为2个周期。因此,无论队列的状态是什么,处理都可以在指定的时间内完成。
和软件方式在同样测试模型下的对比:
2.2 具体实现
HW-RTOS 通过硬件大概实现了 30 个 API 函数,具体包括以下几个方面:
Semaphore
Event flag
Mail box
Lock CPU and disable dispatch
Sleep / wakeup
Release waiting
Rotate ready queue
Change priority |
如下图所示,HW-RTOS作为系统总线上的一个外围模块来实现。
HW-RTOS为API调用实现了3个专门的寄存器:
API
register,
Argument register,
Result register |
瑞萨已经为处理这些寄存器准备了一个操作系统库。用户可以使用操作系统库轻松调用API调用,就像传统的软件RTOS一样。当调用set_flg
API调用时,OS库将参数写入参数寄存器,并将API的类型写入API寄存器。当HW-RTOS接收到这些信息时,它执行API并将返回值写入结果寄存器。OS库将返回值报告给调用方应用程序。执行API时可能需要进行任务切换。在这种情况下,HW-RTOS表示需要进行任务切换,并将下一个应该执行的任务的ID写入结果寄存器,以将该信息传递到OS库。OS库根据此信息执行上下文切换。
2.3 性能测试
上图显示了API执行时间。传统软件RTOS的执行时间用深紫色表示,HW-RTOS用浅紫色表示。HW-RTOS不仅比软件RTOS的执行时间短,而且波动也不大。
3.优化点2:Tick offloading
3.1 原理介绍
3.1.1 Software Tick
传统OS需要处理一些定时任务。包括定时器、sleep()、xxx_timeout()、时间片调度等。为了这个目的,测量时间的软件处理被周期性地激活。这就是所谓的Tick进程。如图所示,为了激活tick进程,需要周期性中断。
如上图图所示,虽然tick是一个不可或缺的功能,但它有以下三个缺点:
(1)、应用程序会周期性的停止,CPU的使用效率会降低。
(2)、由于节拍正在执行一个非常关键的进程,因此在进程执行期间禁用所有中断。因此,这对中断响应时间有负面影响。
(3)、由于滴答过程需要通过软件来实现,所以滴答间隔不可能非常短。换句话说,高度精确的时间管理是不可能的。
并且 Tick 的处理时长不是固定的。Tick进程检查处于等待状态的任务是否超时,因此当大量任务同时超时时,处理需求会增加。
3.1.2 HW-RTOS Tick
HW-RTOS完全在硬件上实现tick过程。这个功能被称为 tick offloading。tick过程在HW-RTOS内部执行。因此,不需要周期中断滴答,也不需要CPU执行滴答过程。如图所示,CPU在任何时候都可以自由运行应用软件。只有在通过超时执行上下文切换时才会停止。此外,由于滴答过程在非常高的速度执行,滴答间隔可以缩短。基于上述原因,与传统软件相比,tick
offloading可以提供以下优点。
No
drop in CPU efficiency caused by tick process
No interrupt disable period
caused by tick process
Large improvement in tick precision
|
|