Linux 实时/性能/网络 - 草稿


问题:“您可以采取哪些步骤来为您的 Linux 系统(运行 CODESYS 运行时)获得最佳性能?”

回答:“这不是那么简单......!但一步一步:......”

我可以做些什么来改进我的系统/运行时/IEC 应用程序的调度?

如果您的 IEC 应用程序对实时性有特定要求,很明显,底层操作系统和运行时系统必须有助于实现这些要求。

那么让我们从下到上逐步检查不同的级别:

  • 系统设置(Linux)
  • 运行时设置
  • IEC应用
  • 特定于现场总线(例如 EtherCAT / ProfiNet)

系统设置/基本配置:

您应该采取一些措施来设置和配置您的基本系统,这些措施非常重要。

  • 使用实时内核 我们建议为您的 Linux 系统使用 RT-Preempt 内核 ( https://rt.wiki.kernel.org )。 在 debian / ubuntu 发行版上,您可以找到一个 rt-kernel 作为包,可以通过“apt”轻松安装。有关详细信息,请参阅您的发行版手册。

    • 在 debian 系统上: sudo apt-get install linux-image-rt-amd64

    • 在 Ubuntu 系统上: sudo apt-get install linux-lowlatency

    • 您可以检查您正在使用的内核,例如使用命令 uname -a

  • 不要在您的系统上使用任何类型的窗口管理器/GUI/X-server 等 这可能会损害系统的实时能力(导致 IEC 应用程序出现高抖动)

  • 在内核/调度调控器中禁用节能模式: 例如:使用“性能”调度调控器(参见https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt) 也可以使用诸如“cpu-freq-utils”之类的工具。 这可能会干扰 intel pstate 驱动程序(它们通常需要不同的方法来固定 CPU 频率)。

您可以检查 scheduling/scaling_governor 与什么一起使用:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

您可以将它(作为 root/admin)设置为“performance”:

echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# set it for all available cores:
echo "performance" > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo "performance" > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
echo "performance" > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

请注意,如果您这样做,则需要在每次系统启动后设置 scaling_governor。您也可以通过内核配置来设置它。

“intel_pstate”内核驱动程序可能很难正确设置它 → 使用“cpufreq-info”仔细检查您的配置!

  • 尽可能禁用频率缩放/切换: 例如:设置最小和最大 CPU 频率。到固定值(切换 CPU 频率可能会导致系统抖动)

  • 隔离相关的 CPU(来自其他内核工作者/其他线程) 确定您希望高优先级作业在其上运行的相关 CPU,例如带有 EtherCAT 主站的 IEC 任务。 使用 CODESYS MultiCore 功能并将 IEC 任务固定到该内核。

然后还使用内核命令行参数“isolcpus”为内核隔离此 CPU → https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html?highlight=isolcpu

您的内核必须在启用 CONFIG "ISOL" 的情况下构建!

例如,可以添加以下作为内核参数来隔离 CPU 1 和 2:

isolcpus=1,2

如果您使用 GRUB(引导加载程序),您可以更改内核参数,例如

gksudo gedit /etc/default/grub

然后找到内核的命令行并添加参数“isolcpus”。 您可以在以下位置找到有关 GRUB 引导加载程序的更多信息: https: //www.gnu.org/software/grub/

  • 对于PC系统,我们进一步推荐:

    • 在 BIOS 中禁用 HyperV(如果可用)
    • 在 BIOS 中禁用所有节能模式(如果可用),例如检查 CPU 的“C/P”状态
  • 对于高级用户,我们建议深入研究内核配置的这些方面:

我们建议您深入研究这些主题/关键字,并检查您是否可以使用这些方面来进一步改进您的系统的实时功能。

  • PREEMPT_FULL
  • 独立CPU
  • rcu_nocbs
  • rcu_nocb_poll
  • 无软件锁定
  • irqbalance 禁用
  • kernel.sched_rt_runtime_us

您可以使用官方工具“ cyclictest ”验证系统的实时能力→ https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest/start

Cyclictest 是这个 debian 软件包的一部分:

sudo apt install rt-tests

如果您发现问题,我们建议使用像“ kernel trace / kernelshark ”这样的机制/工具:https://www.kernel.org/doc/html/latest/trace/index.html 使用这些工具,您可以识别可能的问题实时违规的罪魁祸首。

如果你想了解更多,我们推荐官方内核和 rt-preempt 文档:

Linux内核网络驱动:

如果涉及基于以太网的现场总线,当然网络驱动程序的性能也很重要。任何消息都不应“迟到”甚至丢失。

已知的问题:

我们知道,在内核和网络驱动程序的某些组合中,会发生不同的问题,导致以太网包丢失和/或消息发送/接收太晚。

我们在内核版本 5.10(更频繁)和 4.19(更少)中观察到了这种行为,具体取决于所使用的网络驱动程序(例如 intel e1000e 或 igb 内核驱动程序)。

→ 我们目前正在开发一些测试代码,您可以运行这些代码来检查您是否在您的系统上看到这种效果。

运行时设置

如果需要,您可以在 CODESYS 运行时系统中设置一些配置来影响实时能力:

  • 设置“disable_dma_latency”: 这可以防止 CPU 进入睡眠模式/节能模式并减少抖动。

您可以使用设置(cfg 文件)在 CODESYS 运行时启用此功能:

[SysCpuHandling]
Linux.DisableCpuDmaLatency=1
  • PLC shell 命令“irq-list”和“irq-setprio” 特别是对于基于以太网的现场总线,将网络驱动程序使用的中断优先级设置为与 IEC 任务相同的优先级(或更高)是有意义的使用这个。

IEC 应用配置

当然,以优化实时要求的方式配置 IEC 应用程序也很重要。

优先重点 不要指望系统一次关注太多“最高优先级”的事情。

问你自己:

  • 什么真正需要具有最高优先级?
  • 第二个最重要的方面是什么等等...

例如:仅配置具有最高优先级的单个方面。 例如,如果 EtherCAT 现场总线是您的 IEC 应用程序中最重要的参与者,您不应该在您的 IEC 应用程序中添加比它“更高优先级”的其他方面。

并行执行太多高优先级任务可能会损害系统的实时能力!

明智地选择优先事项

以合理的方式设置不同任务/方面的优先级(彼此相对但也绝对!)

将最高优先级任务配置为尽可能高,但尽可能低(相对于下一个优先级任务)。

IEC 任务优先级和 Linux 线程优先级的映射:

IEC Linux 优先级(默认)
- 88 (SCHED_FIFO)
- 57 (SCHED_FIFO)
0(最高实时优先级) 56 (SCHED_FIFO)
15(最低实时优先级) 41 (SCHED_FIFO)
16(非实时优先级) 0 (SCHED_OTHER)
31(非实时优先级) 0 (SCHED_OTHER)
- 0 (SCHED_OTHER)

提示

  • 默认的 linux 中断优先级是优先级“50”(这意味着 IEC 优先级“6”) 这通常包括网络中断(用于发送和接收网络包,例如 EtherCAT)→ 请参阅下面的章节了解详细信息

  • 16-31 的 IEC 任务优先级是非实时的(使用 SCHED_OTHER)并且“仅”映射到良好的级别。

EtherCAT 现场总线特定配置

如果您正在使用我们的 EtherCAT Master,您可能想要优化您的系统以供 EtherCAT 使用,并且有一些设置和提示如何实现这一点。

但是也有一些诊断机制可以帮助您检测出什么问题,例如,如果您发现包裹丢失、发送时间过长等。

要启用 EtherCAT Master 的增强调试机制,您必须设置一些“IEC 编译器定义”:

  • 右键单击您的应用程序→ 属性→ 构建: 并输入“ EtherCATPerformance, EtherCATSyncDebug”

要查看其他信息,您还应该启用通用选项编辑器: * 工具→ 选项→ 设备编辑器→ 显示通用设备配置视图

在观察窗口内,添加这些变量并观察它们:

变量的名称 描述
EtherCAT_Master.m_dwBeforeReadInputs 接收所有消息的时间(也包含 GetEthFrame)
EtherCAT_Master.m_dwBeforeWriteOutputs 状态机的时间
EtherCAT_Master.m_dwAfterWriteOutputs 发送所有数据的时间(也包含 SendEthFrame)
EtherCAT_Master.m_Master.m_dwSendEthFrame 运行时调用 Sendethframe 的时间
EtherCAT_Master.m_Master.m_dwGetEthFrame 运行时调用 getethframe 的时间
EtherCAT_Master.m_Master.m_diMaxSyncTime
EtherCAT_Master.m_Master.m_diMinSyncTime
EtherCAT_Master.m_Master.m_diSyncBuffer