xenomai系统中timer校准简要分析

一、背景

  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.kernelgravity.irq,单位是ns。
    (2)如果CONFIG_XENO_OPT_TIMING_KSCHEDLAT或者CONFIG_XENO_OPT_TIMING_IRQLAT有设置为非0,则gravity.kernelgravity.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的延时。

你可能感兴趣的:(linux内核,处理器架构)