陳韋達(dá),張 岡,陳 冰,崔自賞
(華中科技大學(xué)機(jī)械科學(xué)與工程學(xué)院,湖北武漢 430000)
工業(yè)以太網(wǎng)總線在現(xiàn)代的工業(yè)生產(chǎn)中有著廣泛應(yīng)用,可以進(jìn)行高精度的數(shù)據(jù)采集,運(yùn)動控制等任務(wù)?,F(xiàn)有的工業(yè)現(xiàn)場總線技術(shù)有EtherCAT、CANopen、CC-link以及ProfiNET等,其中EtherCAT具有高傳輸速率、低延時、低抖動等優(yōu)點。其具有的高時鐘同步精度使其被廣泛用于高速高精度的行業(yè)[1]。其分布式時鐘(distributed clock,DC)機(jī)制可以同步所有支持該機(jī)制的從站時鐘,使得從站節(jié)點之間同步時鐘抖動達(dá)到1 ns以內(nèi)[2]?;谏鲜鰞?yōu)點,EtherCAT成為了伺服電機(jī)的主要通信方法。作為高精度實時控制和高速數(shù)字采集的方法,對其控制程序的實時性也提出了要求,而目前的研究和主站實現(xiàn),在使用通用網(wǎng)卡的X86設(shè)備上的實時性能力仍有待提高。
國內(nèi)有實驗室研發(fā)了EtherCAT在嵌入式平臺的主站,如使用STM43F407與LAN9252芯片[3],ZYNQ芯片在嵌入式下實現(xiàn)[4],其EtherCAT主站在1 ms的周期下測得的通訊抖動為6~7 μs,進(jìn)一步使用FPGA實現(xiàn),抖動可以降到1 μs以內(nèi)[5]。在X86平臺下的主站需要進(jìn)行內(nèi)核的改造,在使用了EtherCAT的專屬網(wǎng)卡下,周期為1 ms的低速周期,抖動達(dá)到80 μs級別[6]??梢娫赬86平臺內(nèi)核改造較為復(fù)雜,且實時性能有限。
在X86下開發(fā)主站與嵌入式下相比也有明顯的優(yōu)點:
(1)性能上X86架構(gòu)要比ARM強(qiáng)大得多,用戶層面的運(yùn)動控制可以使用更復(fù)雜的算法與上層軟件開發(fā)。
(2)擴(kuò)展性更強(qiáng),X86架構(gòu)下需要添加CPU、內(nèi)存或者硬盤都比嵌入式的環(huán)境更容易。
(3)簡易性,采用嵌入式需要自己進(jìn)行嵌入式的設(shè)計以及對嵌入式的網(wǎng)卡驅(qū)動進(jìn)行改造,開發(fā)難度大。而實驗團(tuán)隊都會有X86的工控機(jī)或者PC,只需要安裝IGH與PREEMPT_RT補(bǔ)丁就可以進(jìn)行進(jìn)一步的開發(fā)與測試。即便不具備IGH要求的專用網(wǎng)卡,也可以實現(xiàn)EtherCAT的控制。
實時Linux的方案也有使用單內(nèi)核的PREEMPT_RT補(bǔ)丁,或者雙內(nèi)核的RTAI,Xenomai,其中實時補(bǔ)丁增加了操作系統(tǒng)中高精度定時器和硬實時內(nèi)核的實現(xiàn),能夠完成對EtherCAT報文的控制。相比于Xenomai這種雙內(nèi)核機(jī)制,安裝更簡單。
基于上述原因,在通用的X86平臺上,使用通用的網(wǎng)卡,在簡單的PREEMPT_RT補(bǔ)丁上,基于開源的IGH主站方案搭建EtherCAT主站,并進(jìn)行實時性能的優(yōu)化,使其使用這些通用設(shè)備也能滿足高性能的實時運(yùn)動控制需求。
圖1為任務(wù)控制到網(wǎng)卡報文發(fā)送的數(shù)據(jù)流與主站結(jié)構(gòu)。運(yùn)動任務(wù)可以從用戶層使用應(yīng)用層接口,或者從內(nèi)核空間將運(yùn)動控制命令傳遞到IGH EtherCAT master模塊。IGH EtherCAT master模塊處理與封裝EtherCAT報文,發(fā)往通用以太網(wǎng)驅(qū)動模塊,通用以太網(wǎng)驅(qū)動模塊將報文交由網(wǎng)絡(luò)協(xié)議棧發(fā)送到外部設(shè)備,也就是EtherCAT總線連接的伺服電機(jī)。
圖1 EtherCAT主站架構(gòu)
實驗平臺使用的是Intel(R)Core(TM)i5-6500 CPU @ 3.20 GHz的4核CPU,Intel的I210網(wǎng)卡,安裝了Linux的發(fā)行版Ubuntu 18.04,安裝Linux 4.19.37版本的實時補(bǔ)丁。編譯安裝IGH1.5.2版本。在用戶層編寫電機(jī)任務(wù)程序使其在位置模式下運(yùn)動。將通信周期設(shè)置在200 μs。
通信抖動使用ET2000測試。整個測試系統(tǒng)如圖2所示。主站報文經(jīng)由ET2000的端口連接從站1邁信伺服電機(jī)。ET2000是具有四通道的工業(yè)以太網(wǎng)分析設(shè)備,其在每一個報文上打上高精度的時間戳,從自己的輸出口輸出,用于高精度的時間分析,可使用wireshark抓包后分析內(nèi)容,有EtherCAT Switch Link一項,內(nèi)容如圖3所示。
圖2 測試系統(tǒng)結(jié)構(gòu)
圖3 wireshark抓包內(nèi)容分析
圖3中port表示經(jīng)過的ET2000的端口號,timestamp即為經(jīng)過端口時,ET2000給報文加上的時間戳。時間戳為十六進(jìn)制表示的絕對時間,單位為ns,分析時需將其轉(zhuǎn)化為十進(jìn)制。端口號相同,序號相連的報文做差即可得到ns精度的報文周期時間。抓取50 000個從主站發(fā)往從站的EtherCAT報文,通過高精度時間戳計算報文之間的時間差,見圖4;加上負(fù)載后,測量50 000組報文的周期時間抖動,見圖5。
圖4 不帶負(fù)載的測試結(jié)果
圖5 帶負(fù)載的測試結(jié)果
圖5測試中的負(fù)載,為開啟50個進(jìn)程,每個進(jìn)程執(zhí)行一個死循環(huán),從而占用大量CPU資源,用于測試運(yùn)動控制程序在CPU忙碌狀態(tài)下實時性的能力。選取4個指標(biāo)來判斷實時性能力,200 μs通信周期下,時間抖動的均值、最大值,用于考察抖動時間,并且計算抖動值超過200 μs的大抖動出現(xiàn)百分比、50 000個測試周期中超過200 μs的大抖動個數(shù),用于考察大抖動出現(xiàn)的頻率。見表1。
表1 基本實時性測試結(jié)果
在帶負(fù)載條件下,最大抖動的時間達(dá)到了1 ms以上而且大抖動報文出現(xiàn)的頻率也提高了。不帶負(fù)載的情況下的平均抖動數(shù)值與國內(nèi)其他團(tuán)隊在X86平臺上的實驗結(jié)果保持量級上的一致[3]。而最大抖動因為是通用X86平臺以及實時補(bǔ)丁原因,達(dá)到了1 ms以上。
提出4種優(yōu)化方案,使用高精度定時器,內(nèi)核模塊運(yùn)行,隔離CPU以及設(shè)定CPU固定頻率。將其不同組合以及是否承載負(fù)載進(jìn)行實驗,同樣提取關(guān)鍵的4個指標(biāo)繪制出表2、表3。其中,load50表示承載50個忙碌進(jìn)程的負(fù)載,CPU表示做了CPU的隔離,使該CPU只運(yùn)行本運(yùn)動控制程序。3.2 GHz為對CPU頻率進(jìn)行設(shè)置。
表2 用戶空間下不同測試條件下的關(guān)鍵指標(biāo)對比
表3 內(nèi)核空間下不同測試條件下的關(guān)鍵指標(biāo)對比
考慮到實時Linux提供了高精度休眠函數(shù)nanosleep,以及preempt-rt補(bǔ)丁中對其進(jìn)行了實時性的重構(gòu)。使用nanosleep替代之前的usleep睡眠函數(shù)將有效提高計時精度,其中關(guān)鍵代碼如下:
clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&nextnanosleeptime,NULL);
nextnanosleeptime.tv_nsec += cyctime;
nanoSecondFieldConversion(&nextnanosleeptime);
同樣進(jìn)行正常環(huán)境以及高負(fù)載環(huán)境測試,將其與基礎(chǔ)測試結(jié)果繪制在一個散列圖可以直觀地觀察到效果,見圖6。
圖6 無負(fù)載下nanosleep和usleep實時性測試結(jié)果對比
如圖6所示,使用了高精度定時器后,平均抖動得到了很好的改善,在不負(fù)載的情況下延時抖動從86 μs下降到14 μs以下。但在負(fù)載情況下,大抖動的出現(xiàn)個數(shù)和抖動最大值并沒有很大改進(jìn),仍大于1 ms。大抖動出現(xiàn)的原因和內(nèi)核調(diào)度有關(guān),使用高精度的計時器改善不大。
參考圖1可以將運(yùn)動任務(wù)編寫為內(nèi)核模塊,在內(nèi)核空間中加載,可以直接使用IGH的內(nèi)核層函數(shù),從而減少了內(nèi)核層到用戶層的上下文切換的時間。因為周期任務(wù)由內(nèi)核的計時器觸發(fā),內(nèi)核層的代碼相比于用戶層,擁有更好的實時性性能,對每個周期的響應(yīng)時間更有保證。
內(nèi)核模塊的計時方法有2種:一種是忙等待,即使用udelay函數(shù),在等待下一次報文發(fā)送的時間里,程序?qū)⒊掷m(xù)占用CPU。udelay使用的是軟件循環(huán),根據(jù)引導(dǎo)期間算出的處理器速度以及l(fā)oops_pre_jiffy整數(shù)變量來確定循環(huán)的次數(shù)。小于1 ms的短延時任務(wù)使用udelay是合適的,但缺點是等待的方式會大量占用CPU資源,為系統(tǒng)增加沉重的負(fù)擔(dān)。另一種方式是使用計時函數(shù)schedule_hrtimeout,該函數(shù)使用了高精度定時器的任務(wù)調(diào)度方式,在回調(diào)函數(shù)處理完周期任務(wù)后,向內(nèi)核的高精度計時器的紅黑樹中重新注冊自身,等待下一次計時時間到被再次調(diào)用。注冊結(jié)束后函數(shù)運(yùn)行結(jié)束,讓出CPU資源,使得其他進(jìn)程可以被CPU運(yùn)行。
測試結(jié)果顯示,使用schedule_hrtimeout的抖動均值和使用高精度定時器的用戶層方案效果一致??梢钥闯觯?00 μs這樣的短周期下,由于更高級別任務(wù)占用CPU資源的原因,使用任務(wù)的調(diào)度方式即便是在內(nèi)核態(tài),也仍然是會出現(xiàn)較大時長的抖動。使用udelay的忙等待方式在最大抖動數(shù)值以及大抖動報文出現(xiàn)的頻率上都有很好的改善。如圖7所示,負(fù)載模式下內(nèi)核層udelay和用戶層的usleep,nanosleep作為周期任務(wù)延時函數(shù)相比,udelay的忙等待模式要優(yōu)異很多。
圖7 負(fù)載下使用usleep、nanosleep和udelay實時性測試結(jié)果對比
在Linux系統(tǒng)中,進(jìn)程的調(diào)度是由內(nèi)核完成的。在多核系統(tǒng)中,進(jìn)程有可能在多個不同的CPU上來回執(zhí)行,這使得CPU無法從高速緩存中加載得到運(yùn)行時上下文,而需要從內(nèi)存中獲取,從而影響每次周期任務(wù)執(zhí)行的時間造成報文周期抖動??紤]將一個CPU隔離開,不運(yùn)行其他用戶進(jìn)程以及中斷函數(shù),只運(yùn)行EthetCAT的運(yùn)動控制任務(wù)。這樣在該任務(wù)中可以實現(xiàn)高實時要求、高效能的計算。從而實現(xiàn)更低的延時抖動。
如圖8所示,使用htop命令查看各個CPU的使用狀態(tài)。當(dāng)在/etc/default/grub文件中修改參數(shù),“isolCPUs=2”,sudo update-grub更新后重啟。
圖8 隔離CPU后的運(yùn)行情況
由圖8可知,CPU2(內(nèi)核從0開始編號)不在工作。使用kthread_bind將內(nèi)核線程綁定到該CPU上。同樣進(jìn)行帶負(fù)載與不帶負(fù)載測試。由表2可以看到,當(dāng)隔離CPU后,最大抖動的值在各種方式下都有很大的改善,僅在用戶層使用usleep的情況下,出現(xiàn)了一個超過200 μs的報文抖動。其在負(fù)載下也有很好的表現(xiàn),由于CPU超頻的原因,在負(fù)載情況下的最大抖動和抖動均值都小于相應(yīng)情況下不帶負(fù)載的結(jié)果。在帶負(fù)載的情況下,最大實時抖動在70 μs以下,均值抖動在1 μs以內(nèi),完全可以達(dá)到高性能實時控制的要求。
由于Linux對CPU的驅(qū)動默認(rèn)狀態(tài)為節(jié)能模式,通常以最低頻率運(yùn)行,根據(jù)忙碌程度來動態(tài)增加CPU的頻率。不利于高實時要求的控制程序。對于周期性任務(wù),CPU以恒定頻率運(yùn)行。
修改/sys/devices/system/CPU/CPU2/CPUfreq/scaling_governor文件中的CPU運(yùn)行模式為performance(最佳性能模式),使用命令sudo CPUfreq-set-c 2-u 3200000設(shè)定CPU2頻率為3.20 GHz,使其與CPU性能參數(shù)一致。然后進(jìn)行實時性測試。由圖9、圖10可知進(jìn)行了CPU頻率的設(shè)定后,實時性能進(jìn)一步提高。最大抖動在50 μs以內(nèi),均值抖動在0.6 μs以內(nèi)。
圖9 不帶負(fù)載隔離CPU情況下有無設(shè)置CPU頻率的實驗數(shù)據(jù)對比
圖10 帶負(fù)載隔離CPU情況下有無設(shè)置CPU頻率的實驗數(shù)據(jù)對比
本文在通用的X86平臺上,使用通用的網(wǎng)卡,在簡單的Preempt_RT補(bǔ)丁上,基于開源的IGH主站方案搭建EtherCAT主站,提出使用高精度定時器,以內(nèi)核模塊方式運(yùn)行,隔離CPU以及設(shè)定CPU頻率4個優(yōu)化措施,優(yōu)化控制程序的實時性能,使其在帶負(fù)載的CPU忙碌情況下實時性能也能達(dá)到最大抖動在50 μs以內(nèi),均值抖動在0.6 μs以內(nèi)。使得即使使用通用X86平臺,通用網(wǎng)卡,簡單的實時補(bǔ)丁,也完全可以達(dá)到高性能高精度運(yùn)動控制和數(shù)據(jù)采集的要求。其在工業(yè)運(yùn)動控制和傳感器數(shù)據(jù)采集領(lǐng)域都有良好應(yīng)用前景。