劉 凱 呂海燕 張立民
(海軍航空大學(xué)航空基礎(chǔ)學(xué)院 煙臺 264001)
隨著嵌入式系統(tǒng)和網(wǎng)絡(luò)接入方法的日益發(fā)展,越來越多的嵌入式系統(tǒng)連接至網(wǎng)絡(luò),作為網(wǎng)絡(luò)終端參與數(shù)據(jù)交互、信息處理[1~2]?;?TCP/IP 的以太網(wǎng)是一種標(biāo)準(zhǔn)開放式的網(wǎng)絡(luò),由于其通用性強,組網(wǎng)容易,能夠?qū)崿F(xiàn)遠(yuǎn)距離數(shù)據(jù)傳輸,容易實現(xiàn)資源共享,受到了廣泛的應(yīng)用和支持[3~4]。因此,基于以太網(wǎng)的嵌入式系統(tǒng)逐漸成為了當(dāng)前片上系統(tǒng)(Sys?tem on Chip,SoC)[5]的發(fā)展熱點。但是,由于嵌入式系統(tǒng)中硬件資源有限,如果移植完整的TCP/IP協(xié)議棧,會大大增加系統(tǒng)運行載荷,導(dǎo)致系統(tǒng)運行緩慢且數(shù)據(jù)通信不暢。因此,需要依據(jù)嵌入式系統(tǒng)特點,有針對性地選擇TCP/IP協(xié)議棧精簡方案,從而實現(xiàn)網(wǎng)絡(luò)穩(wěn)定通信與系統(tǒng)高效運行的平衡。
LM3S8962[6~7]微控制器是德州儀器(TI)公司提供的一款具有32位高性能運算能力的基于ARM?CortexTM-M3的控制器,其優(yōu)勢還在于能夠方便地運用多種ARM的開發(fā)工具和片上系統(tǒng)(SoC)的底層IP應(yīng)用方案。另外,該微控制器使用了兼容ARM Thumb?的Thumb2指令集來減少存儲容量的需求,并以此達(dá)到降低成本的目的。最后,LM3S8962微控制器與Stellaris?系列的所有成員是代碼兼容的,這為用戶提供了靈活性,能夠適應(yīng)各種精確的需求。
LM3S8962微控制器的主要特性之一是具有10/100以太網(wǎng)控制器,它遵循IEEE 802.3-2002規(guī)范,遵循IEEE 1588-2002精確時間協(xié)議(PTP)。在100Mbps和10Mbps速率運作下支持全雙工和半雙工的操作方式,集成10/100Mbps收發(fā)器(PHY),自動的MDI/MDI-X交叉校驗,可編程MAC地址[8~9]。
針對LM3S8962已經(jīng)具備10/100以太網(wǎng)控制器特點,需要在其硬件以太網(wǎng)控制器的基礎(chǔ)上構(gòu)建協(xié)議包系統(tǒng),從而完成TCP或UDP數(shù)據(jù)包的處理,實現(xiàn)TCP/IP協(xié)議棧的通信。
1)以太網(wǎng)協(xié)議
以太網(wǎng)數(shù)據(jù)由以太網(wǎng)幀來傳送[10]。以太網(wǎng)的沖突退避算法是由硬件自動執(zhí)行的,在軟件設(shè)計中可不用考慮。類型表示上層協(xié)議類型,本協(xié)議棧只處理這兩種類型的以太網(wǎng)幀:IP包、ARP包。
2)地址解析協(xié)議(ARP)和反地址解析協(xié)議(RARP)
為了簡化TCP/IP協(xié)議棧內(nèi)容,本協(xié)議棧僅僅涉及了使用固定IP地址的方式實現(xiàn)以太網(wǎng)通信。因此,在本協(xié)議棧中無需實現(xiàn)RARP,僅僅需要對ARP包進行處理。ARP請求格式如圖1所示。
圖1 ARP請求應(yīng)答格式
以太網(wǎng)報頭中的前兩個字段是以太網(wǎng)的源地址和目的地址。目的地址為全1的特殊地址是廣播地址。兩個字節(jié)長的以太網(wǎng)幀類型表示后面數(shù)據(jù)的類型。如果以太網(wǎng)報文內(nèi)容為ARP請求或應(yīng)答,該字段的值為0×0806。對于一個ARP請求,除目的端硬件地址以外的所有其他字段都有填充值。當(dāng)系統(tǒng)收到一份目的端為本機的ARP請求報文后,它就把硬件地址填進去,然后用兩個目的端地址分別替換兩個發(fā)送端地址,并把操作字段置為2,最后把它發(fā)送回去。
3)控制報文協(xié)議(ICMP)
針對嵌入式應(yīng)用系統(tǒng)的特點,雖然ICMP可以提供很好的網(wǎng)絡(luò)狀態(tài)報告,但對于本系統(tǒng)中嵌入式軟件而言,只需要實現(xiàn)一個“回顯應(yīng)答”(即Ping應(yīng)答)的功能即可。
Ping是Internet上最常用的調(diào)試工具,它的目的是為了測試另一臺主機是否可達(dá)[11~12]。該程序發(fā)送一份ICMP回顯請求報文給目的IP設(shè)備,并等待返回ICMP回顯應(yīng)答。用該命令,可以方便地測試儀表與網(wǎng)絡(luò)是否連通。為實現(xiàn)響應(yīng)ping命令,本協(xié)議支持的ICMP類型如下:
type=8:ICMP Echor(回送)回答報文;
type=0:ICMP Echor請求。
4)網(wǎng)際協(xié)議(IP)
IP數(shù)據(jù)包的格式如圖2所示??紤]到本系統(tǒng)網(wǎng)絡(luò)數(shù)據(jù)較小,故在IP協(xié)議實現(xiàn)時沒有支持有選項字段的IP包和分片操作。
圖2 IP數(shù)據(jù)包格式
8位協(xié)議字段表示上層協(xié)議類型,在本項目中只要處理兩種類型的IP包:ICMP包、UDP包。
5)用戶數(shù)據(jù)報協(xié)議(UDP)
UDP分段的頭部格式如圖3所示。
圖3 UDP分段的頭部格式
在本協(xié)議棧中,設(shè)計了完整的UDP協(xié)議,并實現(xiàn)了與計算機的Socket通信。
從上面可以得出,經(jīng)過了剪裁之后在本系統(tǒng)中應(yīng)用的TCP/IP協(xié)議棧層次如圖4所示。
圖4 TCP/IP協(xié)議棧層次設(shè)計
該層主要為LM3S8962以太網(wǎng)底層硬件驅(qū)動,包含以太網(wǎng)中斷響應(yīng)函數(shù)EthernetIntHandler()、硬件初始化函數(shù)InitNic()、處理接收數(shù)據(jù)函數(shù)Rec?Packet()、以太網(wǎng)底層發(fā)送數(shù)據(jù)函數(shù)Send_Packet()。
LM3S8962自帶的函數(shù)庫包含了基本的以太網(wǎng)通信控制函數(shù),故該協(xié)議是在其函數(shù)庫基礎(chǔ)上實現(xiàn)的。
1)InitNic()
要實現(xiàn)網(wǎng)絡(luò)的驅(qū)動,必須對LM3S8962的各個寄存器進行初始化和配置。在對LM3S8962進行初始化之前需要進行硬件復(fù)位和軟件復(fù)位;然后進行寄存器設(shè)置。LM3S8962網(wǎng)絡(luò)初始化的順序如圖5所示。
圖5 LM3S8962網(wǎng)絡(luò)初始化流程
2)EthernetIntHandler()函數(shù)
該函數(shù)參數(shù)為void,主要是作為接收中斷響應(yīng)函數(shù)調(diào)用RecPacket()函數(shù)。由于該協(xié)議是在μC/OS-Ⅱ基礎(chǔ)上設(shè)計的,在該函數(shù)最后進行了任務(wù)的調(diào)度。
3)RecPacket()函數(shù)
該函數(shù)的參數(shù)為void,該函數(shù)需調(diào)用LM3S8962的庫函數(shù)EthernetPacketGetNonBlocking Get(),其具體功能是從以太網(wǎng)控制器獲取數(shù)據(jù)包,返回接收數(shù)據(jù)包的長度。
4)Send_Packet()函數(shù)
在協(xié)議棧中設(shè)計了鏈表_pkst,其結(jié)構(gòu)如圖6所示。協(xié)議棧利用它作為數(shù)據(jù)讀取和發(fā)送的數(shù)據(jù)結(jié)構(gòu)。
圖6 _pkst結(jié)構(gòu)
Send_Packet()函數(shù)的輸入?yún)?shù)為數(shù)據(jù)鏈初始指針,返回值為void。
數(shù)據(jù)鏈路層中包含地址解析函數(shù)PRO?CESS_ARP_REC(),網(wǎng)絡(luò)的收發(fā)操作函數(shù)Send_IP_LLC()和 Rec_Ethernet_Packet(),還有一些輔助函數(shù),如設(shè)置網(wǎng)絡(luò)地址函數(shù)SetNetPort()等。
1)PROCESS_ARP_REC()函數(shù)
2)Send_IP_LLC()函數(shù)
該函數(shù)能夠為IP數(shù)據(jù)包的目標(biāo)IP查找MAC地址并將其發(fā)送出去。輸入?yún)?shù)為發(fā)送結(jié)構(gòu)指針和目標(biāo)IP地址指針。
3)Rec_Ethernet_Packet()函數(shù)
該函數(shù)被RecPacket()函數(shù)調(diào)用,其功能是處理接收到的數(shù)據(jù)包,并將其數(shù)據(jù)指針傳遞到IP層。其輸入?yún)?shù)為接收數(shù)據(jù)指針;輸出參數(shù)為0表示發(fā)送失敗,1表示發(fā)送成功。
網(wǎng)絡(luò)層包括IP包的接收和發(fā)送控制,ICMP請求報文的接收和 ICMP應(yīng)答報文的發(fā)送控制[13~14]。考慮到實際數(shù)據(jù)量較少,在IP數(shù)據(jù)包的處理上沒有實現(xiàn)分片處理。
在IP協(xié)議中,創(chuàng)建了消息隊列RecUdpQFlag和信號量SendFlag。消息隊列的用處:如果有UDP數(shù)據(jù)包傳遞到IP協(xié)議層,則釋放該消息隊列,同時該消息隊列保存了UDP數(shù)據(jù)包的存儲地址;信號量則在Send_Ip_Frame()函數(shù)中使用。具體使用過程:首先判斷該信號量是否當(dāng)前可用,以判斷該函數(shù)能否獲得網(wǎng)絡(luò)發(fā)送的權(quán)利,如果該時間可以進行網(wǎng)絡(luò)數(shù)據(jù)發(fā)送,則在IP數(shù)據(jù)包發(fā)送完畢以后釋放信號量。
1)IP_PROCESS()函數(shù)
該函數(shù)的輸入?yún)?shù)為接收數(shù)據(jù)結(jié)構(gòu)的指針;返回值表明處理結(jié)果,如果為1,則數(shù)據(jù)處理正確,如果為0表明處理失敗。
2)Send_Ip_Frame()函數(shù)
該函數(shù)實現(xiàn)的是IP數(shù)據(jù)包的發(fā)送。輸入?yún)?shù)由發(fā)送地址指針和目標(biāo)IP地址組成,輸出參數(shù)表明發(fā)送結(jié)果是否成功。
在ICMP協(xié)議中,系統(tǒng)實現(xiàn)了Ping命令的響應(yīng),即客戶端能夠判斷接收服務(wù)端的ICMP Echo報文,同時向服務(wù)端回送一個ICMP Echo Reply報文完成Ping。
3)ICMP_PROCESS()函數(shù)
該函數(shù)的功能是對ICMP數(shù)據(jù)報進行處理。輸入?yún)?shù)為ICMP數(shù)據(jù)報指針,輸出參數(shù)表示處理結(jié)果。
鑒于LM3S8962內(nèi)部以太網(wǎng)控制器穩(wěn)定性高、通信鏈路延時低的優(yōu)勢,同時為了降低通信負(fù)載,在本TCP/IP協(xié)議棧中運輸層僅僅使用UDP協(xié)議。為滿足通信要求,在該層設(shè)計了兩個結(jié)構(gòu)udp_sub_socket和 udp_socket,其結(jié)構(gòu)如圖 7、8 所示,并且定義了全局Socket變量。
udp_socket UdpStatus;
圖7 udp_sub_socket結(jié)構(gòu)
圖8 udp_socket結(jié)構(gòu)
1)UDP_Process()函數(shù)
該函數(shù)的輸入?yún)?shù)為接收UDP數(shù)據(jù)包指針,輸出參數(shù)表明處理結(jié)果。
2)UDP_Send()函數(shù)
該函數(shù)實現(xiàn)了UDP數(shù)據(jù)包的發(fā)送,輸入?yún)?shù)由數(shù)據(jù)指針、目的IP和網(wǎng)絡(luò)端口組成。
對于網(wǎng)絡(luò)數(shù)據(jù)的接收,該協(xié)議棧在系統(tǒng)中的具體使用步驟如下:
1)等待消息隊列RecUdpQFlag。如果消息隊列被釋放了,根據(jù)函數(shù)IP_PROCESS()處理流程,表明存在UDP數(shù)據(jù)包。調(diào)用UDP_Process(),相應(yīng)的代碼如下所示:
UdpTemp = OSQPend (RecUdpQFlag, 0,&eer);
if(eer==OS_NO_ERR)
{
Udp_Process((Rec_Ptr*)UdpTemp);
}
2)等待UdpStatus中的信號量UdpSemRec,通過UDP_Process()保存后的數(shù)據(jù)指針得到UDP數(shù)據(jù)包中的數(shù)據(jù)。
3)如果要求發(fā)送網(wǎng)絡(luò)數(shù)據(jù),調(diào)用UDP_Send()函數(shù)即可。
為了驗證嵌入式TCP/IP協(xié)議棧工作性能,采用兩種方式進行測試,1是Ping測試,2是將其應(yīng)用于數(shù)據(jù)采集節(jié)點測試通信效果。
Pin命令主要是對網(wǎng)絡(luò)層進行測試[15~16]。在測試中,客戶端設(shè)定的IP地址是192.168.0.18,當(dāng)服務(wù)器發(fā)出Ping命令時,客戶端給出回應(yīng)。從圖9中可以看出,傳遞的數(shù)據(jù)并沒有丟失,并且傳輸?shù)臅r延較小,證明通信性能較好??梢宰C明IP層、物理層、數(shù)據(jù)鏈路層是連通的,能夠保證客戶端與服務(wù)器進行正常通信。
圖9 ICMP的測試結(jié)果
在本系統(tǒng)中,數(shù)據(jù)采集節(jié)點通過以太網(wǎng)完成與上位機的信息交互。上位機進行UDP測試工具如圖10所示。
圖10 上位機測試UDP包結(jié)果
經(jīng)過實驗驗證,數(shù)據(jù)采集節(jié)點能夠及時將所采集的數(shù)據(jù)通過網(wǎng)絡(luò)以UDP包的形式傳遞給上位機,上位機根據(jù)節(jié)點傳遞的數(shù)據(jù)及時作出反映。
針對LM3S8962芯片特點,采用了模塊化設(shè)計方法設(shè)計了TCP/IP協(xié)議棧。根據(jù)實際系統(tǒng)通信需要,對各個棧功能進行精簡,去掉了反地址解析協(xié)議,簡化了控制報文協(xié)議和TCP包處理。既保證了以太網(wǎng)通信需求,又節(jié)約了嵌入式系統(tǒng)資源。通過相關(guān)實驗驗證,該協(xié)議棧的設(shè)計達(dá)到了嵌入式系統(tǒng)預(yù)期要求。本文提出的這種基于嵌入式系統(tǒng)的精簡TCP/IP協(xié)議棧,對LM3S8962等同類型芯片的以太網(wǎng)通信等工程實踐提供了參考借鑒,并且對該領(lǐng)域中的相關(guān)技術(shù)研究也具有一定的指導(dǎo)意義。