8.4通过延迟补偿来提高实时性
8.4 通过延迟补偿来提高实时性延迟补偿的基本原理不是改变时钟本身的精度而是主动地、提前地设置定时器的到期时间以“预支”anticipate掉已知的、系统固有的响应延迟。在实时系统中从定时器到期Timer Shot到目标代码中断处理程序 IRQ、内核任务 Kernel 或用户空间线程 User实际开始执行之间存在不可避免的延迟。延迟来源包括硬件因素如硬件定时器重编程所需的时间、总线传输、缓存未命中和软件因素如关中断代码执行、调度延迟、内核态用户态切换等。Gravity (重力值) 是一个静态调整值以纳秒为单位。它的作用是将定时器的触发时间点提前AnticipateGravity (重力值) 所表示的时间量。例如如果一个用户空间线程需要在绝对时间点 T 被唤醒但系统从定时器到期到唤醒该线程通常需要 G 纳秒用户重力那么定时器会被设置为在T - G时刻到期。这样尽管有延迟 G线程实际被唤醒的时间点会更接近预期的 T。Xenomai 3三个独立的重力值分别对应定时器触发后激活的不同执行上下文irq重力值: 中断发生到执行实时中断处理程序 (Real-time IRQ handler)的固有延迟kernel重力值: 从中断处理程序执行结束到开始执行内核态 RTDM 线程 (Kernel task)的固有延迟user重力值: 从中断处理程序执行结束到开始执行用户态用户空间 Xenomai 实时线程 (User-space thread)的固有延迟# cat /proc/xenomai/clock/coreclk gravity: irq0 kernel5000 user5000 devices: timerarch_sys_timer, clockLinux clocksource watchdog: on ticks: 19251279868217 (1182 49b2b139)如何修改 Gravity (重力值)编译时设置默认值默认情况下Gravity (重力值) 的值是 0表示系统没有对定时器进行补偿。--- Xenomai/cobalt Latency settings --- (0) User scheduling latency (ns) (0) Intra-kernel scheduling latency (ns) (0) Interrupt latency (ns)运行时手动修改 Gravity (重力值)通过写入/proc/xenomai/clock/coreclk文件使用后缀i,k,u或组合来动态调整不同上下文的重力值以优化系统实时性能。/* change the user gravity (default) */ # echo 3000 /proc/xenomai/clock/coreclk /* change the IRQ gravity */ # echo 1000i /proc/xenomai/clock/coreclk /* change the user and kernel gravities */ # echo 2000u 1000k /proc/xenomai/clock/coreclk运行时自动调整 Gravity (重力值)通过 autotune 工具可以自动调整 Gravity (重力值)以优化系统实时性能。编译内核时需打开 Auto-tuning 选项--- Xenomai/cobalt Core features --- * Auto-tuning值得注意的是调整了 Gravity (重力值) 后如果提前触发量设置的过大可以能导致延迟出现负数的情况。因此需要根据系统的实际情况合理设置 Gravity (重力值)。参考https://doc.xenomai.org/v3/html/MIGRATION/index.html