大家好!我是大聪明-PLUS!
2025年10月,举行的"工业自动化:向开放式ICS过渡"论坛上,我与同事们就带有实时补丁的Linux进行了一次有趣的讨论。我们探讨了各种有趣的话题,包括使用虚拟机管理程序、核心分配以及与QNX的区别。我们还讨论了供应商何时会推出针对此类嵌入式系统的解决方案。我向同事们保证,基于Linux的操作系统开发人员会关注并处理所有社区请求,但正如常有的情况一样,工作量超出了团队的能力范围。
我们约定由我撰写一份简短指南,解释如何优化响应时间。我想指出的是,我并非试图证明安装了 PREEMPT_RT 补丁的 Linux 是一个真正的实时操作系统。在我看来,它并非如此,这是其设计使然,与 QNX、VxWorks 和 ThreadX 不同。
我将以 repka-pi 3 ver. 1.6 单板计算机为例,因为我会定期在其上测试软件。
1)安装带有 PREEMPT_RT 补丁的内核。
开发者们已经提供了一个包含 PREEMPT_RT 补丁的内核,我们对此非常感激。我们使用 repka-config 工具选择此内核。
选择 Linux 内核
等待安装完成并重启。之后,使用 *`uname -a` 命令检查所有组件是否已安装并启动。*并检查内核版本是否为 6.1.11-rt7。
2)删除不必要的应用程序和服务。
一切都很清楚很简单:占用处理器时间的应用程序越少越好。甚至可以安全地禁用图形用户界面。
3)规划政策的选择。
已安装的 PREEMPT_RT 补丁并未表明我们需要的应用程序运行在实时调度策略下,因为它运行在默认调度器 CFS(完全公平调度器)下。CFS 旨在确保所有进程获得公平的 CPU 时间,并使用红黑树数据结构来跟踪进程及其 CPU 时间。CFS 根据进程的权重和已使用的 CPU 时间量来分配 CPU 时间。
Linux 操作系统上可用的实时调度策略:
-
先进先出(FIFO)调度是一种简单的先进先出调度器,它将最高优先级分配给优先级最高的任务。FIFO 调度器用于确保实时任务能够获得足够的 CPU 时间,而不会被低优先级任务中断。在该策略中,任务的优先级从 1 到 99,1 为最低优先级,99 为最高优先级。
要查看 FIFO 调度器中正在运行的应用程序,可以使用以下命令:
ps -eLo rtprio,cls,pid,pri,nice,cmd | grep "FF" | sort -r -
RR------轮询调度算法。这种轮询调度器用于确保实时任务获得所需的 CPU 时间,同时避免牺牲低优先级任务的 CPU 时间。基于轮询调度,该算法会为循环队列中的每个任务分配固定的时间。当时间到期时,该任务会被移至队列末尾,下一个待执行的任务将获得其分配的时间,无论前一个任务是否已执行完毕。这确保了所有任务都能公平地获得 CPU 时间,并且不会出现任务没有分配到时间的情况。在该策略中,任务被赋予 1 到 99 的优先级,其中 1 为最低优先级,99 为最高优先级。
要查看 RR 调度器中正在运行的应用程序,可以使用以下命令:
ps -eLo rtprio,cls,pid,pri,nice,cmd | grep "RR" | sort -r -
EDF(提前截止优先)采用基于截止时间的调度算法,确保进程满足其截止时间要求。截止时间调度器针对需要保证 CPU 时间的实时应用程序进行了优化。截止时间调度策略使用 GEDF(全局提前截止优先)算法实现,该算法根据进程的截止时间分配 CPU 时间。GEDF 算法通过尽早将进程调度到 CPU 来确保进程满足其截止时间要求。
一次性任务由一系列子任务组成,每个子任务在每个周期内最多激活一次。每个子任务都有一个相对截止时间**,** 表示其完成时间,以及一个计算时间**,** 表示执行该子任务所需的处理器时间。由于有新任务需要执行,子任务准备就绪的时刻称为到达时间**。** 开始时间表示 子任务开始执行的时间。因此,绝对截止时间由相对截止时间加上到达时间确定**。**

提前截止
使用 sched_setattr 系统调用配置线程时,您可以指定三个参数:运行时(Runtime )、截止时间(Deadline )和周期(Period)。
这些设置可能并不总是符合前面提到的条件:通常,执行时间设置为高于平均处理时间(或最坏情况执行时间),截止时间设置为与相对截止时间相匹配,周期设置为与任务持续时间相匹配。
要使用此类调度程序运行应用程序,请使用以下命令:
chrt -d -T <runtime> -D <deadline> -P <period> <command> <command options>在哪里:
-
运行时间:分配给任务的执行时间。
-
截止日期:任务必须在期限开始后的多长时间内开始并完成。
-
周期:执行该操作需要多长时间才会重复执行。
所有数值均以纳秒为单位。
必须遵循以下规则:运行时长 <= 截止时间 <= 周期。
省略任何参数都将导致以下结果:
-
如果省略运行时值,则运行时将设置为截止时间值。
-
如果省略截止日期时间值,则截止日期将设置为周期值。
-
如果省略"周期"时间值,则"周期"将设置为"截止日期"值。
应用程序启动语句示例:
chrt -d --sched-runtime 1000000 --sched-deadline 5000000 --sched-period 5000000 ./имя_приложения要查看在 EDF 调度程序(deadline)中运行的应用程序,可以使用以下命令:
ps -eLo rtprio,cls,pid,pri,nice,cmd | grep "DL" | sort -r
值得注意的是,操作系统中包含使用不同调度策略运行的应用程序,而这些调度策略各自具有不同的优先级:
-
EDF------首要任务。
-
先进先出/轮转 - 第二优先级。
-
CFS - 第三优先级。
例如,优先级为 99 且通过 FIFO 或 RR 调度的任务不会中断通过 EDF 调度器启动的正在运行的任务。只有通过 EDF 调度且截止时间更近的任务才能中断它。此外,使用高于 90 的优先级时要格外小心,因为这可能会导致与操作系统进程冲突。
在启动所需应用程序之前,您应该在 limits.conf 文件中配置用户限制:
sudo` nano /etc/security/limits.conf `
我们在这里添加两行:
保存文件,为了以防万一,重启操作系统或重新登录,然后在所需的调度程序中启动所需的应用程序。
4)禁用CPU频率调节。
CPU频率在运行过程中可能会发生变化,从而改变硬件性能。

CPU频率调节
为此,您需要安装 cpufrequtils 软件包。为此,请使用以下命令:
sudo` apt install cpufrequtils `
让我们编辑 cpufrequtils 配置文件
ENABLE="true"`
`GOVERNOR="schedutil"`
`MAX_SPEED="648000"`
`MIN_SPEED="648000"` `
可用的州长选项:
-
性能 --- 将频率固定在允许的最大值。
-
节能模式 - 固定最低频率
-
按需模式 - 在可用范围内,根据负载动态提高频率(平衡性能和功耗)。
-
保守型------类似于按需模式,但频率变化更平滑,避免突变。
-
Schedutil 是一种现代算法,它利用 Linux 任务调度器数据来优化频率。
保存文件后,重启操作系统并检查一切是否正常运行。
5)CPU核心隔离
需要注意的是,通过 taskset 进行分配时,操作系统可能会将其他任务分配给这些核心。
为防止这种情况发生,您需要更改内核启动参数。
6) 设置 I/O 操作的优先级
c1 是一个实时类。
n0 是 I/O 调度优先级,取值范围为 0 到 7,其中 0 为最高优先级。
以上所述只是普通用户解决自身问题的一些方法。
必须理解,所有组件及其之间的交互对于开发实时系统都至关重要。仅仅使用实时操作系统(RTOS)并非万能灵药;必须正确使用,并且在为其开发的软件中必须考虑其功能和局限性。