溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SylixOS高精度時(shí)鐘分析

發(fā)布時(shí)間:2020-07-04 20:55:36 來(lái)源:網(wǎng)絡(luò) 閱讀:566 作者:深山野老 欄目:建站服務(wù)器

1.Tick工作原理簡(jiǎn)介

Tick工作原理其實(shí)就是硬件定時(shí)器的工作原理,1個(gè)系統(tǒng)tick就代表一個(gè)定時(shí)器硬件中斷。定時(shí)器的工作原理很簡(jiǎn)單,就是內(nèi)部有一個(gè)遞減的計(jì)數(shù)器,當(dāng)減到0時(shí)產(chǎn)生一個(gè)中斷,如圖 1-1所示:

SylixOS高精度時(shí)鐘分析

1-1定時(shí)器工作原理

假設(shè)定時(shí)器模塊的輸入頻率是1MHz,系統(tǒng)定義的1S內(nèi)tick數(shù)是100,也就是100Hz,可以計(jì)算出遞減計(jì)數(shù)器要設(shè)置的值為1MHz/100Hz=10000。可以看出遞減計(jì)數(shù)器相當(dāng)于一個(gè)分頻器,輸入端每來(lái)一個(gè)脈沖,其值就減去1,當(dāng)減到0時(shí)產(chǎn)生一個(gè)中斷,同時(shí)其值自動(dòng)重載成10000,如此循環(huán)下去。

2.系統(tǒng)獲取時(shí)間操作

系統(tǒng)獲取時(shí)間相關(guān)接口是基于tick來(lái)工作的,但是這是有誤差的,如圖 2-1所示:

SylixOS高精度時(shí)鐘分析

2-1系統(tǒng)獲取時(shí)間

虛線表示下一個(gè)tick中斷還未產(chǎn)生,如果此時(shí)來(lái)獲取時(shí)間,獲取到的時(shí)間只是之前tick累計(jì)的時(shí)間。假設(shè)tick中斷產(chǎn)生時(shí)刻和獲取時(shí)間那一時(shí)刻之間的跨度是4ms,那么獲取的時(shí)間就有4ms的誤差,高精度時(shí)鐘就是為了消除這種誤差而誕生的。

3.高精度時(shí)鐘原理

3.1基本原理

上述誤差產(chǎn)生的根本原因是沒(méi)有將tick中斷產(chǎn)生時(shí)刻和獲取時(shí)間那一時(shí)刻之間的跨度更新到時(shí)間里去,如果計(jì)算出這段時(shí)間并加到獲取的時(shí)間里去就可以校正獲取的時(shí)間了。結(jié)合圖 1-1和圖 2-1,基本的校正原理如下所述:

  • 1個(gè)tick時(shí)間等價(jià)于遞減計(jì)數(shù)器的初始值,假設(shè)是10000,也就是說(shuō)遞減10000次相當(dāng)于過(guò)了一個(gè)tick時(shí)間

  • 1000 * 1000 * 1000 / 10000得到遞減一次的時(shí)間,單位是ns

  • 用計(jì)數(shù)器初始值減去獲取時(shí)間那一時(shí)刻計(jì)數(shù)器中的值,就得到了獲取時(shí)間時(shí)刻計(jì)數(shù)器已經(jīng)遞減的次數(shù)

  • 用遞減一次的時(shí)間 *遞減的次數(shù),就得到tick中斷產(chǎn)生時(shí)刻和獲取時(shí)間那一時(shí)刻之間的時(shí)間跨度

3.2特殊情況

當(dāng)系統(tǒng)是多核時(shí),系統(tǒng)產(chǎn)生一個(gè)由CPU0來(lái)處理的tick中斷,當(dāng)CPU0還沒(méi)有更新整個(gè)系統(tǒng)的tick數(shù)時(shí),這時(shí)CPU1來(lái)獲取時(shí)間,按照基本原理的計(jì)算之后還要加上一個(gè)tick的時(shí)間才是正確的。

4.代碼展示

程序清單 4-1

VOID bspTickHighResolution (struct timespec *ptv)

{

REGISTER UINT32 uiCntCur, uiDone;

 

uiCntCur = (UINT32)timerGetCnt(4);

uiDone = GuiFullCnt - uiCntCur;

 

/*

*檢查是否有 TICK中斷請(qǐng)求

*/

if (rSRCPND & BIT_TIMER4) {

/*

*這里由于 TICK沒(méi)有及時(shí)更新,所以需要重新獲取并且加上一個(gè) TICK的時(shí)間

*/

uiCntCur = (UINT32)timerGetCnt(4);

uiDone = GuiFullCnt - uiCntCur;

 

if (uiCntCur != 0) {

uiDone += GuiFullCnt;

}

}

 

ptv->tv_nsec += (LONG)((Gui64NSecPerCnt7 * uiDone) >> 7);

if (ptv->tv_nsec >= 1000000000) {

ptv->tv_nsec -= 1000000000;

ptv->tv_sec++;

}

}

  • GuiFullCnt表示遞減計(jì)數(shù)器的初始值,也就是產(chǎn)生1個(gè)tick時(shí)間的計(jì)數(shù)值;Gui64NSecPerCnt7表示遞減一次的時(shí)間,但是這個(gè)時(shí)間被擴(kuò)大了128倍,目的是為了提高計(jì)算精度

  • uiDone表示獲取時(shí)間時(shí)刻計(jì)數(shù)器已經(jīng)遞減的次數(shù),uiCntCur表示獲取時(shí)間時(shí)刻計(jì)數(shù)器當(dāng)前值

  • if (rSRCPND & BIT_TIMER4)用于特殊情況的判斷,條件成立表示系統(tǒng)的tick數(shù)還沒(méi)來(lái)得及更新,不成立表示系統(tǒng)的tick數(shù)已經(jīng)被更新

  • 當(dāng)uiCntCur=0時(shí),表示tick中斷剛剛產(chǎn)生,這時(shí)uiDone就已經(jīng)代表一個(gè)tick的計(jì)數(shù)值,所以就無(wú)需再加上一個(gè)tick的計(jì)數(shù)值了

  • 最后將修正后的時(shí)間賦值給tv_nsec成員

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI