目的:协议采样率收发离散度达到10us以下..
问题:常规运行,为10~30毫秒,目前通过修改极限只能达到1000us.(5分钟)
技术难点:摘自http://www.eefocus.com/article/10-10/2075521287133552.html
Linux在实时方面存在的不足,Linux虽然符合POSIX1003.1b关于实时扩展部分的标准,例如:支持SCHED_FIFO和SCHED_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
.Sleep(n)//n毫秒
.sleep(n)//n秒 不准
for(;;)延时
gettimeofday()函数(通过修改Hz,但是还是有进程调度时间片的误差.不行)
线程优先等级设置
离散度精度提高,但是还是有时间片的轮转误差..
高精度硬件中断定时器hrtimer
需要内核加载,常规用于驱动..目前没有成功
高精度定时器posix_timer
交叉编译不通过..不网上显示可能做不到实时..
现在用posix timer可以定时,可是一旦定时间小于1ms就很不准确了