关于linux应用层高精度定时器设计(笔记)

目的:协议采样率收发离散度达到10us以下..

问题:常规运行,为10~30毫秒,目前通过修改极限只能达到1000us.5分钟)

 

技术难点:摘自http://www.eefocus.com/article/10-10/2075521287133552.html

  Linux在实时方面存在的不足,Linux虽然符合POSIX1003.1b关于实时扩展部分的标准,例如:支持SCHED_FIFOSCHED_RR实时调度策略,锁内存机制 (memorylocking),实时信号等功能,但是由于其最初的设计目标为通用分时操作系统,因此作为一个实时操作系统,Linux仍然存在如下缺陷:
       (1) Linux
的内核本身是非抢占的。Linux下分用户态和核心态两种模式,当进程运行在用户态时,可被优先级更高的进程抢占,但当它进入核心态时,其他用户态进程优先级再高也不能抢占它。
       (2) Linux
虽然给实时进程提供了较高的优先级,但是没有加入时间限制。例如:完成的最后期限、应在多长时间内完成、执行周期等等。同时,其他大量的非实时进程也可能对实时进程造成阻塞,无法确保实时进程的响应时间。
       (3)
时钟粒度粗糙。时钟管理是操作系统的脉搏,任务的执行和中止在很多情况下都是由时钟直接或间接唤起的,它还是进程调度的重要依据。Linux的周期模式定时器频率仅为100Hz,远不能满足实时应用的要求。

 

解决思路

.定时器使用:

Linux为每个任务安排了3个内部定时器:

1).ITIMER_REAL:实时定时器,不管进程在何种模式下运行(甚至在进程被挂起时),它总在计数。定时到达,向进程发送SIGALRM信号。

2).ITIMER_VIRTUAL:这个不是实时定时器,当进程在用户模式(即程序执行时)计算进程执行的时间。定时到达后向该进程发送SIGVTALRM信号。 

3).ITIMER_PROF:进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计数。定时到达产生SIGPROF信号。ITIMER_PROF记录的时间比ITIMER_VIRTUAL多了进程调度所花的时间。

定时器在初始化是,被赋予一个初始值,随时间递减,递减至0后发出信号,同时恢复初始值。在任务中,我们可以一种或者全部三种定时器,但同一时刻同一类型的定时器只能使用一个。

. alarm()

alarm用在不需要经确定时的时候,返回之前剩余的秒数。unsigned int alarm(unsigned int seconds);
     alarm()
函数提供精度为 s 级的定时器,到时之后,向进程发送信号,这种利用信号实现的方法效率低,且精度也不满足要求(不行满足)

 

.setitimer()

setitimer()支持3 种类型的定时器,分别是:ITIMER_REAL,以系统真实的时间来计算,定时器到时后发送 SIGALRM 信号;ITIMER_VIRTUAL ,以该进程在用户态下花费的时间来计算,定时器到时后发送 SIGVTALRM 信号。ITIMER_PROF,以该进程在用户态下和内核态下所费的时间来计算, 定时器到时后发送SIGPROF信号 (测试不行,进程切换多了,你这个进程的很多次信号还会丢掉。)  

 fuction       time(usec)    realtime        reduce

----------------------------------------------------

usleep         500000     500966         966

nanosleep      500000     500917         917

select         500000     501264         1264

pselect        500000     501551         1551


.Sleepn//n毫秒
.sleepn//n                不准

时间差

for(;;)延时

gettimeofday()函数(通过修改Hz,但是还是有进程调度时间片的误差.不行)

 

线程优先等级设置

离散度精度提高,但是还是有时间片的轮转误差..

 

高精度硬件中断定时器hrtimer

需要内核加载,常规用于驱动..目前没有成功

 

高精度定时器posix_timer

交叉编译不通过..不网上显示可能做不到实时..

现在用posix timer可以定时,可是一旦定时间小于1ms就很不准确了

你可能感兴趣的:(linux,timer,测试,扩展,任务)