【求助】关于hrtimer定时器精度(用过hrtimer进行10us级定时的大牛请进)

时间:2022-05-16 08:54:21
最近在使用dm365的嵌入式linux进行开发时,需要一个高精度定时周期——16kHz。因此考虑使用hrtimer,但是用下来发现,号称纳秒精度级别的hrtimer,在周期低于74us之后就无能为力了,不知道是不是我的使用有问题,特地在此开贴求大牛解惑。
我的使用步骤具体如下:

首先kernel中已经打开了high resolution Timer support

驱动程序中hrtimer的初始化如下:

 hrtimer_init(&m_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
 m_timer.function = vibrator_timer_func;
 hrtimer_start(&m_timer,ktime_set(0, 62500),HRTIMER_MODE_REL_PINNED);


定时函数vibrator_timer_func如下:
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
{
  gpio_set_value(gpio_test, 1);
  gpio_set_value(gpio_test, 0);
  hrtimer_forward_now(&m_timer,ktime_set(0, 62500));
  return HRTIMER_RESTART;
}

其中gpio_test为输出引脚,为了方便输出查看。
但是用示波器查看引脚波形时,发现虽然设定的周期为62.5us,但是输出总是为72us左右,而且偶尔会有两个波形靠的很近(也就是说周期突然变为10us以下)。我将周期设到40us的话,就会出现72us和10us经常交替出现,无法实现精确的40us的波形,如果设置到100us时,则波形就是100us了,而且貌似没有看到有10us以下的周期出现。

上面就是目前我使用下来的现象,不知道大神们有什么建议,是不是我哪些地方不对?
(注:我用rt_task(current)查看驱动是否是实时任务时返回的是false,不知道这个会不会有影响?如果有的话,怎么设置成实时任务?)


1 个解决方案

#1


没有人回复,自己研究了两天内核里的hrTimer软件架构,终于搞定了。
我用的是dm365,因此在arch/arm/mach-davinci/time.c文件中有下列函数
static void __init davinci_timer_init(void)

该函数中有一行
clockevent_davinci.min_delta_ns = 50000; /* 50 usec */


而hrTimer在设定下一次定时中断时,会跟该值进行对比
	if (delta < dev->min_delta_ns)
delta = dev->min_delta_ns;

(在clockevents_program_event函数中)

默认该值是50us,所以我定时小于50us的都被改为了50us,将该值改为5us后,问题解决,出来了完美的40us周期波形。

写在这里希望对后面遇到同样问题的人有帮助。

#1


没有人回复,自己研究了两天内核里的hrTimer软件架构,终于搞定了。
我用的是dm365,因此在arch/arm/mach-davinci/time.c文件中有下列函数
static void __init davinci_timer_init(void)

该函数中有一行
clockevent_davinci.min_delta_ns = 50000; /* 50 usec */


而hrTimer在设定下一次定时中断时,会跟该值进行对比
	if (delta < dev->min_delta_ns)
delta = dev->min_delta_ns;

(在clockevents_program_event函数中)

默认该值是50us,所以我定时小于50us的都被改为了50us,将该值改为5us后,问题解决,出来了完美的40us周期波形。

写在这里希望对后面遇到同样问题的人有帮助。