IEEE1588是精確網(wǎng)絡(luò)對(duì)時(shí)協(xié)議,簡稱PTP。它通過硬件實(shí)現(xiàn)的時(shí)間標(biāo)簽(hardware time stamp),使對(duì)時(shí)精度達(dá)到亞微秒級(jí)(< 1us),大大高于常規(guī)的網(wǎng)絡(luò)對(duì)時(shí)協(xié)議(NTP)。PTP協(xié)議的另一個(gè)特色是它可輸出精確時(shí)間同步的硬件脈沖,通常稱為PPS脈沖。在網(wǎng)絡(luò)化的嵌入式系統(tǒng)中,利用PTP的硬件PPS脈沖,可對(duì)處于不同位置的多臺(tái)設(shè)備實(shí)現(xiàn)同步觸發(fā)的功能。這對(duì)分布式系統(tǒng)的數(shù)據(jù)采集、實(shí)時(shí)控制都具有非常的意義。
英創(chuàng)公司的多款嵌入式主板,ESM7000、ESM6802和ESM6800,其網(wǎng)絡(luò)接口均支持PTP協(xié)議,且可輸出PPS脈沖,因此是分布式智能設(shè)備的理想嵌入式平臺(tái)。以下將以ESM7000為例,介紹實(shí)現(xiàn)分布式同步觸發(fā)的軟硬件方案。
基于PTP的同步觸發(fā)軟件流程
ESM7000預(yù)裝的Linux平臺(tái)文件系統(tǒng)中,已包含了PTP對(duì)時(shí)及硬件時(shí)間同步的完整工具,即ptp4l和phc2sys,同時(shí)可方便的控制PPS脈沖的使能。在這個(gè)基礎(chǔ)上,按照?qǐng)D1所示流程就可實(shí)現(xiàn)同步觸發(fā)的功能。
圖1同步觸發(fā)軟件流程
在實(shí)際的測試中發(fā)現(xiàn),PTP的對(duì)時(shí)精度與網(wǎng)絡(luò)環(huán)境有密切關(guān)系。在單一的100M網(wǎng)絡(luò)環(huán)境所獲得的設(shè)備間的同步精度在±200ns;而在1000M網(wǎng)環(huán)境,同步精度就下降到±1us;混合網(wǎng)絡(luò)環(huán)境,同步精度可差至±15us。
同步觸發(fā)脈沖的硬件方案
所謂硬件方案,是指圖1中觸發(fā)脈沖生成器的實(shí)現(xiàn)方案。以PTP協(xié)議生成的周期性PPS脈沖為基礎(chǔ),由應(yīng)用程序生成觸發(fā)使能信號(hào),再通過一個(gè)簡單的D觸發(fā)器生成最后的觸發(fā)脈沖。硬件方案涉及3個(gè)信號(hào)如下:
●PPS_OUT:整秒脈沖輸出,即周期固定為1秒,在ESM7000上,PPS的脈沖寬度為10ns,上升沿有效。
●TRG_EN:觸發(fā)使能,通常用一位GPIO來實(shí)現(xiàn),其高電平有效。
●TRG_PULSE:觸發(fā)脈沖,上升沿有效;在TRG_EN為低時(shí),將強(qiáng)制TRG_PULSE為低;當(dāng)TRG_EN為高時(shí),后續(xù)的PPS_OUT脈沖上升沿將鎖存高電平,從而是TRG_PULSE變高電平。TRG_PULSE脈沖上升沿將將作為系統(tǒng)采集控制硬件單元的觸發(fā)輸入,觸發(fā)各個(gè)嵌入式設(shè)備同步動(dòng)作。
圖2同步觸發(fā)脈沖生成電路原理圖
在圖2中,TRG_PULSE還可反饋給ESM7000主板,通知同步觸發(fā)已發(fā)生。但不是必須的。
大部分ESMARC主板均可支持PTP同步觸發(fā)功能。對(duì)不同型號(hào)的主板,PPS脈沖輸出管腳有所不同,如下表所示:
主板型號(hào) | PTP網(wǎng)口 | PPS信號(hào)管腳 | 備注 |
ESM7000系列 | eth0 | CN2.GPIO0 | |
ESM6802系列 | eth0 | CN2.GPIO24 | V2.4版才支持 |
ESM6800系列 | eth1 | CN2.GPIO22 | 不能使用SD卡 |
ES6801 | eth0 | CN1.GPIO0 | 不能使用CAN1 |
對(duì)選擇哪一位GPIO管腳作為TRG_EN,本方案沒有限制??筛鶕?jù)設(shè)備的具體情況來確定。
對(duì)同步觸發(fā)從設(shè)備測試
本測試用從設(shè)備的“當(dāng)前時(shí)間+ 偏移量”來代替主設(shè)備發(fā)布的觸發(fā)時(shí)間TRGTIME,就可用簡單的腳本測試整個(gè)觸發(fā)過程,具體的腳本如下:
#!/bin/sh # trg_en_3 $1 [$2] [$3] # $1 = 0, off ptp; = 1: on ptp # $2 = number of seconds to delay from cuurent time # $3 = ip:port PATH="/usr/bin:$PATH" E_NOARGS=85 re='^[0-9]+$' TRG_EN_GPIO="gpio1" TRG_EN_DIRECTORY="/sys/class/em_gpio/em_gpio/$TRG_EN_GPIO" PHC2SYSLOG="/tmp/phc2syslog.txt" DELAY=10 # if no arg, exit if [ -z "$1" ] then echo "Usage: `basename $0` filename" exit $E_NOARGS fi # if $1 != 1, off ptp and exit if [ "$1" -ne 1 ] then echo 0 > /sys/class/ptp/ptp0/pps_enable pkill phc2sys pkill ptp4l exit 0 fi # get trigger delay is available, default = 10(s) if [ $# -ge 2 ] then DELAY="$2" fi # now we start to make trg_en step by step echo "step 1: setup gpio1 as trg_en" if [ ! -d "$TRG_EN_DIRECTORY" ] then echo "config $TRG_EN_GPIO as trg_en" echo 1 > /sys/class/em_gpio/em_gpio/export fi echo out > /sys/class/em_gpio/em_gpio/$TRG_EN_GPIO/direction echo 0 > /sys/class/em_gpio/em_gpio/$TRG_EN_GPIO/value echo "step 2: start ptp" phc2sys -s eth0 -c CLOCK_REALTIME -w -m -u 4 > $PHC2SYSLOG & sleep 1 ptp4l -i eth0 -s & echo "step 3: wait phc2sys sync convergence" num_rms=0 while [ "$num_rms" -lt 3 ] do RMS_ARRAY=$(cat $PHC2SYSLOG | tail -n 3 | sed -r 's/.*rms[ ]+([0-9]+).*/\1/g') # echo "$RMS_ARRAY" for rms in $RMS_ARRAY do if ! [[ $rms =~ $re ]] then echo "$rms is NOT an integer!" break fi echo "$rms" if [ "$rms" -lt 350 ]; then let "num_rms += 1" fi done # clear log file if rms is convergence if [ "$num_rms" -ge 3 ]; then echo "rms is convergence ($num_rms)" cat /dev/null > $PHC2SYSLOG else let "num_rms = 0" sleep 2 fi done echo "step 4: enable pps, and setup trigger time" echo 1 > /sys/class/ptp/ptp0/pps_enable TRGTIME=$(date +%s) # get current date in seconds let "TRGTIME = $TRGTIME + $DELAY" PPSTIME=$(cat /sys/class/pps/pps0/assert | cut -d '.' -f 1) echo "TRGTIME = $TRGTIME PPSTIME = $PPSTIME" echo "step 5: wait pps time reach trigger time" while [ "$PPSTIME" -lt "$TRGTIME" ] do sleep 0.1 PPSTIME=$(cat /sys/class/pps/pps0/assert | cut -d '.' -f 1) done echo "step 6: now PPSTIME = TRGTIME, set trg_en" echo 1 > /sys/class/em_gpio/em_gpio/$TRG_EN_GPIO/value echo "step 7: wait pps time reach trigger time + 1" let "TRGTIME = $TRGTIME + 1" while [ "$PPSTIME" -lt "$TRGTIME" ] do sleep 0.1 PPSTIME=$(cat /sys/class/pps/pps0/assert | cut -d '.' -f 1) done echo "step 8: clear trg_en" echo 0 > /sys/class/em_gpio/em_gpio/$TRG_EN_GPIO/value echo "basename $0 done" |
從示波器可觀察到,上述腳本產(chǎn)生的TRG_EN信號(hào),準(zhǔn)確使能PPS脈沖產(chǎn)生與之上升沿完全同步的觸發(fā)脈沖TRG_PULSE。
對(duì)分布式系統(tǒng)同步觸發(fā)功能感興趣的客戶,可通過郵件support@emtronix.com與英創(chuàng)公司技術(shù)部門聯(lián)系,以了解詳細(xì)的實(shí)現(xiàn)代碼。
-
Linux
+關(guān)注
關(guān)注
87文章
11164瀏覽量
208469 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6083瀏覽量
35097
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論