PREEMPT-RT中断线程化原理与中断线程优先级设置


本文介绍实时linux方案PREEMPT-RT提升系统实时性的机制之一–中断线程化,以及中断线程优先级配置,希望能为感兴趣的读者提供些许参考。

什么是实时
实时分类
常见的RTOS
latency和jitter

一、什么是中断线程化

1. 普通Linux中断处理

中断是一种异步事件处理机制,用于响应硬件请求,它会打断进程的正常调度和执行,然后调用内核中断处理程序来响应设备的请求。

由于中断处理程序会打断其他进程的运行,所以,为了减少对正常进程运行调度的影响,中断处理程序就需要尽可能快地运行。如果中断本身要做的事情不多,那么处理起来也不会有太大问题;但如果中断要处理的事情很多,中断服务程序就有可能要运行很长时间。特别是,中断处理程序在响应中断时,还会临时关闭中断。若中断任务繁重,这就会导致上一次中断处理完成之前,其他中断都不能响应,甚至丢失中断。

所以Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:

  • 上半部:快速处理硬件中断,inux不支持中断嵌套,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作,即硬中断(Interrupt Request,IRQ)。
  • 下半部:延迟处理上半部遗留任务,通常以内核线程方式运行,即软中断(SoftIRQ)。

硬中断处理程序(ISR)迅速响应硬件事件,执行最少工作,大部分任务推迟至软中断SoftIRQ或任务队列workqueue。

软中断是一种机制,用于在稍后执行较耗时的中断处理任务。一般以内核线程的方式执行,并且每个 CPU 都对应一个软中断内核线程,名字为 “ksoftirqd/CPU 编号”,如0 号 CPU 对应的软中断内核线程的名字就是 ksoftirqd/0。软中断在软中断上下文运行,执行时机有2个,一个是硬件中断返回后立即执行,这时和硬件中断一样,完全抢占进程上下文,不允许被调度和抢占,其执行时间为不超过2ms,如果执行的软中断超过了2ms会将软中断延迟到软中断线程 “ksoftirqd/CPU 编号”中执行

系统中软硬件中断通过proc 文件系统来查看:

  • /proc/softirqs 提供了软中断的运行情况;

  • /proc/interrupts 提供了硬中断的运行情况。

2. 实时性的不足

传统的中断处理方式虽然提升了系统的吞吐量,但从实时任务响应实时性方面来看存在以下不足:

  • 中断禁用:inux不支持中断嵌套,在硬中断处理过程中,其他中断会被屏蔽,增加了延迟。
  • 中断串行处理:inux不支持中断嵌套,同一cpu上的外设中断处理串行执行,这在非紧急外设中断多的情况下导致紧急外设中断处理的不确定性。
  • 不可预知的延迟:不同的驱动程序,硬中断处理程序执行需要的时间不同,不可预知,可能导致高优先级任务被中断抢占延迟执行,影响任务的实时性能。
  • 软中断的不确定性:软中断在硬中断退出后前期处理是完全抢占进程上下文的,它的处理时间和调度顺序也可能影响到实时任务的执行。

image-20241216221938065

这些不足使得普通linux中断处理方式难以满足高实时性要求的应用场景。

3. 中断线程化

为了解决上述问题,PREEMPT-RT补丁引入了中断线程化机制,于2009年合入linux主线版本2.6.30。顾名思义就是将原来硬件中断上下文的中断处理的部分也通过一个内核线程来处理,除了代码中明确指明非中断线程化的中断和系统硬件timer中断外的中断均通过中断线程来处理,中断线程默认是一个实时线程,调度类为SCHED_FIFO,实时优先级为50。同时将SoftIRQ全部放到ksoftirqd/CPU线程中执行,ksoftirqd/CPU为普通非实时任务不变。通过ps命令可以看到中断线程。

ubuntu@work-host:~$ ps -ef | grep irq
root          14       2  0 12月10 ?      00:02:44 [ksoftirqd/0]
root          19       2  0 12月10 ?      00:00:08 [irq_work/0]
root          25       2  0 12月10 ?      00:00:00 [irq_work/1]
root          28       2  0 12月10 ?      00:00:00 [ksoftirqd/1]
root          33       2  0 12月10 ?      00:00:04 [irq_work/2]
root          36       2  0 12月10 ?      00:02:47 [ksoftirqd/2]
root          41       2  0 12月10 ?      00:00:01 [irq_work/3]
root          44       2  0 12月10 ?      00:03:09 [ksoftirqd/3]
root          49       2  0 12月10 ?      00:00:04 [irq_work/4]
root          52       2  0 12月10 ?      00:02:42 [ksoftirqd/4]
root          57       2  0 12月10 ?      00:00:02 [irq_work/5]
root          60       2  0 12月10 ?      00:02:28 [ksoftirqd/5]
root         121       2  0 12月10 ?      00:00:00 [irq/9-acpi]
root         136       2  0 12月10 ?      00:00:00 [irq/120-PCIe PM]
root         137       2  0 12月10 ?      00:00:00 [irq/121-PCIe PM]
root         138       2  0 12月10 ?      00:00:00 [irq/121-aerdrv]
root         139       2  0 12月10 ?      00:00:00 [irq/121-s-aerdr]
root         140       2  0 12月10 ?      00:00:00 [irq/122-PCIe PM]
root         141       2  0 12月10 ?      00:00:00 [irq/122-aerdrv]
root         142       2  0 12月10 ?      00:00:00 [irq/122-s-aerdr]
root         143       2  0 12月10 ?      00:00:00 [irq/123-PCIe PM]
root         144       2  0 12月10 ?      00:00:00 [irq/123-aerdrv]
root         145       2  0 12月10 ?      00:00:00 [irq/123-s-aerdr]
root         149       2  0 12月10 ?      00:00:00 [vfio-irqfd-clea]
root         150       2  0 12月10 ?      00:00:00 [irq/8-rtc0]
root         229       2  0 12月10 ?      00:13:52 [irq/124-xhci_hc]
root         230       2  0 12月10 ?      00:00:00 [irq/16-i801_smb]
root         281       2  0 12月10 ?      00:00:00 [irq/126-ahci[00]
root         746       2  0 12月10 ?      00:00:00 [irq/142-mei_me]
root        1089       2  0 12月10 ?      00:00:05 [irq/143-i915]
root        1105       2  0 12月10 ?      00:00:00 [irq/144-snd_hda]
root        1465       1  0 12月10 ?      00:01:24 /usr/sbin/irqbalance --foreground
root        1731       2  0 12月10 ?      00:00:20 [irq/125-eno1]
root        1734       2  0 12月10 ?      00:00:00 [irq/127-enp2s0]
root        1735       2  0 12月10 ?      00:00:04 [irq/128-enp2s0-]
....

中断线程化通过以下方式提升了Linux系统的实时性:

  • 减少中断禁用时间:由原本整个硬件中断处理过程都需要屏蔽全局中断,变成仅响应中断,唤醒中断线程部分会屏蔽全局中断,这部分只执行最少量的处理,减少了中断禁用的时间,降低了整体延迟。
  • 优先级管理:中断处理程序作为内核线程,基本不会屏蔽全局中断,并且不同优先级的外设中断线程,可以被赋予不同的优先级,从而避免低优先级的外设中断阻塞高优先级外设、任务的执行。
  • 可抢占性:中断线程作为可调度的内核线程,可以被高优先级任务抢占,使系统响应更加灵活和实时。
  • 可预期性增强:中断处理时间变得更加可控和可预见,提高了系统的实时性能。
    -系统吞吐量降低:中断线程化后,CPU上下文切换增多,那 CPU 的处理效率就会打一定折扣。
    image-20241216221938065

通过这些改进,PREEMPT-RT的中断线程化机制有效地解决了传统中断处理方式在实时性上的不足,使Linux系统能够更好地满足高实时性应用的需求。

二、中断线程优先级配置

所有外设的中断线程默认一个实时线程,调度类为SCHED_FIFO,实时优先级为50,对于实时性要求高的外设应该设置更高的优先级,如何才能修改中断线程的优先级?方式有两种,第一种最直接的办法,驱动代码中添加代码修改,但这样不灵活。另外一种是通过chrt工具来修改。

使用chrt修改中断线程优先级

例如,要将PID为1234的线程的实时优先级设置为50,可以执行以下命令:

chrt -f -p 50 1234

这里,-f表示设置实时优先级,-p表示操作对象是进程。同样,只有root用户才能修改线程的实时优先级。

注意:在使用这些命令时,请确保已正确指定PID,以免对其他进程造成不必要的影响。
但直接使用chrt还是太原始,下面我给大家推荐一个工具–rtirq。

使用rtirq修改中断线程优先级

安装rtirq

如果你使用的是debian衍生发行版,还可以通过rtirq这个工具来修改中断线程优先级,直接从github拉取

git clone https://github.com/rncbc/rtirq

或者通过apt软件包管理器安装

sudo apt install rtirq-init

注意:rtirq工具依赖完整功能的ps和chrt,所以在一些使用busybox嵌入式系统中由于ps功能简单,rtirq运行不了。

rtirq使用说明

我们来看看rtirq-init是如何工作的,rtirq是一个脚本,位于/etc/init.d/rtirq,位于/etc/init.d目录下的的脚本系统启动后会自动执行,首先读取解析配置文件,然后根据配置文件来修改中断线程的优先级和调度策,最终执行的也是chrt命令,只不过它通过配置文件的方式提供了更多的灵活性配置,你可以自行分析脚本源码。
脚本/etc/init.d/rtirq接收的参数有startstopresetrestart(或)force-reloadstatus
rtirq脚本执行时使用的配置文件依次为为/etc/sysconfig/rtirq/etc/default/rtirq/etc/rtirq.conf,前一个存在后面的就不生效。其中/etc/default/rtirq是安装后自动生成的模板文件,你可以直接修改它或者基于它重新新建一个。

rtirq配置

/etc/default/rtirq内容如下:

# 我们要修改的IRQ线程服务名称,按下面的优先级及步长依次配置
# (从优先级高到低,以空格分隔列表)。
# RTIRQ_NAME_LIST="rtc snd usb i8042" #旧版本
RTIRQ_NAME_LIST="snd usb i8042"

# 最高的优先级。
RTIRQ_PRIO_HIGH=90

# 优先级递减步长。
RTIRQ_PRIO_DECR=5

# 最低的优先级。
RTIRQ_PRIO_LOW=51

# 是否将所有 IRQ 线程重置为 SCHED_OTHER。
RTIRQ_RESET_ALL=0

# 当内核支持时,
# 哪些服务不应被线程化(以空格分隔列表)。
RTIRQ_NON_THREADED="rtc snd"

# 将被强制到最高实时优先级范围内的进程名(99-91)(从高到低,以空格分隔列表)
# RTIRQ_HIGH_LIST="timer"
  • RTIRQ_NAME_LIST表示我们要修改的中断线程集合,按优先级从RTIRQ_PRIO_HIGH到RTIRQ_PRIO_LOW高顺序排列,示例中的是snd(90)>usb(85)>i8042(80);
  • RTIRQ_PRIO_HIGH表示第一个RTIRQ_NAME_LIST中第一个中断线程的优先级;
  • RTIRQ_PRIO_DECR表示RTIRQ_NAME_LIST中的中断线程优先级从高到低的步长;
  • RTIRQ_PRIO_LOW表示最低优先级;
  • RTIRQ_RESET_ALL是否将RTIRQ_NAME_LIST外的所有 IRQ 线程重置为 SCHED_OTHER
    如果我们不知道 IRQ 线程的名称,可以通过执行/etc/init.d/rtirq status来获取,同时能看到系统中中断线程的默认优先级:
ubuntu@work-host:~$ /etc/init.d/rtirq status
    PID CLS RTPRIO  NI PRI %CPU STAT COMMAND
   1105 FF      90   - 130  0.0 S    irq/144-snd_hda
    229 FF      85   - 125  0.1 S    irq/124-xhci_hc
    121 FF      50   -  90  0.0 S    irq/9-acpi
    136 FF      50   -  90  0.0 S    irq/120-PCIe PM
    137 FF      50   -  90  0.0 S    irq/121-PCIe PM
    138 FF      50   -  90  0.0 S    irq/121-aerdrv
    150 FF      50   -  90  0.0 S    irq/8-rtc0
    230 FF      50   -  90  0.0 S    irq/16-i801_smb
    281 FF      50   -  90  0.0 S    irq/126-ahci[00
    746 FF      50   -  90  0.0 S    irq/142-mei_me
   1089 FF      50   -  90  0.0 S    irq/143-i915
   1731 FF      50   -  90  0.0 S    irq/125-eno1
....
   1757 FF      50   -  90  0.0 S    irq/141-enp4s0-
     14 RR       1   -  41  0.0 S    ksoftirqd/0
     28 TS       -   0  19  0.0 S    ksoftirqd/1
     36 TS       -   0  19  0.0 S    ksoftirqd/2
     44 TS       -   0  19  0.0 S    ksoftirqd/3
     52 TS       -   0  19  0.0 S    ksoftirqd/4
     60 TS       -   0  19  0.0 S    ksoftirqd/5
....

示例

  1. 先将所有线程优先级配置为0,配置文件如下:
....
# Whether to reset all IRQ threads to SCHED_OTHER.
RTIRQ_RESET_ALL=1
...

执行:

ubuntu@work-host:~$ sudo /etc/init.d/rtirq reset
ubuntu@work-host:~$ sudo /etc/init.d/rtirq status

    PID CLS RTPRIO  NI PRI %CPU STAT COMMAND
     14 TS       -   0  19  0.0 S    ksoftirqd/0
     28 TS       -   0  19  0.0 S    ksoftirqd/1
     36 TS       -   0  19  0.0 S    ksoftirqd/2
     44 TS       -   0  19  0.0 S    ksoftirqd/3
     52 TS       -   0  19  0.0 S    ksoftirqd/4
     60 TS       -   0  19  0.0 S    ksoftirqd/5
    121 TS       -   0  19  0.0 S    irq/9-acpi
    137 TS       -   0  19  0.0 S    irq/120-PCIe PM
    138 TS       -   0  19  0.0 S    irq/121-PCIe PM
    139 TS       -   0  19  0.0 S    irq/121-aerdrv
    140 TS       -   0  19  0.0 S    irq/121-s-aerdr
    141 TS       -   0  19  0.0 S    irq/122-PCIe PM
    142 TS       -   0  19  0.0 S    irq/122-aerdrv
    143 TS       -   0  19  0.0 S    irq/122-s-aerdr
    144 TS       -   0  19  0.0 S    irq/123-PCIe PM
    145 TS       -   0  19  0.0 S    irq/123-aerdrv
    146 TS       -   0  19  0.0 S    irq/123-s-aerdr
    151 TS       -   0  19  0.0 S    irq/8-rtc0
    251 TS       -   0  19  0.0 S    irq/125-xhci_hc
    252 TS       -   0  19  0.0 S    irq/16-i801_smb
    299 TS       -   0  19  0.0 S    irq/126-ahci[00
    776 TS       -   0  19  0.0 S    irq/142-mei_me
   1121 TS       -   0  19  0.0 S    irq/143-i915
   1136 TS       -   0  19  0.0 S    irq/144-snd_hda
   1798 TS       -   0  19  0.0 S    irq/124-eno1
   1799 TS       -   0  19  0.0 S    irq/127-enp2s0
   1800 TS       -   0  19  0.0 S    irq/128-enp2s0-
   1801 TS       -   0  19  0.0 S    irq/129-enp2s0-
   1802 TS       -   0  19  0.0 S    irq/130-enp2s0-
   1803 TS       -   0  19  0.0 S    irq/131-enp2s0-
   1808 TS       -   0  19  0.0 S    irq/132-enp3s0
   1809 TS       -   0  19  0.0 S    irq/133-enp3s0-
   1810 TS       -   0  19  0.0 S    irq/134-enp3s0-
   1811 TS       -   0  19  0.0 S    irq/135-enp3s0-
   1812 TS       -   0  19  0.0 S    irq/136-enp3s0-
   1822 TS       -   0  19  0.0 S    irq/137-enp4s0
   1823 TS       -   0  19  0.0 S    irq/138-enp4s0-
   1824 TS       -   0  19  0.0 S    irq/139-enp4s0-
   1825 TS       -   0  19  0.0 S    irq/140-enp4s0-
   1826 TS       -   0  19  0.0 S    irq/141-enp4s0-
  1. 修改rtc0、enp4s0的中断线程优先级,配置文件如下:
# IRQ thread service names
# (space separated list, from higher to lower priority).
# RTIRQ_NAME_LIST="rtc snd usb i8042" # old
RTIRQ_NAME_LIST="rtc enp4s0"

# Highest priority.
RTIRQ_PRIO_HIGH=90

# Priority decrease step.
RTIRQ_PRIO_DECR=5

# Lowest priority.
RTIRQ_PRIO_LOW=51

# Whether to reset all IRQ threads to SCHED_OTHER.
RTIRQ_RESET_ALL=0

# On kernel configurations that support it,
# which services should be NOT threaded
# (space separated list).
#RTIRQ_NON_THREADED="rtc snd"

# Process names which will be forced to the
# highest realtime priority range (99-91)
# (space separated list, from highest to lower priority).
# RTIRQ_HIGH_LIST="timer"

执行

ubuntu@work-host:~$ sudo /etc/init.d/rtirq start
Setting IRQ priorities: stop [rtc] irq=8 pid=151: OK.
Setting IRQ priorities: stop [enp4s0] irq=137 pid=1822: OK.
Setting IRQ priorities: stop [enp4s0] irq=138 pid=1823: OK.
Setting IRQ priorities: stop [enp4s0] irq=139 pid=1824: OK.
Setting IRQ priorities: stop [enp4s0] irq=140 pid=1825: OK.
Setting IRQ priorities: stop [enp4s0] irq=141 pid=1826: OK.
ubuntu@work-host:~$ sudo /etc/init.d/rtirq status

    PID CLS RTPRIO  NI PRI %CPU STAT COMMAND
    151 FF      90   - 130  0.0 S    irq/8-rtc0
   1822 FF      85   - 125  0.0 S    irq/137-enp4s0
   1823 FF      84   - 124  0.0 S    irq/138-enp4s0-
   1824 FF      83   - 123  0.0 S    irq/139-enp4s0-
   1825 FF      82   - 122  0.0 S    irq/140-enp4s0-
   1826 FF      81   - 121  0.0 S    irq/141-enp4s0-
     14 TS       -   0  19  0.0 S    ksoftirqd/0
     28 TS       -   0  19  0.0 S    ksoftirqd/1
     36 TS       -   0  19  0.0 S    ksoftirqd/2
     44 TS       -   0  19  0.0 S    ksoftirqd/3
     52 TS       -   0  19  0.0 S    ksoftirqd/4
     60 TS       -   0  19  0.0 S    ksoftirqd/5
    121 TS       -   0  19  0.0 S    irq/9-acpi
    137 TS       -   0  19  0.0 S    irq/120-PCIe PM
    138 TS       -   0  19  0.0 S    irq/121-PCIe PM
    139 TS       -   0  19  0.0 S    irq/121-aerdrv
    140 TS       -   0  19  0.0 S    irq/121-s-aerdr
    141 TS       -   0  19  0.0 S    irq/122-PCIe PM
    142 TS       -   0  19  0.0 S    irq/122-aerdrv
    143 TS       -   0  19  0.0 S    irq/122-s-aerdr
    144 TS       -   0  19  0.0 S    irq/123-PCIe PM
    145 TS       -   0  19  0.0 S    irq/123-aerdrv
    146 TS       -   0  19  0.0 S    irq/123-s-aerdr
    251 TS       -   0  19  0.0 S    irq/125-xhci_hc
    252 TS       -   0  19  0.0 S    irq/16-i801_smb
    299 TS       -   0  19  0.0 S    irq/126-ahci[00
    776 TS       -   0  19  0.0 S    irq/142-mei_me
   1121 TS       -   0  19  0.0 S    irq/143-i915
   1136 TS       -   0  19  0.0 S    irq/144-snd_hda
   1798 TS       -   0  19  0.0 S    irq/124-eno1
   1799 TS       -   0  19  0.0 S    irq/127-enp2s0
   1800 TS       -   0  19  0.0 S    irq/128-enp2s0-
   1801 TS       -   0  19  0.0 S    irq/129-enp2s0-
   1802 TS       -   0  19  0.0 S    irq/130-enp2s0-
   1803 TS       -   0  19  0.0 S    irq/131-enp2s0-
   1808 TS       -   0  19  0.0 S    irq/132-enp3s0
   1809 TS       -   0  19  0.0 S    irq/133-enp3s0-
   1810 TS       -   0  19  0.0 S    irq/134-enp3s0-
   1811 TS       -   0  19  0.0 S    irq/135-enp3s0-
   1812 TS       -   0  19  0.0 S    irq/136-enp3s0-

可以看到,irq/8-rtc0实时优先级为90,irq/137-enp4s0实时优先级为85,修改成功。

三、总结

本文主要介绍了中断线程化这一提高linux系统实时性的机制。通过将外设中断处理从屏蔽全局中断的硬件中断上下转移到线程上下文程执行,可以更好地控制中断处理的优先级和响应时间,但牺牲了部分系统的吞吐量。此外,文章还详细讨论了如何配置不同外设的中断线程优先级,以确保关键任务的实时性。这些配置方法对系统设计者在规划和优化实时应用的优先级时具有重要意义。

<think>好的,我现在需要回答用户的问题:“在 Linux 上部署 CODESYS 时,如何验证 Preempt-RT 补丁是否生效?”首先,我得回顾一下用户之前的询问历史,确保回答的一致性和相关性。用户之前问过如何为CODESYS Runtime分配独占CPU核,现在的问题是关于验证Preempt-RT补丁是否生效。这两个问题都涉及到Linux实时系统的配置,特别是CODESYS的部署。 首先,我需要了解Preempt-RT补丁的作用。Preempt-RT实时抢占补丁)是Linux内核的一个修改版本,旨在减少系统延迟,提供更好的实时性能。对于CODESYS这样的工业自动化软件来说,实时性能至关重要,因此验证补丁是否成功应用是必要的。 接下来,我需要确定验证Preempt-RT补丁生效的方法。可能的步骤包括检查内核版本、查看内核配置参数、测试系统延迟等。用户可能需要多种方法来确认补丁的正确应用,包括命令行工具和性能测试工具。 然后,我需要考虑用户的技术背景。用户可能具备一定的Linux系统管理知识,但可能需要详细的步骤说明,特别是具体的命令和预期的输出。因此,回答需要结构清晰,分步骤说明,并给出每个步骤的验证方法。 此外,用户之前的问题中提到了使用lscpu、taskset等命令,因此在本次回答中可能需要提到类似的工具,如uname检查内核版本,检查/boot/config文件的内核配置,使用cyclictest测试延迟等。 还需要注意潜在的问题,比如用户可能没有正确安装Preempt-RT补丁,或者配置参数未启用,导致验证失败。因此,在回答中可能需要包含常见问题的解决方法,或者提示用户注意的关键点。 最后,要确保回答符合用户之前接受的格式,使用分步骤说明,代码块展示命令,注意事项和常见问题部分。同时,使用中文,避免Markdown格式,但根据用户当前的指示,可能允许使用代码块等基本格式。 总结起来,回答应该包括以下步骤: 1. 检查内核版本和配置。 2. 使用工具如cyclictest进行延迟测试。 3. 查看系统日志或内核启动信息。 4. 注意事项,如权限问题、其他系统配置的影响等。 5. 常见问题解答,比如补丁未生效的可能原因。 需要验证每个步骤的正确性,确保命令的准确性,例如正确的grep参数,cyclictest的使用方法等。同时,可能需要提醒用户需要root权限运行某些命令,或者如何安装必要的测试工具。 现在,我需要将这些思路整理成一个结构清晰、逐步说明的回答,确保用户能够按照步骤验证Preempt-RT补丁是否生效,并理解每个步骤的意义和可能出现的问题。</think>以下是验证 Linux 系统上 **Preempt-RT 实时补丁**是否生效的详细方法,适用于 CODESYS 部署场景: --- ### **1. 检查内核版本配置** #### **步骤 1:确认内核版本** - 执行命令: ```bash uname -a ``` - **预期输出**: 内核名称应包含 `PREEMPT_RT` 标识,例如: ```bash Linux hostname 5.10.0-rt60 #1 SMP PREEMPT_RT ... x86_64 GNU/Linux ``` ✅ 正确标志:`PREEMPT_RT` ❌ 未生效标志:`PREEMPT`(非实时)或 `PREEMPT_VOLUNTARY`(非实时) #### **步骤 2:检查内核配置参数** - 查看内核编译配置: ```bash grep CONFIG_PREEMPT_RT /boot/config-$(uname -r) ``` - **预期输出**: ```bash CONFIG_PREEMPT_RT=y # 表示已启用实时补丁 ``` ❌ 若输出 `CONFIG_PREEMPT_RT is not set`,则补丁未生效。 --- ### **2. 测试实时延迟(核心验证方法)** #### **工具:使用 `cyclictest`** 1. **安装测试工具**: ```bash sudo apt-get install rt-tests # Debian/Ubuntu sudo yum install rt-tests # CentOS/RHEL ``` 2. **运行延迟测试**(需 root 权限): ```bash sudo cyclictest -t1 -p 99 -n -m -D 1h -i 1000 -H 1000 ``` - **参数说明**: - `-t1`:启动 1 个测试线 - `-p 99`:设置最高实时优先级 - `-i 1000`:线间隔 1000 微秒 - `-m`:锁定内存(避免换页延迟) - `-D 1h`:持续运行 1 小时(可选) 3. **解读结果**: 输出示例如下: ```bash # /dev/cpu_dma_latency set to 0us T: 0 ( 3608) P:99 I:1000 C: 1000000 Min: 1 Act: 2 Avg: 3 Max: 42 ``` - **关键指标**: - `Max`(最大延迟):低于 **50 微秒** 表明实时性良好(适用于工业控制场景) - `Avg`(平均延迟):通常应小于 10 微秒 ❌ 若 `Max` 超过 100 微秒,可能 Preempt-RT 未生效或系统配置有误。 --- ### **3. 验证中断线调度** #### **步骤 1:查看中断线程化状态** - Preempt-RT 会将大部分硬件中断转为内核线(可调度)。执行命令: ```bash ps -eLo pid,cls,rtprio,pri,nice,cmd | grep "irq/" ``` - **预期输出**: 显示以 `irq/` 开头的线(如 `irq/12-i915`),且调度策略为 `SCHED_FIFO`: ```bash 123 FF 99 139 - [irq/12-i915] ``` ✅ `FF` 表示 `SCHED_FIFO`(实时线) #### **步骤 2:检查实时调度策略支持** - 验证内核是否允许设置最高优先级(99): ```bash chrt -m ``` - **预期输出**: ```bash SCHED_FIFO 最小/最大优先级: 1/99 SCHED_RR 最小/最大优先级: 1/99 SCHED_OTHER 最小/最大优先级: 0/0 ``` --- ### **4. 查看内核启动日志** - 执行命令: ```bash dmesg | grep "Preempt-RT" ``` - **预期输出**: 若补丁生效,会显示类似以下信息: ```bash [ 0.000000] Preempt-RT kernel v5.10.0-rt60 enabled ``` --- ### **注意事项** 1. **测试环境隔离**: - 关闭其他高负载进- 禁用 CPU 节能模式: ```bash sudo cpupower frequency-set -g performance ``` 2. **权限要求**: - `cyclictest` 和 `chrt` 需要 root 权限(或用户加入 `realtime` 组)。 3. **硬件影响**: - 某些硬件(如旧版 BIOS 或 USB 控制器)可能导致额外延迟,需结合 `ftrace` 或 `perf` 深入分析。 --- ### **常见问题** - **Q:内核显示 `PREEMPT` 但非 `PREEMPT_RT`,是否生效?** A:未生效!标准 `PREEMPT` 仅为通用抢占,非实时补丁。 - **Q:`cyclictest` 延迟过高怎么办?** A:检查是否遗漏以下配置: - BIOS 中禁用 CPU C-States 和 SpeedStep。 - 内核启动参数添加 `nohz=off` 或 `nohz_full=...`。 - 使用 `isolcpus` 隔离核心(参考上一篇 CPU 隔离方法)。 --- 通过以上方法可明确验证 Preempt-RT 补丁是否生效,确保 CODESYS 在实时环境中稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值