如何將lwIP TCP/IP堆疊整合至嵌入式應用

作者:ADI應用工程師 Anju Puthenpurayil


摘要

TCP/IP堆疊的應用已廣泛普及至區域與廣域網路的乙太網路通訊介面中。輕量TCP/IP (lwIP)是TCP/IP協定的精簡化實作,主要的目的是減少記憶體的使用量。本文將引導讀者將 lwIP TCP/IP堆疊整合到嵌入式應用,進而加快研發流程以及節省時間與工作量。

介紹

輕量化TCP/IP(lwIP)堆疊是TCP/IP協定的精簡實作,專門設計用來縮減RAM記憶體的使用量,這使其非常適合用在嵌入式系統。它提供三種獨特的應用程式介面(API):

  • 未封裝的低階API
  • 負責網路通訊的高階 API
  • BSD 風格的socket通訊端 API

本文專注探討使用未封裝API介面的範例。運用未封裝API建置callback回呼函數的應用程式會由核心事件觸發。

儘管未封裝API較socket通訊端API更為複雜,但由於其處理負荷(overhead)較低,因此能提供高出許多的吞吐量。

接著我們將探討幾個建構在lwIP TCP/IP堆疊之上的範例,其中採用了Analog Devices的MAX32570微控制器。開始的部分是一個ping展示,主要從PC向裝置發送ping探測訊號。後續的部分介紹TCP Echo伺服器範例,這個初步的伺服器展示對於測試TCP連結相當實用。

ADI的MaximSDK 軟體開發套件收錄許多必要的軟體與工具,讓用戶針對ADI的MSX32xxx微控制器開發韌體。套件中有一個lwIP堆疊函式庫檔案“MaximSDK\Libraries\lwIP”。圖1顯示MaximSDK資料夾結構中的lwIP函式庫檔案。

Figure 1. ADI’s MaximSDK lwIP library files.

圖1. ADI的MaximSDK lwIP 函式庫檔案

lwIP資料夾包含多個子目錄:

  • API 資料夾 (網路通訊與 socket 通訊端API)
  • 核心資料夾 (lwIP 核心檔案,包含 “tcp.c”、“ip.c” 等)
  • Netif 資料夾 (網路介面檔案)
  • Include 資料夾 (所有lwIP include 引入檔案)
  • Maxim資料夾 (為ADI微控制器設計的客製化mac 驅動程式)

lwIP架構依循TCP/IP模型結構。TCP/IP通訊協定是多個分層組成的協定。TCP/IP通常被看成是一個四層結構的系統,如圖2所示。

Figure 2. TCP/IP protocol layers.

圖2. TCP/IP 通訊協定分層

lwIP 專案檔中一定有一個名為“lwipopts.h”的組態檔案,以及一個名為“opt.h”的組態檔案。“opt.h”檔案中記錄所有預設的堆疊組態以及其模組組態,而“lwipopts.h”則讓使用者能自行設定堆疊與其模組的所有組態。須注意這個檔案並未包含所有可能的lwIP選項。因此,如果在“lwipopts.h”組態檔案中沒有定義某項組態,系統就會採用“opt.h”中定義的預設組態。

類似的情況,lwIP函式庫有一個和程式相關的表頭檔案名為 “lwipcfg.h”。包括控制器的IP位址、閘道器位址、網路遮罩位址、以及MAC位址都應定義在“lwipcfg.h”檔案,如圖3所示。

Figure 3. lwipcfg header file.

圖3. lwipcfg 表頭檔案

要在lwIP以及底層的硬體驅動程式之間建立連結,需要用到一個特定平台專屬的配接層。舉例來說,在為微控制器建置lwIP堆疊時,需要量身設計的驅動程式來橋接lwIP堆疊與微控制器的乙太網路MAC驅動程式。這個客製化驅動程式應涵蓋以下功能:

  • 初始化功能: 此項功能負責初始化微控制器專屬的MAC驅動程式
  • 傳送功能: 將從TCP堆疊收到的資料傳送給乙太網路MAC驅動程式,以便進行後續的傳輸
  • 接收功能: 將從乙太網路MAC驅動程式收到的封包轉送到TCP堆疊

對於ADI微控制器,預存的客製化驅動程式已放在“MaximSDK\Libraries\lwIP\Maxim\mxc_eth.c”路徑下的MaximSDK。這個驅動程式可作為包裝器,能包裝微控制器本身的Ethernet MAC (EMAC)週邊函式庫,該函式庫位於“C:\MaximSDK\ Libraries\PeriphDrivers\Source\EMAC”路徑下的週邊驅動程式中

Ping 範例

“ping”指令是一個簡單的工具,用來進行網路除錯。其能執行網際網路控制訊息協定(ICMP)的echo 回應請求,向指定的IP位址傳送一個訊號然後等候回覆。當目的地收到這個請求,就會回覆一個echo封包。本章節解釋如何從Windows PC向微控制器執行基本的ping測試以檢查其連結狀態,同時還會闡述如何使用微控制器的ping模組來和PC進行通訊。

以下詳列Windows環境中ping工具的工作流程:

  • 向微控制器傳送4個資料封包,然後等待回應
  • 微控制器將這些資料封包傳回PC作為回應,亦即迴響答覆請求。

執行ping測試:

  • 使用乙太網路線將微控制器EVKIT套件連到PC
  • 開啟命令列提示視窗,然後輸入“ping <微控制器的IP位址>”然後按下enter鍵

命令列提示視窗中顯示回應,如圖4所示,意謂著在PC與微控制器之間已建立正常運行的連結

Figure 4. Ping output in command prompt.

圖4.命令列提示視窗顯示的 Ping 輸出內容

從微控制器測試Ping

“lwIP_Ping”檔案是ADI旗下MAX32570微控制器的ping範例,收錄於MaximSDK開發套件。該檔案存放在“C:\MaximSDK\Examples\ MAX32570\lwIP_Ping”,目錄中並提供以下指南:

  • 微控制器的IP位址是使用“lwipcfg.h”檔案來設定。微控制器與PC的IP位址應在同一個網段。在微控制器的“lwipcfg.h”檔案中,PC的IP位址應設定成閘道器位址。
  • 使用乙太網路線連接PC與MAX32570 EVKIT套件
  • 執行ping範例碼
  • 在eclipse程式中開啟序列終端機 (Window-> Show view -> Terminal)。如圖5所示,如果ping成功,終端機畫面應顯示ping的結果

Figure 5. Ping output in serial terminal.

圖5. 序列終端機顯示的Ping 輸出內容

命令列提示視窗僅顯示ping統計資料。要檢視實際傳送的資料,需要用到一個名為Wireshark的程式。Wireshark能擷取網路連線所傳送的資料。開啟Wireshark後,再選擇乙太網路選項。另外還能顯示像是來源與目的地MAC位址、來源與目的地IP位址、通訊協定、以及額外傳送資料等細部資料。Wireshark顯示的資訊如圖6所示。

Figure 6. Ping data packet in Wireshark.

圖6. Wireshark程式中顯示的ping資料封包

正如範例所示,傳送的資料為 0x00, 0x01… 一直到0x1F。但如果使用者想要修改傳送資料的內容那該怎麼做?

修改微控制器Ping指令所發送的資料

透過ping指令發出的資料是在“ping. c”檔案中設定的。“Ping.c”檔案是 ping的傳送程式模組。要傳送的資料大小是以“PING_DATA_SIZE”參數設定在“ping.c”檔案中。如圖7所示,要傳送的資料大小為32 位元組。

Figure 7. Ping data packet size.

圖7. Ping 資料封包尺寸

準備要傳送的資料的定義亦寫在“ping.c” 檔案。額外的資料緩衝區會寫入相同的資料,如圖8所示的“0x00, 0x01, 0x02…to 0x1F.”

Figure 8. Ping data packet.

圖8. Ping 資料封包

依據應用程式的需求,如果使用者想要修改資料,可以在“ping .c”檔案中修改資料緩衝區。舉例來說,將所有32位元組的資料變更成“0x01, 0x01…0x01” 如圖9所示

Figure 9. Modified ping data packet.

圖9. 修改後的 ping資料封包

在Wireshark中顯示修改後的 “ping .c” 檔案。這裡使用了新的參數來更新資料。

Figure 10. Modified ping data packet in Wireshark.

圖10. 在Wireshark中顯示修改後的ping資料封包

TCP Echo 伺服器

ping範例中採用ICMP來判斷目標系統的反應狀況。其會使用預設資料透過網路向目標接收端傳送一個echo請求。當目標位址收到這個請求時,它會回覆一個echo應答封包。

如果使用者希望從某個裝置向另一個裝置傳送客製化資料,可使用TCP協定進行資料傳輸。在標準TCP函式中的Echo服務主要用來檢查可及性以及判斷各種路由問題。在這項服務中,伺服器與客戶端都是使用TCP來建立的。當伺服器從客戶端收到訊息,它會回覆相同的訊息。

在MaximSDK,“lwIP TCP”原始碼檔案展示了如何使用lwIP函式庫中的 TCP函數。在這個案例中,微控制器扮演TCP伺服器,並會等候客戶端發送連接請求。接著伺服器會返傳從客戶端送來的資料。在TCP Echo伺服器範例中,應使用“tcpecho_raw.c”原始碼檔案。依循以下步驟設定TCP Echo伺服器。

要設定TCP Echo伺服器:

  • 建立一個 socket
  • 將socket綁定到宣告的埠號
  • 完成綁定後,其會開始監聽傳來的連接請求
  • 收到連接請求後,其會接受客戶端設備發送來的連接請求
  • 伺服器接收到客戶端傳來的資料
  • 最後,其傳回相同的資料

圖11 顯示的指令碼顯示了韌體的結構,該結構是主函數的一部分。config_emac會初始化EMAC,而MXC_ETH_Init 則會初始化 lwIP堆疊。

Figure 11. A snippet of code giving an overview of the firmware structure.

圖11. 從指令碼片斷觀察韌體的結構

在EMAC與lwIP堆疊完成初始化後,TCP Echo 伺服器會透過tcpecho_raw_init進行初始化。Echo伺服器結構如圖12所示。

Figure 12. The Echo server initialization structure.

圖12. Echo 伺服器初始化結構.

Echo伺服器的初始化會建立新的socket。之後它會將指定的IP位址和埠號綁定到新的socket。完成綁定後,其會持續監聽遠端客戶端發送的連接請求。

要測試TCP伺服器範例,須使用 echotool.exe PC 客戶端工具。echotool.exe執行檔應存放在C槽,故我們應從C槽開啟命令列提示視窗。在客戶端模式中,其會將資料傳送到伺服器並檢查是否會回傳,如圖13所示。確保一定要在客戶端模式中使用echo工具來測試伺服器範例。

如何測試 TCP Server 範例:

  • 確保所有連結都正常運行
  • 使用eclipse軟體將範例程式碼組建成可執行程式
  • 在除錯模式中執行指令碼
  • 在遠端PC開啟命令列提示視窗。
  • 在命令列提示欄中輸入以下指令:
    • “C:\>echotool IP_address /p tcp /r 7 /n 15 /t 2 /d LwIP TCP echo server 
      Example”
          IP_address is the actual board IP address. The static IP address is 
          192.168.100.200 
          /p tcp is the protocol (TCP protocol) 
          /r is the actual remote port on the echo server (echo port) 
          /n is the number of the echo requests  
          /t is the connection timeout in seconds 
          /d is the message to be sent for echo (for example, “LwIP TCP echo server 
          Example”)
                      

Figure 13. TCP Echo server output.

圖13. TCP Echo 伺服器輸出內容

TCP協定和透過網路傳送的資料,都可透過Wireshark軟體進行檢驗。透過網路傳送的封包在會Wireshark中顯示,如圖14所示。透過命令列提示欄傳送的資料為“LwIP TCP echo server Example”。在Wireshark程式中也能看到相同的資料。

Figure 14. TCP Echo server output in Wireshark.

圖14. Wireshark 程式中的TCP Echo 伺服器輸出結果

總結

瞭解並有效率地運用lwIP堆疊的功能以及ICMP協議為基礎的ping工具和TCP協定,能為網路診斷以及資料傳輸開創出眾多的可能性。ADI的MAX32570微控制器與MaximSDK 提供了一個紮實的基礎來建置lwIP堆疊,並建構可靠的通訊系統。藉由依循本文列舉的範例,即可排除各種網路問題,進而創造無縫的連結以及確保資料完整性。

References

1 nongnu.org/lwIP/2_1_x/index.html

wireshark.org/download.html

github.com/PavelBansky/EchoTool