嵌入式平臺中配置雙協議棧的問題
最近有不少網友問到如何進行那個配置雙協議棧的問題。我們可以來從下面的文章中做一個具體的了解。我們都知道,網絡的發展速度驚人,格式的功能以及應用令人眼花繚亂。在這些功能以及應用的背后,是眾多網絡協議的支持。那么這里我們來重點講解一下Windows平臺上使用Visual C++ 6.0開發環境進行嵌入式TCP/IP協議棧的開發和仿真調試手段。詳細講解了如何使用Winpcap接收和發送IP數據報文以及在Windows上配置雙協議棧的一些問題。
1 引言
隨著Internet的廣泛的應用,在嵌入式設備中支持TCP/IP協議以連接到Internet網絡并與外界通信的需求更加強烈,這就需要在嵌入式系統中支持TCP/IP協議棧.雖然目前的商用嵌入式操作系統,如VxWorks、QNX、pSOS、VRTX等,均提供基于TCP/IP的網絡組件,但為了滿足各個方面的應用需要,其實現過于復雜,需要占用大量的系統資源.而嵌入式系統的本身資源有限,并且其應用和功能比較單一,具有較強的針對性,因此也并不需要一個完整的TCP/IP網絡協議組件,只需要實現與需求相關的部分協議,不使用的協議則不需要支持.在另一方面,對于某些特定的嵌入式系統,甚至需要優化TCP/IP協議棧或者在TCP/IP協議棧中編寫自己需要的網絡協議.那些不能提供開放源碼的商用嵌入式系統的TCP/IP協議棧都很難滿足用戶的配置需求,需要用戶自行開發和定制適合自己系統需求的嵌入式TCP/IP協議棧.
2 嵌入式協議棧的開發和調試問題
一般的嵌入式系統的開發和調試都是使用其相應的開發調試工具連接計算機和目標機進行交叉開發和調試.例如被廣泛使用的VxWorks嵌入式實時操作系統的開發工具Tornado,它就是一套強有力的交叉開發工具,用戶可以在計算機上使用圖形界面對目標機上的應用程序進行調試.
但即便是使用像Tornado這樣優秀的嵌入式開發環境,在交叉調試協議棧此類比較大型的程序時,還是顯得力不從心,其開發調試是件費時費力的工作,大大增加了系統的開發難度和開發調試的周期.在目前的嵌入式系統的調試工具還不盡如人意的現狀下,對嵌入式TCP/IP協議棧的開發如果能前期在Windows平臺上進行開發和仿真調試,將是一件很有意義的工作.
嵌入式TCP/IP協議棧雖然是基于嵌入式操作系統,但除了接收和發送數據包以外,幾乎并不直接與底層硬件打交道.因此在Windows平臺上仿真調試和運行TCP/IP協議棧是完全可行的,可以完成絕大部分功能的開發與調試,后期再移植到嵌入式系統上,只需進一步稍加調試和測試便能實現整個嵌入式軟件系統的功能和性能.這樣的開發流程能夠極大的提高開發的效率,減少開發的周期.
3 在Windows平臺上運行嵌入式協議棧
在講解配置雙協議棧之前,我們來了解一下在Windows平臺上運行嵌入式協議棧的內容。在Windows平臺上仿真調試和運行TCP/IP協議棧,首先需要在Visual C++ 6.0開發環境中創建一個Win32應用程序的項目工程用于模擬嵌入式系統,嵌入式TCP/IP協議棧就是在這個Win32的應用程序中運行.這樣,我們使用Windows平臺下的一個進程模擬了一個多任務的嵌入式操作系統.
一個多任務嵌入式操作系統需要具有任務管理、內存管理以及任務間通信機制如信號量、消息隊列等功能.因此,如想在Windows平臺上運行嵌入式TCP/IP協議棧,也必須提供上述多任務嵌入式操作系統的基本功能.
在多任務嵌入式操作系統中,任務是系統進行調度的最基本的單元,參與資源競爭和CPU資源在任務間的分配,系統通過循環的方式為每個任務安排一定的 CPU時間片,而在宏觀上看仿佛是若干任務并發處理,形成多任務操作系統.而在Winodows這樣的通用操作系統平臺上,則是由線程作為參與CPU時間 片資源競爭最小實體,因此,我們使用線程模擬嵌入式操作系統中的一個任務.任務的創建、刪除和控制等操作通過調用Windows平臺中提供的線程的創建、 刪除和控制的Win32 API函數來實現.
在多任務操作系統中,任務與任務之間需要協調動作,相互配合,這就需要提供任務間相互通信的機制以進行同步和互斥.嵌入式系統中一般提供信號量、事件和消 息機制這三種主要的任務間通信手段.同樣,在Windows平臺上的Win32 API也提供相應的用于進程/線程間通信的信號量、事件和消息機制的函數.#p#
由于Windows是一個強大的通用分時操作系統,能夠提供完善的操 作系統接口.因此,多任務嵌入式操作系統完全可以在Windows平臺上模擬.不過,這種模擬也只是近似的,畢竟對于多數嵌入式系統都是實時系統,而 Windows卻是分時系統,無法保證其系統的實時性.
想要對配置雙協議棧有所掌握,肯定是要了解TCP/IP協議棧的開發的。至于嵌入式TCP/IP協議棧的開發,考慮TCP/IP協議族的復雜性以及其協議棧龐大的代碼量,試圖完全從頭到尾徹底的重新編寫一套TCP/IP協議棧的代碼是極為艱難的,需要大量的人力、物力和時間的投入.其實目前TCP/IP技術已經十分成熟,幾乎所有的通用操作系統都提供TCP/IP協議棧用于網絡支持,包括那些公開源碼的操作系統.因此考慮移植源碼公開的TCP/IP協議棧,同時根據需求對其進行適量的精簡和改進.
目前,比較常見的源碼公開的TCP/IP協議棧軟件有:
1). BSD Net網絡協議棧軟件.這是由加利福利亞大學伯克利分校計算機系統研究小組發布的,世界上***個被廣泛應用TCP/IP軟件版本就是伯克利于1983年發布的4.2BSD,有許多系統的TCP/IP協議棧實現都是以它的源代碼為基礎而開發的.目前其***版本是1994年發布的4.4BSD-Lite2,又稱為Net/3.
2). Linux的TCP/IP協議棧軟件.作為一個遵循GUN公共許可協議,源碼全部公開的自由操作系統軟件,其TCP/IP協議棧部分源碼是以BSD的網絡協議棧為模型,支持BSD的Socket接口,但其內部代碼是重新寫的,與4.4BSD-Lite2并不雷同.
3). lwIP是一個比較小型的源碼開放的TCP/IP協議棧軟件,是由瑞典計算機科學研究院的Adam Dunkels教授編寫.它只需要10K的RAM空間和40K的ROM存儲空間,因此非常適合嵌入式系統里使用.
4). uIP則是一個超小型的TCP/IP協議棧,僅能提供ARP、SLIP、TCP、ICMP和IP這幾種基本的協議.其所需資源非常的少,所以非常適合在8位和16位單片機上運行.
對于TCP/IP協議棧的選擇主要根據用戶本身的需求和所能提供的軟硬件資源來確定.比如像BSD和Linux的TCP/IP協議棧屬于通用的協議棧,支持協議比較齊全,但也需要耗用大量的ROM和RAM存儲空間,對CPU的要求也比較高;而lwIP和uIP這類的協議棧是專門為嵌入式操作系統開發出來的,軟件結構比較緊湊,對CPU和存儲器需求不高,但其所支持的協議種類及功能也非常有限.
4 WinPcap工具包介紹
在Windows平臺上仿真調試和運行TCP/IP協議棧,還需要考慮協議棧如何接收和發送數據報文的問題,這就需要使用WinPcap來實現.
WinPcap(Windows Packet Capture)是Windows平臺下一個公共的、免費的網絡訪問系統,能為Win32應用程序提供網絡訪問的能力.它提供以下四項主要功能:
1) 捕獲原始數據報文,包括共享網絡上各主機發送/接收和相互交換的數據包;
2) 在數據報文發送往應用程序之前,按照自定義的規則將某些特定的數據包過濾掉;
3) 在網絡上發送原始的數據報文;
4) 收集網絡通信過程中的統計信息;
WinPcap的主要功能在于獨立于主機協議而發送和接收原始數據報文,能夠監聽共享網絡上傳送的數據包.因此,通過調用它提供的各種函數,可以實現在 Windows平臺下將各類數據報文通過網絡適配器發送到共享網絡上去,同樣也可以接收網絡適配器上收到的各種原始的數據包.
要使用WinPcap,首先需要在Windows平臺上安裝WinPcap驅動軟件,然后便可以在Win32的應用程序中通過包含packet32.h這 個頭文件來使用由WinPcap的動態鏈接庫packet32.dll或者靜態鏈接庫packet32.lib所提供的庫函數來對網絡適配器進行打開、設 置、關閉操作和通過網絡適配器進行接收或者發送數據報文.#p#
下面簡要介紹一下其主要函數的功能:
1) BOOLEAN PacketGetAdapterNames(LPSTR pStr,PULONG BufferSize) 返回可以得到的網絡適配器列表及描述.
2) LPADAPTER PacketOpetAdapter(LPTSTR AdapterName) 打開一個網絡適配器.
3) BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) 設置捕獲數據報的內核級緩沖區大小.
4) BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) 為接收到的數據報設置硬件過濾規則.一般而言,需要將其設置為 NDIS_PACKET_TYPE_PROMISCUOUS(混雜模式),即接收所有流過的數據報文.
5) LPPACKET PacketAllocatePacket(void) 如果運行成功,返回一個_PACKET結構的指針,否則返回NULL.成功返回的結果將會傳送到PacketReceivePacket()函數,接收來自驅動的網絡數據報.
6) VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length) 初始化一個_PACKET結構.
7) BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket, BOOLEAN Sync) 發送一個或多個數據報的副本.
8) BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) 從NPF驅動程序讀取網絡數據報及統計信息.
9) VOID PacketFreePacket(LPPACKET lpPacket) 釋放參數提供的_PACKET結構.
10) VOID PacketCloseAdapter(LPADAPTER lpAdapter) 關閉參數中提供的網絡適配器,釋放相關的ADAPTER結構.
5 在Windows平臺下協議棧發送和接收函數的設計
了解配置雙協議棧的問題之前,我們還要清楚:在Windows平臺下通過WinPcap可以直接對網絡適配器進行操作,從而實現發送和接收數據報文的目的.在使用WinpCap前首先需要進行初始化 操作,其步驟如下:調用PacketGetAdapterNames()獲取當前網絡適配器的名稱,再調用PacketOpenAdapter()函數打 開一個網絡適配器,然后還需要調用PacketSetHwFilter()函數設置網絡適配器的過濾規則和調用PacketSetBuff()設置捕獲數 據報的內核級緩沖區大小.
當協議棧需要發送數據報文時,首先需要調用PacketAllocatePacket()函數為發送數據報文創建一個網絡數據報結構,然后調用 PacketInitPacket()函數對該結構進行初始化,將存儲待發送數據報文的緩沖區指針和長度填入網絡數據報結構,再接下來便是調用 PacketSendPacket()函數將數據報文從指定的網絡適配器中發送出去,之后需要調用PacketFreePacket()函數釋放掉剛才申 請的網絡數據報文結構的內存空間.這樣,一個TCP/IP協議棧就能夠完成將一個數據報文通過WinPcap操作網絡適配器發送到網絡上的工作.
#p#
使用WinPcap接收網絡適配器上收集到的網絡上的數據報文,首先需要創建一個高優先級別的任務或者線程,一般在TCP/IP協 議棧的網絡接口層初始化時即需要創建一個這樣的任務或者線程,然后在該任務或者線程函數里調用PacketAllocatePacket()為接收數據報 文創建網絡數據報結構,再調用PacketInitPacket()函數為接收的數據報文分配內存緩沖區,這個緩沖區需要盡量大一點兒,否則一旦網絡上數 據報文比較多,而協議棧上層來不及處理,則會造成數據報文的丟失.接下來便是循環的調用PacketReceivePacket()函數從指定的網絡適配 器讀取數據報文,并將數據報文拷貝到協議棧的內存空間,再通過操作系統提供的任務或線程間通信的機制將該數據報文發送到TCP/IP協議棧的接收任務或者線程進行報文的分析和處理.這個數據接收的任務和線程將永遠不會返回,始終循環調用PacketReceivePacket()函數讀取網絡適配器上接收到的網絡上傳輸過來的數據報文并將其交付給TCP/IP協議棧進行處理.
6 在Windows平臺上配置雙協議棧的問題
由于Windows平臺本身自帶有TCP/IP協議棧,而我們又需要在Windows平臺上運行一個嵌入式TCP/IP協議棧,實際上是在Windows這一個操作系統上配置了雙TCP/IP協議棧.
要使這兩個TCP/IP協議棧相互之間互不影響并能各自良好的運行,首先需要為兩個協議棧各自分配不同的IP地址;其次在嵌入式TCP/IP協議棧中的數據鏈路層的Mac地址,一定不能使用Windows平臺的TCP/IP協議棧使用的網絡適配器的地址,除非計算機裝有兩塊網絡適配器,Windows平臺的TCP/IP協議棧使用一個網絡適配器進行數據的收發,而嵌入式TCP/IP協議棧使用另一個網網絡適配器收發數據報文.其實在嵌入式TCP/IP協 議棧中,其鏈路層的Mac地址可以通過修改程序代碼設置任意的虛擬Mac地址,但這必須首先調用WinPcap的PacketSetHwFilter() 函數設置網絡適配器的接收模式為NDIS_PACKET_TYPE_PROMISCUOUS(混雜模式)用于指定網羅適配器接收所有流過的數據報文,否 則,網絡適配器會根據本身的Mac地址對網絡上接收到的數據報文進行Mac過濾,丟棄掉不屬于該網絡適配器接收的數據報文.
7 小結
作者在工作中按照上述方法,成功的在Windows平臺上運行并調試了Linux的TCP/IP協議棧,并最終將其移植到VxWorks操作系統中運行.在調試過程中,作者明顯感覺Windows的VC6開發平臺下調試確實比直接使用Tornado調試要方便和快捷許多.由于前期在Windows平臺上調試時解決了大部分移植和修改TCP/IP協議棧的問題,后期在Tornado下調試時基本上沒有花費太多的時間,大大提高了工作的效率,減小了開發的周期.