请问用户空间能否实现微秒级的延时

344 views
Skip to first unread message

chensheng duan

unread,
Jan 19, 2011, 2:21:06 AM1/19/11
to linux-kernel
arm平台,假设硬件可以提供足够精度的时钟,从内核的角度可以放在中断处理里面做,但是不知道如何提供给用户,包括实时的设置和被通知,因为感觉这些系统调用都很耗时。
应用层我查了查,现成的有实时定时器,就是timer_create,但没看过这个的内核实现,拿不准是不是和select一样精度要求一高误差就很大。事实上在应用层即使测量时间都很困难,内核里我可以拉gpio然后用示波器量,也可以记录定时器的count,但是应用层都要靠系统调用来获取。
_______________________________________________
Linux 内核开发中文邮件列表
Linux-...@zh-kernel.org
http://zh-kernel.org/mailman/listinfo/linux-kernel
Linux 内核开发中文社区: http://zh-kernel.org

chensheng duan

unread,
Jan 19, 2011, 4:46:33 AM1/19/11
to boywhp w, linux-kernel
在 2011年1月19日 下午4:27,boywhp w <boy...@gmail.com>写道:

> linux不能搞这种东西吧?进程切换好像就要几十ms???
> sleep会导致进程切换的

切换不需要几十ms吧 一个tick才多少 都不够切换的
这里实现肯定不能用sleep 没机会调度回来,要靠类似动态定时器的实现方式。
我不知道比如

set(100us);//设置一个定时器
hang=1;
while(hang);
...

定时器的handler:
hang=0;

这样不知是否可行

张增辉

unread,
Jan 19, 2011, 7:23:27 AM1/19/11
to chensheng duan, linux-kernel
内核里面的精度也是受限的。不过可以开发高精度的定时器。应用层的本来是直接调用内核提供的接口就可以,但是涉及到 swap 进程状态等,所以如果要更改的话 还需要更改内核里面 比方调度方面的东西,当然如果你调度要求的精度远远大于 1/hz s的话 就不用考虑这么多了。 呵呵
在pc x86下我有apic timer的误差小于us的高精度实现。arm的不是很熟悉。呵呵

Gao Ya'nan

unread,
Jan 19, 2011, 8:47:46 AM1/19/11
to chensheng duan, linux-kernel
看看 Xenomai。

2011/1/19 chensheng duan <csdua...@gmail.com>:

chensheng duan

unread,
Jan 19, 2011, 8:29:48 PM1/19/11
to Gao Ya'nan, linux-kernel
xenomai吗,好的,我会去看看。
你这一说我想起来,我几年前在应用层用过rtai的实时api,不过当问到rtlinux为啥不支持这项技术的时候,rtlinux的maintainer对此不屑一顾

chensheng duan

unread,
Jan 19, 2011, 8:33:51 PM1/19/11
to 张增辉, linux-kernel
在 2011年1月19日 下午8:23,张增辉 <zhangz...@yeah.net>写道:

>
> 内核里面的精度也是受限的。不过可以开发高精度的定时器。应用层的本来是直接调用内核提供的接口就可以,但是涉及到 swap 进程状态等,所以如果要更改的话 还需要更改内核里面 比方调度方面的东西,当然如果你调度要求的精度远远大于 1/hz s的话 就不用考虑这么多了。 呵呵
> 在pc x86下我有apic timer的误差小于us的高精度实现。arm的不是很熟悉。呵呵
> 在 2011-01-19,"chensheng duan" <csdua...@gmail.com> 写道:
>
>
> >arm平台,假设硬件可以提供足够精度的时钟,从内核的角度可以放在中断处理里面做,但是不知道如何提供给用户,包括实时的设置和被通知,因为感觉这些系统调用都很耗时。
>
> >应用层我查了查,现成的有实时定时器,就是timer_create,但没看过这个的内核实现,拿不准是不是和select一样精度要求一高误差就很大。事实上在应用层即使测量时间都很困难,内核里我可以拉gpio然后用示波器量,也可以记录定时器的count,但是应用层都要靠系统调用来获取。
> >_______________________________________________
> >Linux 内核开发中文邮件列表
> >Linux-...@zh-kernel.org
> >http://zh-kernel.org/mailman/listinfo/linux-kernel
> >Linux 内核开发中文社区: http://zh-kernel.org
>

很羡慕x86底下的环境,硬件统一一致,不像arm,没有统一的硬件环境,也就没法有个固定的时钟源以及相关的机制。我现在的想法就是借助高精度定时器,然后到点给用户发信号,但目前不清楚这个信号延时多少,会不会丢失,另外还有同时会不会只有一个线程能使用这个定时器。

zhenglinux

unread,
Jan 19, 2011, 9:20:09 PM1/19/11
to linux-...@zh-kernel.org
于 2011-1-20 9:33, chensheng duan 写道:
> 硬件统一一致,不像arm,没有统一的硬件环境,也就没法有个固定的时钟源以及相关的机制。我现在的想法就是借助高精度定时器,然后到点给用户发信号,但目前不清楚这个信号延时多少,会不会丢失,另外还有同时会不会只有一个线程能使用这个定时器。
多精密的东西啊,要用到微妙级的延时,还得用arm,还得用linux,还得是APP,要求蛮高的。哈哈

chensheng duan

unread,
Jan 19, 2011, 9:48:40 PM1/19/11
to zhenglinux, linux-...@zh-kernel.org
在 2011年1月20日 上午10:20,zhenglinux <zheng...@126.com>写道:

> 于 2011-1-20 9:33, chensheng duan 写道:
>
> 硬件统一一致,不像arm,没有统一的硬件环境,也就没法有个固定的时钟源以及相关的机制。我现在的想法就是借助高精度定时器,然后到点给用户发信号,但目前不清楚这个信号延时多少,会不会丢失,另外还有同时会不会只有一个线程能使用这个定时器。
>>
> 多精密的东西啊,要用到微妙级的延时,还得用arm,还得用linux,还得是APP,要求蛮高的。哈哈
>
>

> 工业上的玩意,如果用rtos或者裸奔,都还好,用linux相对麻烦不少

zhangxiao

unread,
Jan 19, 2011, 10:06:00 PM1/19/11
to chensheng duan, linux-kernel
On 2011年01月19日 15:21, chensheng duan wrote:
> arm平台,假设硬件可以提供足够精度的时钟,从内核的角度可以放在中断处理里面做,但是不知道如何提供给用户,包括实时的设置和被通知,因为感觉这些系统调用都很耗时。
> 应用层我查了查,现成的有实时定时器,就是timer_create,但没看过这个的内核实现,拿不准是不是和select一样精度要求一高误差就很大。事实上在应用层即使测量时间都很困难,内核里我可以拉gpio然后用示波器量,也可以记录定时器的count,但是应用层都要靠系统调用来获取。
我的理解是,你想要的并不是用户态下面的微秒级的延时机制,而是要给用户层一
个接口,来设置一个微秒级的延时时间,以及一种方式用来通知用户态应 用程
序,延时已然被触发或者是其他相关信息是么?

毕竟,如此精确的延时放在用户态执行不大合适,呵呵。

chensheng duan

unread,
Jan 19, 2011, 10:30:52 PM1/19/11
to zhangxiao, linux-kernel
在 2011年1月20日 上午11:06,zhangxiao <xiao....@windriver.com>写道:

> On 2011年01月19日 15:21, chensheng duan wrote:
>
>>
>> arm平台,假设硬件可以提供足够精度的时钟,从内核的角度可以放在中断处理里面做,但是不知道如何提供给用户,包括实时的设置和被通知,因为感觉这些系统调用都很耗时。
>>
>> 应用层我查了查,现成的有实时定时器,就是timer_create,但没看过这个的内核实现,拿不准是不是和select一样精度要求一高误差就很大。事实上在应用层即使测量时间都很困难,内核里我可以拉gpio然后用示波器量,也可以记录定时器的count,但是应用层都要靠系统调用来获取。
>>
> 我的理解是,你想要的并不是用户态下面的微秒级的延时机制,而是要给用户层一 个接口,来设置一个微秒级的延时时间,以及一种方式用来通知用户态应 用程
> 序,延时已然被触发或者是其他相关信息是么?
>
> 毕竟,如此精确的延时放在用户态执行不大合适,呵呵。
>
> _______________________________________________
>> Linux 内核开发中文邮件列表
>> Linux-...@zh-kernel.org
>> http://zh-kernel.org/mailman/listinfo/linux-kernel
>> Linux 内核开发中文社区: http://zh-kernel.org
>>
>
>

没错,而且只能这样实现。不能sleep,因为调度不过来。自己算好循环周期忙等也不靠谱。只能是通过接口告诉内核,然后内核发信号给app这样来做。然后通过这个机制,如果是app层的定时器,信号handler就调用想要的回调,如果是想实现延迟,就只有先while(1)阻塞,handler负责break。但是还没深入看这样是否保险,比如信号丢失,那样就完全阻塞住了。同时是不是一个硬件定时器对应一个软件上的一个线程,如果这样搞出来只能给一个线程用,其他一用就乱了,意义也不大。
确实不大适合,如果不行就把一部分实现拆到内核里,不过如果有delay几微秒的需求,不知道是不是系统调用的过程就有那么长了。这里最bt的需求是20us,普遍一般百微秒级别,md
不行继续裸奔

zhangxiao

unread,
Jan 19, 2011, 10:40:02 PM1/19/11
to chensheng duan, linux-kernel
On 2011年01月20日 11:30, chensheng duan wrote:
>
>
> 在 2011年1月20日 上午11:06,zhangxiao <xiao....@windriver.com
> <mailto:xiao....@windriver.com>>写道:

>
> On 2011年01月19日 15:21, chensheng duan wrote:
>
> arm平台,假设硬件可以提供足够精度的时钟,从内核的角度可以放在中
> 断处理里面做,但是不知道如何提供给用户,包括实时的设置和被通知,
> 因为感觉这些系统调用都很耗时。
> 应用层我查了查,现成的有实时定时器,就是timer_create,但没看过这
> 个的内核实现,拿不准是不是和select一样精度要求一高误差就很大。事
> 实上在应用层即使测量时间都很困难,内核里我可以拉gpio然后用示波器
> 量,也可以记录定时器的count,但是应用层都要靠系统调用来获取。
>
> 我的理解是,你想要的并不是用户态下面的微秒级的延时机制,而是要给用户
> 层一 个接口,来设置一个微秒级的延时时间,以及一种方式用来通知用户态
> 应 用程 序,延时已然被触发或者是其他相关信息是么?
>
> 毕竟,如此精确的延时放在用户态执行不大合适,呵呵。
>
> _______________________________________________
> Linux 内核开发中文邮件列表
> Linux-...@zh-kernel.org <mailto:Linux-...@zh-kernel.org>

> http://zh-kernel.org/mailman/listinfo/linux-kernel
> Linux 内核开发中文社区: http://zh-kernel.org
>
>
> 没错,而且只能这样实现。不能sleep,因为调度不过来。自己算好循环周期忙等
> 也不靠谱。只能是通过接口告诉内核,然后内核发信号给app这样来做。然后通过
> 这个机制,如果是app层的定时器,信号handler就调用想要的回调,如果是想实现
> 延迟,就只有先while(1)阻塞,handler负责break。但是还没深入看这样是否保
> 险,比如信号丢失,那样就完全阻塞住了。同时是不是一个硬件定时器对应一个软
> 件上的一个线程,如果这样搞出来只能给一个线程用,其他一用就乱了,意义也不大。
> 确实不大适合,如果不行就把一部分实现拆到内核里,不过如果有delay几微秒的
> 需求,不知道是不是系统调用的过程就有那么长了。这里最bt的需求是20us,普遍
> 一般百微秒级别,md 不行继续裸奔
可能是我没有表述清除,我的意思的这个timer的handler就不应该在用户态,至少
也应该在内核态,最好是中断处理程序里面。

毕竟,用户态应用程序的级别太低,就像是一条异常繁忙的铁路线上的慢车,遇到
任何其他车辆都得让行。这种情况下你就不能把时间敏感的任务放在这么不靠谱的
机制上面。你想阿,即便内核的一切都很完美,分秒不差的让定时器到期,然后唤
醒你这个进程,你这个进程会立即得到执行么?其他软硬中断会不会打扰你?高优
先级进程会不会挡着你?凭什么就会立即把珍贵的CPU资源出让给你这么一个用户
态进程呢?

chensheng duan

unread,
Jan 19, 2011, 10:50:38 PM1/19/11
to zhangxiao, linux-kernel

你说的对,我对app层不熟悉,不清楚内核给进程发信号,信号的handler是不是会立刻执行。即使会立刻执行,在delay的情况也没法立刻使进程从死循环break,因为进程有可能被调度了。
当初想放到应用层,主要还是因为不想把原有的app代码拆开,现在看也没法偷这个懒。
多谢大家指点阿,现在还是把时间放在内核阶段的高精度定时。

E=MaC^2s

unread,
Jan 20, 2011, 12:22:55 AM1/20/11
to chensheng duan, linux-kernel
如果你不怕cpu占用100% 或者这个延时调用的频率不高,用while(1)轮询时间可以试试,
内核里用hrtimer精度还是很高的。

chensheng duan

unread,
Jan 20, 2011, 2:31:46 AM1/20/11
to E=MaC^2s, linux-kernel

你是说内核里,while(1)hang住,然后hrtimer让其break出来?
我在想如果是这样的实现机制,如果在一个很短的时间,比如几十微秒,不如直接udelay算了,反正都是忙等,而且如果cpu不变频的话,lpj还算靠谱。
有没有哪里逻辑上有漏洞?

E=MaC^2s

unread,
Jan 20, 2011, 2:55:15 AM1/20/11
to chensheng duan, linux-kernel
内核里while(1) 还能活过来么 呵呵
我的意思是用户空间while(1)然后不停的查时间

或者 就在内核里搞 在hrtimer硬件中断中解决,精度足够你用了

在 11-1-20,chensheng duan<csdua...@gmail.com> 写道:

chensheng duan

unread,
Jan 20, 2011, 3:11:13 AM1/20/11
to E=MaC^2s, linux-kernel

是的,只有在内核里定时来做了。不过前面有人提到的xenomai,有空看看有没有啥其他方法,如果不是标准linux的话。

Liu Yu-B13201

unread,
Jan 20, 2011, 4:40:13 AM1/20/11
to chensheng duan, E=MaC^2s, linux-kernel
撇开udelay不谈
通常的高精度定时的做法是用hrtimer 挂一个定时器
定时器中调度一个tasklet
tasklet会在下半部中执行 应该能满足大部分实时的需求了

chensheng duan

unread,
Jan 20, 2011, 9:50:16 AM1/20/11
to Liu Yu-B13201, linux-kernel

> 还要再raise一个tasklet么,我以为直接定时器中断里面做了,多谢提醒,看来得仔细看看代码了

boywhp w

unread,
Jan 20, 2011, 7:06:56 PM1/20/11
to Liu Yu-B13201, linux-kernel
这个方法感觉比较靠谱一点,不过应该只能用在内核代码吧?

在 2011年1月20日 下午5:40,Liu Yu-B13201 <B13...@freescale.com>写道:

Allen Wang

unread,
Jan 22, 2011, 2:18:32 AM1/22/11
to boywhp w, linux-kernel
2011/1/21 boywhp w <boy...@gmail.com>

> 这个方法感觉比较靠谱一点,不过应该只能用在内核代码吧?
>
>
userspace: __asm("swi xxx") do critical thing
__asm("swi xxxx")
----------------------------------------------------------------------------------------------------------------------------
kernelspace: preempt & irqfiq disable ^
preempt & irqfiq enable
udelay |
ret_to_user
------------

udelay expires
ret_to_user |
a naive idea..

Reply all
Reply to author
Forward
0 new messages