王晨博,孟博,張楠
(中航工業(yè)西安航空計(jì)算技術(shù)研究所,陜西西安,710068)
關(guān)鍵字:RTnet;端到端時(shí)延;Linux;TDMA
在對(duì)實(shí)時(shí)性要求較高的系統(tǒng)中,采用TCP協(xié)議雖然可提供可靠的通信服務(wù),然而其三次握手協(xié)議增加了額外的時(shí)間開銷,導(dǎo)致數(shù)據(jù)傳輸不具備有界的傳輸時(shí)延。目前有很多機(jī)構(gòu)進(jìn)行了實(shí)時(shí)以太網(wǎng)通信的研究,但是大部分方案只能提供數(shù)據(jù)傳輸?shù)能泴?shí)時(shí)保證,其它一些方案需要多節(jié)點(diǎn)的架構(gòu)設(shè)計(jì)進(jìn)行適應(yīng)性更改,不具備適用性。RTnet是一個(gè)與Linux網(wǎng)絡(luò)子系統(tǒng)類似的網(wǎng)絡(luò)協(xié)議棧,能夠在不改變現(xiàn)有網(wǎng)絡(luò)硬件的前提下提供硬實(shí)時(shí)保證。
RTnet是一個(gè)基于RTAI或Xenomai的開源硬實(shí)時(shí)網(wǎng)絡(luò)協(xié)議棧,由德國漢諾威大學(xué)的Ulrich Marx開發(fā),RTnet使用標(biāo)準(zhǔn)以太網(wǎng)設(shè)備,支持包括千兆以太網(wǎng)的多種網(wǎng)絡(luò)適配器。RTnet以確定性的方式實(shí)現(xiàn)UDP/IP、TCP/IP、ICMP和ARP等協(xié)議,并為內(nèi)核空間和用戶空間之間提供了POSIX Socket API接口[1]。為了避免以太網(wǎng)中不可預(yù)測的沖突和擁塞,RTnet中設(shè)置了一個(gè)額外的實(shí)時(shí)媒體訪問控制層RTmac。
RTnet的關(guān)鍵技術(shù)就是時(shí)分多址(TDMA)技術(shù),采用改進(jìn)的Linux操作系統(tǒng)結(jié)合RTnet實(shí)時(shí)協(xié)議棧來提高以太網(wǎng)實(shí)時(shí)性。本文搭建了一個(gè)使用RTnet協(xié)議棧的多節(jié)點(diǎn)和交換機(jī)的網(wǎng)絡(luò)拓?fù)?,并設(shè)計(jì)了主節(jié)點(diǎn)和從節(jié)點(diǎn)之間的數(shù)據(jù)傳輸時(shí)間延遲測試方案。
RTnet參考了標(biāo)準(zhǔn)Linux的模塊化設(shè)計(jì)思想,可以根據(jù)需要加載相應(yīng)的模塊。RTnet的動(dòng)態(tài)模塊主要包括UDP/IP協(xié)議、數(shù)據(jù)包管理、RTcap、RTcfg、RTmac、Socket API、RT driver等模塊,這些動(dòng)態(tài)模塊的具體描述如下:
(1)數(shù)據(jù)包管理。包管理通過實(shí)時(shí)任務(wù)處理包的傳輸和接收。在發(fā)送端,數(shù)據(jù)包通過協(xié)議棧發(fā)送出去。在接收端,數(shù)據(jù)包從實(shí)時(shí)驅(qū)動(dòng)層接收到堆棧管理。棧管理的功能是根據(jù)不同的協(xié)議類型進(jìn)行分組。棧管理的優(yōu)先級(jí)高于所有需要RTnet服務(wù)的任務(wù),這種機(jī)制旨在避免優(yōu)先級(jí)倒置。RTnet將分片數(shù)據(jù)包存儲(chǔ)在“rtskbs”的數(shù)據(jù)結(jié)構(gòu)中,所有的rtskb都有一個(gè)固定的大小而且可以裝在最大長度的數(shù)據(jù)包。與普通堆棧不同,rtskbs必須以嚴(yán)格確定的方式進(jìn)行分配。由于這個(gè)原因,rtskb被預(yù)先分配到多個(gè)池中,每個(gè)池對(duì)應(yīng)數(shù)據(jù)包的生產(chǎn)者或消費(fèi)者。使用時(shí)從池中獲取,如果池中沒有足夠的rtskb則獲取失敗。
(2)UDP/IP協(xié)議。與常規(guī)的UDP/IP協(xié)議棧相比,動(dòng)態(tài)ARP被轉(zhuǎn)換為靜態(tài)配置,簡化了路由和地址解析。通過動(dòng)態(tài)加載rtipv4.ko或rtipv6.ko模塊可以實(shí)現(xiàn)這種性能。RTnet路由基于兩個(gè)表:主路由表和可選網(wǎng)絡(luò)路由表。主路由表包含所有可以通過本網(wǎng)段直接到達(dá)的目的IP地址??蛇x路由表僅在需要不同的網(wǎng)絡(luò)通信時(shí)使用。RTnet在發(fā)送大數(shù)據(jù)包時(shí),通過IP分片將數(shù)據(jù)包在網(wǎng)絡(luò)上分成多個(gè)部分進(jìn)行發(fā)送。在接收端,RTnet棧中的IP層接收一系列分片的IP數(shù)據(jù)包,并將它們重新組合,然后將整個(gè)數(shù)據(jù)包傳遞給UDP層。
(3)RT driver。RTnet下的網(wǎng)卡驅(qū)動(dòng)采用了和Linux類似的架構(gòu),為了對(duì)數(shù)據(jù)包時(shí)間戳進(jìn)行精確管理,RTnet沒有采用NIC內(nèi)置的時(shí)間戳,而是在接收中斷和數(shù)據(jù)包發(fā)送時(shí)進(jìn)行記錄[4]。為了支持RTcap和RTmac,還提供了發(fā)送重定向和訪問MTU的接口。
(4)API接口。應(yīng)用程序可以通過POSIX兼容的socket接口和IO接口使用RTnet。本設(shè)計(jì)中使用到的RTnet API接口包括:rt_dev_open()、rt_dev_socket()、rt_dev_close()、rt_dev_ioctl()、rt_dev_read()、rt_dev_write()、rt_dev_recvmsg()、rt_dev_recvfrom()、rt_dev_recv()、rt_dev_sendmsg()、rt_dev_sendto()、rt_dev_send()、rt_dev_bind()、rt_dev_connect()、rt_dev_listen()、rt_dev_accept()和 rt_dev_shutdown()。
(5)RTmac。實(shí)時(shí)媒體訪問控制(RTmac)為RTnet提供TDMA訪問策略。RTmac基于主/從節(jié)點(diǎn)的工作模式。如果第一主節(jié)點(diǎn)不工作,可以使用其他主節(jié)點(diǎn)。一個(gè)主節(jié)點(diǎn)周期性的發(fā)送數(shù)據(jù)到所有從節(jié)點(diǎn),每一個(gè)節(jié)點(diǎn)(包含主節(jié)點(diǎn))在一個(gè)TDMA周期中至少擁有一個(gè)時(shí)隙,在該分配的時(shí)隙中節(jié)點(diǎn)可以向外發(fā)送數(shù)據(jù)。在不同配置模式中,一個(gè)節(jié)點(diǎn)可能在TDMA周期中擁有多個(gè)時(shí)隙,多種TDMA的分配策略如圖1所示。若遇到一個(gè)時(shí)隙分配給多個(gè)節(jié)點(diǎn),則按照節(jié)點(diǎn)的優(yōu)先級(jí)進(jìn)行排隊(duì),最高優(yōu)先級(jí)的節(jié)點(diǎn)在當(dāng)前周期發(fā)送數(shù)據(jù),次優(yōu)先級(jí)的節(jié)點(diǎn)在第二個(gè)TDMA周期中的對(duì)應(yīng)時(shí)隙發(fā)送數(shù)據(jù),保證了高優(yōu)先級(jí)實(shí)時(shí)數(shù)據(jù)的確定性傳輸。該模塊中配置了32個(gè)節(jié)點(diǎn)優(yōu)先級(jí),最低的優(yōu)先級(jí)是為非實(shí)時(shí)協(xié)議保留的[5]。在使用RTmac實(shí)時(shí)拓展時(shí),需要?jiǎng)討B(tài)加載tdma.ko和rtmac.ko模塊。通過使用RTmac實(shí)時(shí)拓展,可以使網(wǎng)絡(luò)中的數(shù)據(jù)以確定的時(shí)間片進(jìn)行發(fā)送,保證有界的數(shù)據(jù)傳輸延遲,增加數(shù)據(jù)傳輸?shù)拇_定性和可靠性。
圖1 TDMA策略
(6)RTcap。主要用于網(wǎng)絡(luò)發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的捕獲,用于進(jìn)行網(wǎng)絡(luò)傳輸特性分析。其時(shí)間戳抖動(dòng)非常低,通常低于10us。RTcap.ko動(dòng)態(tài)模塊需要在所有網(wǎng)絡(luò)接口設(shè)備的驅(qū)動(dòng)加載之后再加載。
本文主要對(duì)數(shù)據(jù)包往返時(shí)間RTT進(jìn)行測試。首先使用TCP/IP協(xié)議棧對(duì)節(jié)點(diǎn)間的數(shù)據(jù)傳輸延遲進(jìn)行測試并記錄,之后加載RTAI和RTnet的相關(guān)動(dòng)態(tài)模塊,完成Linux從內(nèi)核到協(xié)議棧的實(shí)時(shí)化轉(zhuǎn)換,然后對(duì)使用RTnet協(xié)議棧的節(jié)點(diǎn)間數(shù)據(jù)傳輸延遲進(jìn)行測試。RTAI的動(dòng)態(tài)模塊主要包括rt_make_hard_real_time()和rt_make_soft_real_time(),其主要功能為進(jìn)行內(nèi)核空間與用戶空間的相互轉(zhuǎn)換,使測試數(shù)據(jù)的發(fā)送和接收任務(wù)在內(nèi)核中完成,而不是在用戶空間傳送,這樣使得任務(wù)的優(yōu)先級(jí)變?yōu)樽罡?,保證其實(shí)時(shí)性。
測試使用若干臺(tái)PC機(jī)和COTS交換機(jī),其中一臺(tái)作為主節(jié)點(diǎn),剩余PC機(jī)作為從節(jié)點(diǎn),所有節(jié)點(diǎn)在一個(gè)網(wǎng)段內(nèi),測試網(wǎng)絡(luò)拓?fù)淙鐖D2所示。
圖2 測試網(wǎng)絡(luò)拓?fù)?/p>
主從節(jié)點(diǎn)配置操作系統(tǒng)為Linux fedora 2.6版本,在進(jìn)行通信測試前,需要在Linux fedora 2.6的基礎(chǔ)上進(jìn)行內(nèi)核的實(shí)時(shí)化拓展,添加RTAI(Real Time Application Interface)動(dòng)態(tài)加載模塊,最后加載RTnet模塊。本文選用的RTAI版本為RTAI-3.6.2,RTnet版本為0.9.10。
在運(yùn)行RTnet網(wǎng)絡(luò)協(xié)議之前,首先禁用 Linux系統(tǒng)的網(wǎng)絡(luò)接口設(shè)備,并卸載Linux 系統(tǒng)的網(wǎng)絡(luò)接口設(shè)備的驅(qū)動(dòng)[2]。然后加載實(shí)時(shí)網(wǎng)絡(luò)接口設(shè)備相關(guān)的驅(qū)動(dòng),具體的操作系統(tǒng)實(shí)時(shí)化步驟如下所示。
其中,RTAI模塊完成了對(duì)Linux內(nèi)核的實(shí)時(shí)性改進(jìn)。
測試軟件主要包括發(fā)送模塊、接收模塊,數(shù)據(jù)庫模塊和主控制模塊四個(gè)部分。數(shù)據(jù)庫模塊用來在準(zhǔn)備階段產(chǎn)生網(wǎng)絡(luò)數(shù)據(jù)庫文件,包括源/目的IP地址、源/目的端口和數(shù)據(jù)長度等。在硬實(shí)時(shí)模式下,發(fā)送模塊完成初始化操作,使用mailbox機(jī)制將數(shù)據(jù)包發(fā)送至主控制模塊。接收模塊完成初始化操作,使用mailbox機(jī)制從主控制模塊獲取數(shù)據(jù)包。主控制模塊包含若干發(fā)送和接收線程,發(fā)送線程完成數(shù)據(jù)包的組包,封裝等操作并發(fā)送至以太網(wǎng),接收線程完成數(shù)據(jù)接收解析,之后將數(shù)據(jù)包通過mailbox傳遞至接收模塊。
mailbox服務(wù)由RTAI調(diào)度器提供,mailbox相關(guān)的API接口函數(shù)包括:rt_mbx_init ()、rt_mbx_delete ()、rt_mbx_send ()、rt_mbx_if ()、rt_mbx_until ()、rt_mbx_timed ()、rt_mbx_receive ()。使用mailbox服務(wù)時(shí)需要將rtai_sched. ko模塊加載進(jìn)Linux內(nèi)核內(nèi)。
按照?qǐng)D3搭建測試環(huán)境,本時(shí)延測試使用主節(jié)點(diǎn)和從節(jié)點(diǎn)A進(jìn)行。配置TDMA循環(huán)長度為1ms,在1個(gè)TDMA周期中主節(jié)點(diǎn)和從節(jié)點(diǎn)A分別有兩個(gè)200us的發(fā)送時(shí)隙。主節(jié)點(diǎn)發(fā)送請(qǐng)求數(shù)據(jù)幀,配置數(shù)據(jù)幀長度為1000字節(jié)。從節(jié)點(diǎn)A收到該數(shù)據(jù)幀后立即回復(fù)主節(jié)點(diǎn)一個(gè)相應(yīng)數(shù)據(jù)幀。
圖3 主從節(jié)點(diǎn)時(shí)間片均為200us
采用TCP/IP協(xié)議棧與采用RTNET協(xié)議棧分別進(jìn)行測試的結(jié)果如表1所示,由于經(jīng)過RTAI改造的Linux內(nèi)核的時(shí)鐘精度得到提高,因此RTnet協(xié)議棧的測試結(jié)果取值可以精確到0.1us。
表1 RTT測試統(tǒng)計(jì)結(jié)果
從測試結(jié)果可以看出,采用TCP/IP協(xié)議棧傳輸時(shí),RTT平均值較大,且標(biāo)準(zhǔn)差很大。采用RTNET協(xié)議棧傳輸時(shí),RTT平均值與抖動(dòng)均有很大程度降低,滿足數(shù)據(jù)的實(shí)時(shí)性需要。
通過對(duì)傳統(tǒng)交換式以太網(wǎng)進(jìn)行實(shí)時(shí)性改進(jìn),測試了使用RTAI和RTnet技術(shù)后的網(wǎng)絡(luò)端到端時(shí)延。測試結(jié)果表明,網(wǎng)絡(luò)的實(shí)時(shí)性得到了提高。