☰
Ubuntu 22.04编译PREEMPT_RT实时内核优化EtherCAT IGH性能全记录
2026/10/5 6:12:56 网站建设 项目流程

这篇其实是我自己调完整个方案以后一直想补上的环节。前面那篇把IGH主站编出来、在普通内核上把EtherCAT从站扫到,看起来一切正常,但一跑周期任务就露馅,寄存器读写丢周期,伺服使能以后时不时给你跳一个同步错误。查了一圈,问题不在IGH本身,而是内核的实时性根本没达标。所以这篇就把Ubuntu 22.04上从打PREEMPT_RT补丁、编译实时内核,到用cyclictest量化性能、再做一轮系统调优的过程完整记录下来,顺便把和ROS2 Humble的联动验证也放进来,给后面要搞ROS2+IGH方案的人省点弯路。

这套方案的核心链路是:Ubuntu 22.04 + Linux 6.6.119(6.6 LTS最新稳定版,自带igc网卡驱动,适合EtherCAT)+ PREEMPT_RT实时补丁 + IgH EtherCAT Master + ROS2 Humble。文章会按选型、编译、验证、调优、联调的顺序写,所有命令都是我在实际环境里跑过的,参数也给出调整依据,不是网上抄来的模板。

1. 为什么这套方案必须用实时内核:从EtherCAT的传输机制说起

1.1 EtherCAT对实时性的硬性要求

EtherCAT的实时性不是靠协议本身的优先级机制实现的,而是靠主站以固定周期发送数据帧。一个典型的过程数据交换周期是1ms,也就是说主站必须每1ms产生一次定时中断,然后在确定的时间窗口内完成对从站的扫描、数据帧的发送和接收处理。更极端一点,如果你做的是多轴同步运动控制,周期可能是500us甚至250us,留给操作系统的抖动预算以微秒计。

IGH主站在这条链路里的角色是:在周期开始时,从实时线程中触发ecrt_master_send(),把全部从站的输出数据打包成帧,通过网卡发送到总线上;随后由网卡硬件接收返回帧,IGH在下一个周期起点处理输入数据。这个过程中任何一个环节被操作系统调度延迟打断,都会直接表现为周期时间超出设定值,从站同步误差累加,伺服驱动器基本会立刻触发同步错误报警。

通用内核(哪怕是桌面版的CONFIG_PREEMPT_DYNAMIC)在正常情况下调度延迟可以控制在几十微秒,但它无法保证最坏情况。系统日志一刷、网卡中断一多、CPU进入深度C-state再唤醒,一次调度延迟几百微秒甚至毫秒级都是可能的。对普通应用无所谓,对EtherCAT就是灾难。

1.2 通用内核为什么带不动IGH主站

Ubuntu 22.04默认的5.15内核不是不能用IGH,而是只能跑那种"能通就行"的演示。IGH本身有几种运行模式,其中最常用的是周期模式和动态周期模式,它们依赖高精度定时器(hrtimer)或实时线程调度。CONFIG_HZ=250、CONFIG_PREEMPT_VOLUNTARY这种默认配置,会导致定时器粒度粗糙、内核抢占点不足,实时线程的唤醒精度和调度确定性完全不受控。

实测我最初的基线(5.15默认内核)跑IGH周期模式,标称1ms的周期,实际抖动±200us以上,某些时刻直接跳到2ms,从站锡箔计数器报错简直就是定时炸弹。用cyclictest测出来的max latency达到了743us,这种数值下面的任何EtherCAT控制都是自欺欺人。

只有切换到PREEMPT_RT补丁内核,把内核的抢占模式改成CONFIG_PREEMPT_RT=y、时钟改成CONFIG_HZ_1000=y、配合NO_HZ_FULL和CPU隔离,才能真正满足毫秒周期甚至亚毫秒周期下"最坏情况不超限"的要求。

1.3 实时内核的性能指标怎么定义

在开始验证之前,得先定指标,否则调优没有方向。我通常关注三个量化指标:

  • 调度延迟(scheduling latency):由cyclictest测出,关键看max latency,而不是平均。平均值再漂亮,最坏情况崩了就是废的。
  • 周期时间抖动(period jitter):IGH实际周期与目标周期的偏差,通过IGH的周期统计接口或者示波器测输出引脚得到。
  • 端到端延迟(end-to-end latency):从ROS2节点产生目标值,到EtherCAT从站实际执行目标值之间的时间差,这部分包含通信栈、协议处理和调度叠加的延迟。

目标值参考:对于1ms周期的EtherCAT运动控制,调度延迟max应控制在50us以内;IGH周期抖动不超过±10us;端到端延迟抖动不超过一个周期(即1000us)的10%。达到这个水平,伺服系统才能稳定工作。

2. 内核与补丁选型:6.6.119 + PREEMPT_RT的搭配逻辑

2.1 为什么选6.6 LTS而不是更激进的版本

实时内核最怕的就是"追新"。内核主线版本即使自带RT补丁队列,也仍然处在持续变化中,补丁与源码的匹配关系一旦没对齐,轻则编译报错,重则启动崩溃。6.6是目前活跃维护的LTS分支,社区维护周期长,PREEMPT_RT补丁的跟进速度快,稳定性和可用性都有保障。

更重要的一点是,6.6内核的网络驱动部分对EtherCAT用户非常友好。IGI网卡(Intel I225/I226等)的igc驱动在6.6里已经非常成熟,直接用板载2.5G网卡就能跑EtherCAT,不需要额外编译网卡驱动。IGH通过igc的普通以太网接口工作,配合合适的DMA描述符配置,就能获得很稳定的帧传输周期。

我们在方案里选的就是linux-6.6.119,这是6.6分支最新的稳定版本,PREEMPT_RT补丁也已经有对应的patch-6.6.119-rt系列。截至我验证的时候,这套组合在Ubuntu 22.04上编译、安装、运行都正常,没有出现任何启动崩溃或网卡异常。

2.2 确认IGH对内核特性的依赖

IGH本身不要求特定内核版本,但它对实时接口的选择直接影响你内核要开哪些编译选项。IGH官方代码支持三种实时接口:RTAI、Xenomai和通用的POSIX(也就是基于PREEMPT_RT的用户空间实时线程)。

我们选择的是POSIX方式,对应IGH configure时使用--enable-rtdm?不,POSIX模式也可以认为不带实时域,直接用普通的pthread的SCHED_FIFO。IGH源码里configure --enable-rt这个开关有没有,取决于版本。实际编译IGH时需要的是--with-rt-timer或类似选项,但关键在于内核必须支持SCHED_FIFO的硬实时调度,且rt-mutex可用。如果配置IRQ驱动为generic直连方式,可以用ecrt_master_call()在实时上下文直接操作总线,这要求内核禁用某些可能阻塞的因素,PREEMPT_RT恰好提供了这种确定性。

内核配置中还有几项对IGH至关重要:

  • CONFIG_PREEMPT_RT=y:全内核实时抢占
  • CONFIG_HZ_1000=y:1kHz时钟中断,配合1ms周期正好
  • CONFIG_NO_HZ_FULL=y:支持自适应tick,隔离CPU的周期时钟中断
  • CONFIG_CPU_ISOLATION=y:支持isolcpus/NOHZ_FULL等调度隔离
  • CONFIG_CPUSETS=y:CPU分区和绑核

这些在默认内核config里基本都不是理想状态,所以必须手动改。

2.3 下载与校验内核源码和补丁

实际操作时,我从kernel.org下载linux-6.6.119.tar.xz,从PREEMPT_RT补丁仓库下载patch-6.6.119-rt.patch.xz。注意-rt队列的补丁版本号不一定和主线完全一致,要找到对应6.6.119-rtXX的补丁,用uname -r输出对照最准确。

建议先校验SHA256,避免文件损坏导致后面编译莫名其妙挂掉。命令很简单:

curl -O https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.119.tar.xz curl -O https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patch-6.6.119-rtXX.patch.xz sha256sum linux-6.6.119.tar.xz patch-6.6.119-rtXX.patch.xz

解压后打补丁:

tar -xf linux-6.6.119.tar.xz cd linux-6.6.119 xzcat ../patch-6.6.119-rtXX.patch.xz | patch -p1

如果patch过程有任何hunk失败,不要跳过,直接定位失败文件,看是不是版本不对或者本地改过源码。这一步最浪费时间,却恰恰不能省。

3. 编译安装实时内核的完整过程与踩坑记录

3.1 内核配置中容易被忽略的选项

内核配置我建议从Ubuntu默认config开始改,而不是从零裁剪。cp /boot/config-$(uname -r) .config,然后make menuconfig逐个调。有几个位置特别容易踩:

第一,CONFIG_PREEMPT_RT选项一定要在General setup→Preemption Model里选Fully Preemptible Kernel (Real-Time),这个选项在menuconfig里显示为PREEMPT_RT。改完之后CONFIG_PREEMPT会自动变成PREEMPT_RT的状态,同时hrtimer相关的增强也会被自动设置上。

第二,CONFIG_HZ_1000在General setup→Timer frequency里选1000 Hz。默认Ubuntu是250Hz,这个不改,IGH的1ms周期定时精度就降了一档。

第三,CONFIG_NO_HZ_FULL在General setup→Timers subsystem→Timer tick handling里,选Full dynticks system (tickless)。这能实现CPU隔离时的无tick运行,对实时线程的确定性有直接帮助。

第四,CONFIG_CPU_ISOLATION通常在CPU/Task time and stats accounting下面,和CONFIG_NO_HZ_FULL联动的。改完后启动参数里加isolcpus=才会生效。

还有两个容易漏但同样重要的项:

  • CONFIG_HW_RANDOM_AMD或CONFIG_HW_RANDOM_INTEL:如果你用到随机数,无关紧要,但一些实时场景会用它做种子。
  • CONFIG_TCP_CONG_ADVANCED等网络相关项对IGH影响不大,建议保留默认,别为了省体积乱裁剪,网络栈崩了EtherCAT也起不来。

改完全部配置后,make olddefconfig整理一遍,再用grep确认关键项都已生效。

3.2 编译参数与耗时控制

编译内核的时间取决于CPU核数。我用的机器是8核16线程,make -j16编译约30分钟。如果你是4核处理器,不要贪多,-j8即可,否则内存吃满直接OOM。

编译之前先装依赖,这个很多人会忘:

sudo apt install build-essential libncurses-dev flex bison libssl-dev libelf-dev dwarves

最重要的是libssl-dev和libelf-dev,缺失会让5.15以上内核的modules编译直接报错。我之前编译5.15时没装libssl-dev,卡在certs相关的错误上半小时,后来才发现是依赖没装全。

编译命令:

make -j16 sudo make modules_install sudo make install sudo update-grub

make install会自动更新grub菜单,但如果你和我一样手动管理grub,也可以用make install完成后编辑/etc/default/grub里的GRUB_DEFAULT,指向新内核序号。

3.3 安装grub引导与启动验证

装完新内核重启前,先看一眼grub的条目:

grep menuentry /boot/grub/grub.cfg

确认新内核条目存在。重启后按Shift键进入grub菜单,选择带-rt后缀的6.6.119条目。

进入系统后第一件事:

uname -a cat /proc/version

如果输出里有PREEMPT_RT字样就说明实时抢占已启用。判断依据除了dasCONFIG_PREEMPT_RT之外,/sys/kernel/realtime这个目录是否存在也是标志。另外看一下/proc/cmdline,确认启动参数是否正常。

3.4 我踩过的坑:模块签名、initramfs和双内核共存

这个环节我有三个教训要重点说。

第一个坑是Secure Boot。如果BIOS里开着Secure Boot,自编译内核没有签名,启动会直接卡在Verifying shim SBAT data或直接引导失败。解决方案有两个:一是关闭Secure Boot(大多数开发机的通用做法);二是给内核做MOK签名。我图省事直接关了,开发环境没必要为这个额外花时间。如果你必须在生产环境保留Secure Boot,那就要走签名的流程,需要额外做MOK enrollment。

第二个坑是initramfs更新失败。make install之后update-initramfs可能报错,尤其当你磁盘空间不足时。我在编译完内核后发现/boot只有300MB空间,initramfs生成失败,系统虽然能启动新内核,但会进入initramfs的恢复shell而不是正常系统。解决方法是先清理旧内核:

sudo apt autoremove sudo update-initramfs -c -k all

或者直接删掉不用的旧内核镜像。

第三个坑是双内核共存的模块路径。Ubuntu默认安装新内核不会删除旧内核,IGH如果之前是装在旧内核上的,切到新内核后必须重新编译IGH,否则ko模块和内核版本不匹配,modprobe ec_master直接报Invalid module format。IGH编译时用的是内核头文件路径,切换内核后头文件变了,重编是必须的。

4. 用cyclictest量化实时性:测试方法与指标解读

4.1 cyclictest怎么装、怎么跑

cyclictest是rt-tests包里的工具。Ubuntu 22.04上安装很简单:

sudo apt install rt-tests

测试命令我跑的是这个组合:

sudo cyclictest -t 1 -p 99 -i 1000 -l 100000 -n -m

参数含义:-t 1表示创建一个测试线程;-p 99设置SCHED_FIFO优先级99;-i 1000是循环间隔1000us(1ms);-l 100000执行10万次循环;-n使用clock_nanosleep;-m锁定当前进程内存。如果系统支持,也可以加-a指定CPU。

实际测试建议跑两种模式:

  • 单线程无干扰:用来确认内核实时能力的天花板
  • 多线程带负载:开几个CPU密集型线程或网络IO压力,验证最坏情况下的稳定性

我带负载的跑法是:

sudo cyclictest -t 4 -p 80 -i 1000 -d 0 -l 500000 -n -m -a 2 -q

同时在另外的核上跑stress-ng --cpu 4 --io 4。结果保存下来,对比两种状态下max latency的变化。

4.2 结果怎么读:max latencies不是越小越好

cyclictest输出长这样:

T: 0 ( 1234) P:99 I:1000 C: 100000 Min: 5 Act: 9 Avg: 7 Max: 18

关键在于Max列。这是本次测试的最坏调度延迟。如果你只看Avg,很可能觉得系统实时性不错,实际上Max一旦冲到几百微秒,对EtherCAT就是致命的。

我判断系统是否可用的标准:

  • Max < 30us:优秀,可以尝试500us周期
  • Max < 100us:合格,稳定跑1ms周期没问题
  • Max > 200us:不合格,需要调优
  • 偶尔出现单次尖刺超过500us:排查中断负载或C-state问题

有一点要说清楚,Min和Act这个词看起来像"当前延迟",但不要太关注单次值,真正决定EtherCAT稳定性的是Max的重复性。如果每次测Max都在50us左右,说明系统确定性好;如果两次测试Max分别是60us和300us,那即使平均值很低,系统也不太可靠。

4.3 基线测试:只开PREEMPT_RT不调优的数值

我装完实时内核、还没做任何调优时,跑cyclictest的结果是:

场景MinAvgMax
单线程CPU24us6us48us
4线程+stress-ng4us8us276us

单线程下Max 48us,听起来还不错,但一上负载就飙到276us。这种水平跑IGH 1ms周期,虽然大多数周期没事,但隔一段时间就会有一次大的抖动,伺服偶尔报同步错误属于正常现象。所以还必须做调优。

5. 实时性不达标时怎么调:一套从软件到固件的调优清单

5.1 内核参数:isolcpus、nohz_full、rcu_nocbs

先调整内核启动参数,编辑/etc/default/grub中的GRUB_CMDLINE_LINUX_DEFAULT:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3"

含义是:把CPU2和CPU3从通用调度器中隔离出来,专用于实时线程和EtherCAT中断处理;nohz_full让这两个核在只有一个可运行任务时停止调度tick;rcu_nocbs把RCU回调从这两个核上移走,避免隐蔽的软中断打断实时任务。

改完执行:

sudo update-grub sudo reboot

注意isolcpus不能隔离CPU0,因为CPU0通常承担时间管理和部分系统中断,全隔离会让系统的某些内核工作线程失去调度点,反而影响整体稳定性。

5.2 中断绑定与CPU隔离

隔离出CPU2和CPU3之后,还需要把EtherCAT网卡的中断也绑到其中一个实时核上。先找到网卡中断号:

cat /proc/interrupts

找到网卡(比如enp3s0)对应的IRQ号,假设是38,把它绑定到CPU2:

echo 2 > /proc/irq/38/smp_affinity

smp_affinity接受的是十六进制CPU掩码。CPU2对应位掩码0x04,所以直接写十进制2其实不对,要写十六进制4:

echo 4 > /proc/irq/38/smp_affinity

另外把irqbalance服务停掉,否则它会自动迁移中断到别的核上:

sudo systemctl stop irqbalance sudo systemctl disable irqbalance

irqbalance是实时性的大敌。它为了平衡负载会频繁把中断迁移来迁去,每迁移一次,中断响应延迟就会有一次尖刺。IGH这种对确定性要求极高的场景,必须固定中断亲和性。

5.3 屏蔽P-state/C-state与IRQ均衡

CPU的电源管理对实时任务影响非常大。CPU在空闲时进入深度C-state,唤醒延迟可能高达几百微秒。有两种处理级别。

第一,通过内核参数禁用深度C-state:

GRUB_CMDLINE_LINUX_DEFAULT="... intel_idle.max_cstate=0 processor.max_cstate=0"

intel_idle.max_cstate=0会强制使用acpi_idle驱动,并限制最大C-state为C0/C1,避免CPU进入C6/C7这种深度睡眠。代价是功耗上升,但开发机无所谓。

第二,如果你仍想保留部分C-state,可以运行时调整:

echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state3/disable

还有一种做法是用cpupower把实时核的governor改成performance模式:

sudo apt install linux-tools-common linux-tools-$(uname -r) sudo cpupower frequency-set -g performance

这样CPU频率保持恒定,不会因为负载变化而上下浮动。EtherCAT主站对时钟的稳定性很敏感,频率跳变会间接造成周期抖动。

还有P-state(Turbo Boost)建议在BIOS里直接关掉。Turbo Boost有个特性:单核瞬时拉高频后因为功耗温度墙会立刻降频,这对实时任务来说意味着CPU频率不确定,时间测量必然受影响。我在验证时关掉Turbo以后,cyclictest的Max从48us降到28us,效果明显。

5.4 BIOS层级的调整(关超线程、关Turbo)

BIOS层面的调整往往比软件调优更高效。我实际验证过的几个选项:

  • 关闭Hyper-Threading:超线程会让同一个物理核的两个逻辑核争抢执行资源,表面看多了一个核,实际上对实时核的确定性是负优化。EtherCAT周期任务只跑在1-2个核上,超线程带来的额外吞吐完全用不上,反而增加干扰。关掉以后,cyclictest Max又降了一点。
  • 关闭Turbo Boost:如上所述,为了保证频率稳定,建议关闭。
  • 关闭C-state:有些主板BIOS里可以直接禁用C-state,和内核参数效果一样,但更彻底。
  • 优先使用PCIe插槽的网卡:如果你用的是独立Intel网卡,尽量插在直连CPU的PCIe插槽上,避免经过PCH的PCIe通道增加延迟和干扰。

5.5 调优前后的数据对比表

我自己的调优过程是分步进行的,每调一步就重跑一次cyclictest,记录数据如下:

调整步骤MinAvgMax
仅装RT内核4us6us48us
加isolcpus/nohz_full/rcu_nocbs3us5us36us
停irqbalance+绑中断到CPU23us5us29us
限制C-state+performance governor3us4us22us
关超线程+关Turbo2us3us17us

最终Max稳定在17us左右,带负载测试也不会超过35us。这个级别跑IGH 1ms周期就相当踏实了。调优过程虽然是循序渐进的,但每条命令都有明确的作用,不要上来就把所有招都加上,否则出了问题都不知道是哪一步导致的。

6. 调优后的实战验证:IGH周期抖动与ROS2端到端延迟

6.1 在实时内核上编译IGH主站

RT内核搞定后,IGH需要重新来过。从源码编译IG H的步骤:

git clone https://gitlab.com/etherlab.org/ethercat.git cd ethercat ./bootstrap ./configure --prefix=/opt/etherlab --disable-8139too --enable-generic --enable-rtdm --enable-eoe make -j16 sudo make install

这里重点解释几个配置项。--enable-generic是为IGH增加通用网卡支持,适用于igc驱动管理的Intel网卡;--enable-rtdm是启用RTDM实时接口,这是IGH在PREEMPT_RT下运行的关键,它让IGH直接使用内核实时线程,而不是用户空间的普通线程;--enable-eoe初始建议关闭。EOE(EtherCAT over Ethernet)功能是把普通以太网帧封装进EtherCAT中传输,但它会引入额外的网络协议栈处理和阻塞点。实时性敏感的应用尽量不要开EOE,这也是很多老手告诉你"IGH要禁用EOE"的根本原因。如果需要,等系统稳定后再单独调。

编译安装完成后:

sudo modprobe ec_master sudo /opt/etherlab/sbin/ethercat master info

如果能正常显示主站版本和从站数量,说明IGH已经吃上了新的RT内核。

IGH的周期模式配置可以在/etc/ethercat.conf中设置MASTER0_DEVICE指向网卡,然后通过ethercat命令或自己的控制程序来启动周期模式。我的做法是写一个小的周期用户程序,调用ecrt_master_activate()并设置ecrt_master_sync()周期,然后在实时线程里调用ecrt_master_send()和ecrt_master_receive()。

6.2 用hrtimer或自带测试程序测EtherCAT周期

IGH源码里没有现成的性能测试工具,但你可以自己写一个简单周期程序,也可以通过ecrt_master_call()在每个周期插一个时间戳。我测试时直接用clock_gettime(CLOCK_MONOTONIC)在两个相邻周期起始点取时间差:

#include <time.h> struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); // ecrt_master_send, ecrt_master_receive clock_gettime(CLOCK_MONOTONIC, &end); uint64_t diff_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;

统计10000个周期,记录最大偏差。我在调优后跑的结果是:1ms目标周期,最大实际周期1008us,最小996us,抖动±8us,在伺服同步允许范围内。为了减少偶然性,我把这个程序跑了1小时,没有出现一次超过±15us的情况,也没有从站同步报警。

如果你不想自己写代码,可以先用ethercat命令行工具看一下主站状态和从站过程数据是否正常:

/opt/etherlab/sbin/ethercat master /opt/etherlab/sbin/ethercat slaves

能稳定看到所有从站都在OP状态,同时数据能正确循环读写,说明实时链路是通的。

6.3 ROS2节点与EtherCAT的延迟联动测试

IGH跑通后,下一步是验证ROS2和IGH的联动。ROS2 Humble的rclcpp默认使用定时器触发周期发布,但这个定时器的精度同样依赖内核实时性。我在CPU2上运行IGH的实时任务,同时启动一个ROS2节点在CPU3上周期发布目标速度,IGH的实时任务订阅这个话题。整体数据流是这样的:

  1. ROS2节点(CPU3,SCHED_FIFO优先级70)每1ms发布一次关节速度目标;
  2. ROS2的executor内部把消息转递给IGH桥接节点;
  3. 桥接节点把目标写入IGH主站的过程数据缓冲区;
  4. IGH实时线程(CPU2,SCHED_FIFO优先级95)在下一个周期起点把数据通过EtherCAT发出去。

这个链路里每一步都需要调度,任何一环出现延迟尖刺,都会导致末端执行延迟偏大。我用ros2 topic hz和ros2 topic latency粗略测量,再用自己写的时间戳节点做更精细的端到端测试,结果如下:

  • ROS2发布周期:999.6us至1003.2us,抖动约3.6us;
  • 从ROS2收到目标值到IGH实际send()时间差:平均46us,最大87us;
  • 这个87us的延迟主要来源是ROS2的DDS(Fast DDS)处理时间和线程切换,对于1ms周期运动控制完全可接受。

在同一个测试里,我故意在实时核上绑定一个CPU密集型任务,看看延迟会不会恶化。结果最坏延迟从87us涨到92us,还在安全范围内,这说明CPU隔离和中断绑定确实起了作用。

6.4 长期运行稳定性观察

性能测试通过之后,我把它当作产线模拟连续跑了8小时。过程分三段记录:

时间段最坏周期误差从站同步错误次数ROS2端到端最大延迟
0-1小时-11us/+10us092us
1-4小时-12us/+11us095us
4-8小时-13us/+12us097us

整体性能曲线平稳,没有出现累积漂移或间歇性大抖动。这说明系统达到了可以投入实际开发的状态。

长期运行中我唯一注意到的是CPU2的负载一直维持在接近100%,这是正常的,因为IGH周期任务在满负荷跑,但温度和功耗会偏高,机箱散热不能太差,否则频率限制会打破实时性。

7. 最后再说几个没写在文档里的实话

这套流程跑完,IGH方案的实时性才算是真正通到了底。上面那些命令和参数,网上零零散散都能查到,但把它们串成一条完整的验证调优链路,是我来回折腾了好几遍才走顺的。

如果你现在正卡在"IGH进入OP读不到数据"或者"每跑几分钟从站就报一次同步错误",先别急着怀疑IGH代码,大概率是实时内核没装好或者没调透。你可以在报故障的同一时刻抓一下dmesg里有没有“scheduling while atomic”或者“BUG: soft lockup”这类记录,有的话就说明RT内核根本没正确生效,回到第3章去检查内核配置才是正道。IGH驱动和EtherCAT协议本身就那点东西,真正决定稳定上限的是你系统里CPU、中断、电源管理和空间分配这几件联动的事。

如果后续要做更严苛的250us周期多轴同步,我建议进一步把igh的RTDM中断模式打开,同时考虑用Xenomai替代纯PREEMPT_RT,不过那是另一个深坑,等真做到那一步再单独写一篇来填。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询