在工控行業(yè)很多領(lǐng)域中,需要控制系統(tǒng)具有高精度的時(shí)間同步功能,IRIG就是美國(guó)靶場(chǎng)司令委員會(huì)制定的一種時(shí)間標(biāo)準(zhǔn),英創(chuàng)在EM928x系列的Linux工控主板上實(shí)現(xiàn)了IRIG-B碼校時(shí)功能。
IRIG是美國(guó)靶場(chǎng)司令委員會(huì)制定的一種時(shí)間標(biāo)準(zhǔn),其中的串行時(shí)鐘編碼共有6種格式,即A、B、D、E、G、H。它們的主要差別是時(shí)間碼的幀速率不同,廣泛應(yīng)用的IRIG-B即其中的B型編碼,B型碼的時(shí)幀速率為1幀/s,可傳遞100位信息。圖1是IGIG-B碼示意圖,其時(shí)幀周期是1s,每秒100個(gè)碼元,使用脈寬編碼方式,每個(gè)碼元脈寬10ms,共三種碼元,其中高電平5ms和2ms分別表示二進(jìn)制 “1”,“0”,高電平8ms為位置標(biāo)識(shí),分別為P0,P1,…P9。連續(xù)兩個(gè)8ms寬度脈沖的第二個(gè)8ms脈沖的前沿為秒準(zhǔn)點(diǎn)標(biāo)志,也是一個(gè)時(shí)間格式的幀參考標(biāo)志。一個(gè)時(shí)間格式幀包含了秒,時(shí),分,天數(shù),年份,控制位等豐富的信息。
IRIG-B碼標(biāo)準(zhǔn)
首先在硬件連接上,我們使用GPIO23復(fù)用為接收IRIG-B碼脈沖信號(hào)的管腳,所以只需要將時(shí)鐘源發(fā)出的IRIG-B碼脈沖接到GPIO23,需要注意的是,GPIO管腳的輸入電壓不能超過(guò)3.3V,否則會(huì)引起CPU的異?;蚴菗p壞。如果時(shí)鐘源發(fā)出的脈沖為5V,就需要將電平轉(zhuǎn)換為3.3V才可以接入。硬件連接好后,我們來(lái)看看應(yīng)用程序的實(shí)現(xiàn)方法:
首先需要打開(kāi)IRIG-B這個(gè)設(shè)備節(jié)點(diǎn):
fd = open("/dev/irig-b", O_RDWR);
if(fd < 0)
printf("open faile\n");
接下來(lái)使用標(biāo)準(zhǔn)的調(diào)用接口read和write就可以獲取和設(shè)置時(shí)間了,程序中使用了struct tm這個(gè)結(jié)構(gòu)體來(lái)進(jìn)行獲取時(shí)間的信息傳遞:
structtm
{
inttm_sec; /* 秒. [0-60] (1 leap second) */
inttm_min; /* 分. [0-59] */
inttm_hour; /* 時(shí). [0-23] */
inttm_mday; /* 日. [1-31] */
inttm_mon; /* 月. [0-11] */
inttm_year; /* 年 - 1900. */
inttm_wday; /* 一周中的第幾天. [0-6] */
inttm_yday; /* 一年中的第幾天.[0-365] */
inttm_isdst; /* 時(shí)令. [-1/0/1]*/
#ifdef __USE_BSD
longinttm_gmtoff;
__constchar*tm_zone; /* 時(shí)區(qū) */
#else
longint__tm_gmtoff;
__constchar*__tm_zone;
#endif
};
因?yàn)槭侵苯訌臅r(shí)鐘源中獲取的時(shí)間,所以我們只需要關(guān)注tm結(jié)構(gòu)體中的年月日時(shí)分秒這六個(gè)成員。接下來(lái)我們進(jìn)行讀取時(shí)間的操作:
struct tm t;
ret = read(fd, &t,sizeof(struct tm));
if(ret < 0)
printf("read failed!\n");
printf("time:%d-%d-%d %d:%d:%d\n",t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
讀取時(shí)間是通過(guò)阻塞的方式實(shí)現(xiàn)的,板卡會(huì)等到一次完整的時(shí)間脈沖信息才會(huì)返回本次時(shí)間,如果沒(méi)有獲取到完整的信息,會(huì)在5秒后返回系統(tǒng)時(shí)間并且打印提示信息。
為了方便客戶將時(shí)鐘源提供的時(shí)間設(shè)置到板卡中,英創(chuàng)公司提供了專用接口在驅(qū)動(dòng)中獲取時(shí)間并寫(xiě)入到系統(tǒng)或是RTC中,即write()函數(shù),當(dāng)調(diào)用write時(shí),板卡會(huì)阻塞等待從時(shí)鐘源獲取一次完整的時(shí)間信息,然后根據(jù)寫(xiě)入的參數(shù),將時(shí)間直接設(shè)置到系統(tǒng)中或者RTC中:
#defineSET_SYSTIME 0
#defineSET_RTCTIME 1
i1 = SET_SYSTIME;
ret = write(fd, &i1,sizeof(int));
if(ret < 0)
printf("write failed!\n");
i1 = SET_RTCTIME;
ret = write(fd, &i1,sizeof(int));
if(ret < 0)
printf("write failed!\n");
按照上面的例子調(diào)用write就可以將從時(shí)鐘源獲取的時(shí)間寫(xiě)入到板卡中,當(dāng)輸入的數(shù)據(jù)為0時(shí),驅(qū)動(dòng)會(huì)阻塞等待一次完整的時(shí)間信息,獲得時(shí)間后將時(shí)間設(shè)置到系統(tǒng)中,阻塞等待的時(shí)間同樣為5s,否則返回不能獲取時(shí)間的信息。
如果輸入的數(shù)據(jù)為1時(shí),驅(qū)動(dòng)會(huì)同樣阻塞等待一次完整的時(shí)間信息,獲得時(shí)間后將時(shí)間同時(shí)設(shè)置到硬件實(shí)時(shí)時(shí)鐘和系統(tǒng)中,阻塞等待的時(shí)間同樣為5s,否則返回不能獲取時(shí)間的信息。
傳統(tǒng)的工控板卡在對(duì)IRIG-B碼處理時(shí),通常需要增加額外的硬件(如單片機(jī),FPGA)對(duì)B碼進(jìn)行解碼,然后再通過(guò)串口、總線或其它形式將數(shù)據(jù)交給主控板卡處理,增加了系統(tǒng)成本和操作難度,英創(chuàng)Linux工控主板EM928x系列可直接對(duì)B碼進(jìn)行解碼,不需要增加任何硬件就能實(shí)現(xiàn)毫秒級(jí)精度的時(shí)間同步,大大降低了系統(tǒng)復(fù)雜程度,節(jié)約了成本,提高了系統(tǒng)穩(wěn)定性。
-
Linux
+關(guān)注
關(guān)注
87文章
11329瀏覽量
209968 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6086瀏覽量
35486
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論