目的:協議採樣率收發離散度達到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就很不準確了