一、背景
Xenomai为了提升系统的响应速度、减少响应延时在各个维度上都做了许多工作。
其中为了减少定时器上的延时在定时器上实时了一个叫做gravity的校准,以尽可能的消除timer响应路径上的延时,确保定时器的响应时间更加接近用户的期望到期时间。
二、gravity的默认值
Xenomai初始化阶段会调用xnclock_init()函数来设置默认的gravity值,逻辑如下:
static inline void xnarch_get_latencies(struct xnclock_gravity *p)
{
unsigned int ulat;
#if CONFIG_XENO_OPT_TIMING_SCHEDLAT != 0
ulat = CONFIG_XENO_OPT_TIMING_SCHEDLAT;
#elif defined(CONFIG_ARCH_HISI)
ulat = 4000;
#else
ulat = 4000;
#endif
p->user = xnclock_ns_to_ticks(&nkclock, ulat);
p->kernel = xnclock_ns_to_ticks(&nkclock, CONFIG_XENO_OPT_TIMING_KSCHEDLAT);
p->irq = xnclock_ns_to_ticks(&nkclock, CONFIG_XENO_OPT_TIMING_IRQLAT);
}
xnarch_get_latencies(&gravity);
gravity.user += nktimerlat;
if (gravity.kernel == 0)
gravity.kernel = gravity.user;
if (gravity.irq == 0)
gravity.irq = nktimerlat;
简单描述一下上述代码设置默认gravity值的逻辑:
(1)内核中有CONFIG_XENO_OPT_TIMING_SCHEDLAT、CONFIG_XENO_OPT_TIMING_KSCHEDLAT、CONFIG_XENO_OPT_TIMING_IRQLAT三个配置项以提供给用户来配置gravity.user、gravity.kernel和gravity.irq,单位是ns。
(2)如果CONFIG_XENO_OPT_TIMING_KSCHEDLAT或者CONFIG_XENO_OPT_TIMING_IRQLAT有设置为非0,则gravity.kernel或gravity.irq的值分别为
xnclock_ns_to_ticks(&nkclock, CONFIG_XENO_OPT_TIMING_KSCHEDLAT)
或
xnclock_ns_to_ticks(&nkclock, CONFIG_XENO_OPT_TIMING_IRQLAT);
而如果CONFIG_XENO_OPT_TIMING_SCHEDLAT设置为非0,gravity.user的值设置为
xnclock_ns_to_ticks(CONFIG_XENO_OPT_TIMING_SCHEDLAT) + nktimerlat;
(3)否则内核配置为0时,各个gravity的计算方式如下:
gravity.kernel == gravity.user = xnclock_ns_to_ticks(&nkclock, 4000) + nktimerlat;
gravity.irq = nktimerlat。
(4)上面的nktimerlat值是多少呢?是怎么计算的呢?这个值是在xnclock_init()中通过mach_arm_calibrate(void)来计算出一个校准值。
三、默认gravity的问题
如果没有手动配置CONFIG_XENO_OPT_TIMING_SCHEDLAT、CONFIG_XENO_OPT_TIMING_KSCHEDLAT、CONFIG_XENO_OPT_TIMING_IRQLAT项,xenomai会默认计算一套gravity值,旨在降低响应延时。
然而这个默认值gravity是在xenomai启动过程中计算的,无法真实的反应系统启动以后的延迟情况。因而可能引发的问题是用户设置的定时器提前到期。
这方面的一个真实案例就是xenomai提供的默认latency测试用例中结果中出现负值、或者出现irq的响应延时比任务模式要大的情况。
四、如何拿捏gravity
首先,如果在开发、调试阶段,开发人员需要测试系统中真实的timer响应延时,则可以通过写/proc/xenomai/clock/coreclk文件将gravity.kernel、gravity.user和gravity.irq清0。这样timer的响应延迟就是系统当前真实的延时。
其次,如果是在生产工程环境,可以在负载稳定时,通过/usr/xenomai/sbin/autotune对各个gravity进行校准以降低timer的延时。