1. 程式人生 > >[轉]關於編寫Nios II的延時函數的一點心得

[轉]關於編寫Nios II的延時函數的一點心得

RoCE x11 小時 軟件 arc pla sys return tro

平臺

硬件:nios/f 100MHz

軟件:技術分享圖片

內容

0 一點說明

本文僅討論所述平臺的一點心得,若其他等級的nios或優化,請自行研究。

1 usleep()有多準

參考[筆記].怎樣使用Nios II中的timestamp_timer?.[Nios II][SOPC Builder],我們做以下實驗:

代碼1 本文所用測試代碼模板

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> // printf() #include <unistd.h> // usleep()
#include "system.h" // 系統 #include "my_types.h" // 數據類型 #include "sys/alt_timestamp.h" // timestamp int main() { u32 t0, t1, t2; vu32 i; alt_timestamp_start(); // 開啟時間戳服務 t0 = alt_timestamp(); // 測量時間戳t0 usleep(1000); t1 = alt_timestamp();
// 測量時間戳1 for(i=0; i<1000; i++); t2 = alt_timestamp(); // 測量時間戳1 printf("時間戳(t1-t0) = %ld \n", (t1-t0)); printf("時間戳(t2-t1) = %ld \n", (t2-t1)); printf("\n"); printf("系統時鐘頻率是 %ld Hz\n", alt_timestamp_freq()); return 0; }

其中第14行和第16行的內容是下面討論的重點

1 usleep(1000);
1 for(i=0; i<100; i++);

眾所周知,usleep()是Nios II HAL自帶的us級的延時函數,那麽它究竟有多準。

(1)修改第14行為:

1 usleep(1*1000*1000);

編譯運行的結果如圖1.1 所示,usleep(1*1000*1000)共占用99,568,957個tick。那麽1s有多少tick呢,正如顯示的時鐘頻率一樣,1s可分為100,000,000個tick。也就是說usleep(1*1000*1000)實際延時為99,568,957/100M=0.99568957 s。這個時間已經相當準了,和1s差距不大。

技術分享圖片

圖1.1 usleep(1*1000*1000)的結果

(2)修改第14行為:

1 usleep(1*1000);

編譯運行的結果如圖1.2所示。這一次是100,843/100M=1.008ms,也不錯。

技術分享圖片

圖1.2 usleep(1*1000)的結果

(3)修改第14行為:

1 usleep(100);

編譯運行的結果如圖1.3所示。這一次是11,743/100M=117.43us,誤差開始顯現了。

技術分享圖片

圖1.3 usleep(100) 的結果

(4)修改第14行為:

1 usleep(10);

編譯運行的結果如圖1.4所示。這一次是1,511/100M=15.11us,誤差不是一點點。

技術分享圖片

圖1.4 usleep(10)的結果

(5)修改第14行為:

1 usleep(1);

編譯運行的結果如圖1.5所示。這一次是620/100M=6.2us,已經相當離譜了。

技術分享圖片

圖1.4 usleep(1)的結果

小結一下:usleep()在ms級別及以上的延時的確很準,但是us級別就有點捉襟見肘了。

2 想要延時1us怎麽辦?

(1)修改第16行為:

1 for(i=0; i<100; i++);

編譯運行的結果如圖2.1所示,亦即延時1,197/100M=11.97us。

技術分享圖片

圖2.1 for(100)的結果

(2)修改第16行為:

1 for(i=0; i<10; i++);

編譯運行的結果如圖2.2所示,亦即延時207/100M=2.07us。

技術分享圖片

圖2.2 for(10)的結果

(3)修改第16行為:

1 for(i=0; i<1; i++);

編譯運行的結果如圖2.2所示,亦即延時106/100M=1.06us。

技術分享圖片

圖2.3 for(1)的結果

小結:for(1)可以很第實現延時1us的任務。

需要註意的地方

觀察第9行,此處i被申明為vu32(volatile unsigned long)類型,倘若改為u32(unsigned long)類型的話。那麽無論i值為多少,都會被gcc優化掉的。

4 小結

timestamp可以有效地協助我們編寫小時間段的延時代碼。

[轉]關於編寫Nios II的延時函數的一點心得