學會Zynq(10)lwIP簡介
從本篇開始,將花大量篇幅介紹Zynq在裸機環境下乙太網的使用。裸機時最方便的就是使用SDK已經整合了的lwIP 1.4.1庫,我們將先了解lwIP的相關知識,然後再以例項的方式學習TCP、UDP的程式設計方法。
研究背景
在過去幾年裡,將計算機和計算機支援的裝置連線到無線網路的需求逐漸增長。計算機與日常裝置之間的整合度越來越高,價格也在下降。同時,藍芽、IEEE 802.11b/g(俗稱“wifi”)等無線網路技術已經非常普遍。這導致在醫療保健、安全保障、交通業、加工業等領域出現了許多新穎的場景。感測器等小型裝置可以連線到現有的網路設施中(如全球網際網路),人們可以在任何地方監控它們。
網際網路技術非常靈活,能夠適應過去幾十年不斷變化的網路環境。網際網路技術雖然最初是為阿帕網(ARPANET)等低速網路開發的,但現在可以在一個很大的鏈路技術頻譜上執行,在頻寬和誤位元速率方面由截然不同的特性。由於現在已經開發了大量使用網際網路技術的應用程式,能在未來的無線網路中使用現有的網際網路技術是非常有利的。諸如感測器之類的小型裝置通常需要體積小且價格便宜,因此不得不在有限的計算資源和記憶體上實現網際網路協議。
lwIP最早由Adam Dunkels編寫,目前由Kieran Mansley帶領的團隊開發(開發者主頁http://savannah.nongnu.org/projects/lwip )。lwIP是一個小型TCP/IP棧,可以在嵌入式系統中使用。lwIP採取模組化設計,核心棧是IP協議的實現,使用者可以在其上選擇新增TCP、UDP、DHCP等其它協議,包括這些協議的各種特性。當然這樣會導致程式碼量增加、複雜性提高,需要根據使用者的需求進行調整。此外,lwIP在有無作業系統、支援或不支援執行緒的情況下都可以執行,適用於8位或32位微處理器,支援小端和大端系統。
支援協議
lwIP是模組化設計,且支援多種協議,大部分協議在無需使用時可以將其移除,減小程式碼量。lwIP支援的鏈路層和網路層協議包括:
- ARP:一種鏈路層協議,用於將本地硬體地址(即MAC地址)轉譯為IP地址。
- IPv4:目前網際網路中使用的主要的網路層協議。
- IPv6:Ipv4的下一代,IP地址大小擴充套件到了128位。
- ICMP:一種IP的控制協議。
- IGMP:一種IP中多點傳播的管理協議。
lwIP支援的傳輸層協議包括:
- UDP:一種沒有可靠性機制的無連線socket協議。
- TCP:一種面向連線的“流”協議。
lwIP支援的高層次協議包括:
- DHCP:一種帶伺服器的IP地址獲取方法。
- AUTOIP:一種沒有伺服器的IP地址選擇方法。
- SNMP:用於監控網路狀況。
- PPP:在兩個節點之間建立直接連線。
應用程式介面
lwIP提供了三種應用程式介面(Xilinx只支援RAW API和socket API兩種),用於程式和TCP/IP程式碼之間的通訊:
- 低層次的、基於“核”和“回撥”的RAW API
- 兩種高層次的、基於“順序”的API:netconn API和socket API
順序型API類似於BSD socket API,執行模型是基於阻塞的開-讀-寫-關(open-read-write-close)模式。由於TCP/IP棧本質上是基於事件的,所以TCP/IP程式碼和應用程式必須在不同的執行緒中。API之間的差別如下,據此選擇使用哪種API:
- netconn API和raw API只能用於lwIP中,用這些API編寫的程式碼不能移植到其它棧中重用。
- socket API的目的是能與其它posix作業系統/棧之間可移植,但會降低吞吐量。
- socket API和netconn API是需要執行緒的順序型API
- raw API基於回撥機制,比如當新資料到達時呼叫已註冊的回撥函式。由於它不需要切換執行緒,所以由最佳的效能表現。
- raw API和netconn API支援TX和RX的“零拷貝(zero-copy)”。
帶或不帶作業系統的lwIP
lwIP可以在裸機環境下執行,也可以在多執行緒作業系統中執行。
當在沒有作業系統的單執行緒環境中執行lwIP時,只需要IP、ICMP、UDP和TCP協議的實現、緩衝區和記憶體管理等核心元件,當然也可以新增DHCP、DNS等元件,但它們不是必須的。甚至可以只編譯UDP或TCP。在Xilinx中使用的lwIP,如果執行TCP,需要每250ms呼叫依次tcp_tmr,它會執行重傳等TCP定時器的處理工作。UDP則沒有必要。
單執行緒的主迴圈中需要呼叫鏈路層驅動程式(Xilinx介面卡有專用函式),依次處理IP資料包,然後呼叫上層協議處理程式,最後呼叫應用程式的回撥函式。
多執行緒系統中應用程式在併發執行緒中執行。可以讓所有TCP/IP的處理在一個執行緒中完成,使用者應用程式的執行緒通過API函式與TCP/IP執行緒通訊。
最大化吞吐量
一般設計者想盡可能減少程式碼量,並讓lwIP工作在最大吞吐量狀態,有諸多原因會影響到使用lwIP的乙太網裝置的效能。架構設計方面包括:
- 由於網路位元組順序是大端模式,因此最好選擇大端模式的系統,可以省略其中的轉換。
- 系統的一個瓶頸是乙太網MAC驅動程式(lwIP中稱作netif-driver),應儘可能使用中斷和DMA。通常驅動程式可以編寫為偏向於TX或RX,如果應用程式中某個傳輸方向更重要,應確保在高負載情況下首選該方向。在硬體允許的情況下,確保驅動程式支援分散收集(scatter-gather)。
- 另一個瓶頸是TCP和UDP的校驗和計算,傳送資料時生成校驗和,接收資料時檢查校驗和。如果硬體支援,則將校驗和的生成和檢驗留給硬體完成。如果硬體不支援,則確保有一個優化的計算校驗和的軟體架構。
對於在Xilinx中實現,第一點我們無法選擇,第二點Xilinx已經幫你解決了。我們需要注意的就是第三點。lwIP的配置也會影響到吞吐量效能,SDK中如何配置的相關部分檢視本系列其它文章。
如果希望最大化吞吐量,應用程式應該使用RAW API,而不是netconn/socket API。設計程式前,我們首先要選擇使用UDP還是TCP。
- UDP:優點是開銷更少,設計者自己選擇訊息大小;缺點是沒有提供安全的通訊路徑,該協議不能通知使用者對方是否收到了訊息。
- TCP:優點是提供了一個安全的通訊路徑,當對方成功收到訊息時使用者會收到通知;缺點是開銷更大,還會自動選擇訊息大小。
選定協議後,設計者要決定應用程式如何通過網路傳遞資料:
- UDP:確保傳遞的資料塊不會小於網路所允許的最大資料包,比如在標準乙太網中,使用udp_send一次傳送1472個位元組,以最大化一個包中資料位元組和報頭位元組的比,同時最小化網路中包間的間隔。
- TCP:雖然TCP可以將多個tcp_write呼叫的資料合併到一個包中,但由於這個包被分割到多個pbuf中,可能會降低效能。由於TCP需要將資料包儲存起來重新傳輸,直到遠端主機發出應答訊號,所以在tcp_write/tcp_output返回後花費幾秒的時間。如果要傳送小塊資料,應該關掉nagle演算法,讓堆疊立即傳送資料,而不是等待更多資料形成更大的資料包後才傳送資料。應該避免傳送小塊資料,總是等待應答會降低效能。
相關文章
- 學會Zynq(12)lwIP 1.4.1庫的配置與使用
- 學會Zynq(7)中斷系統簡介
- 學會Zynq(1)搭建Zynq-7000 AP SoC處理器
- 學會Zynq(3)Zynq的軟體開發基礎知識
- 學會Zynq(2)Zynq-7000處理器的配置詳解
- 學會Zynq(8)PL中斷示例(SPI)
- 學會Zynq(9)定時器使用示例(PPI)定時器
- 【lwip】lwip原始碼基礎原始碼
- 學會Zynq(5)GPIO中EMIO的使用方法
- 學會Zynq(4)GPIO中MIO的使用方法
- FPGADesigner《學會Zynq》系列目錄與傳送門FPGA
- 學會Zynq(6)固化程式到SD卡或QSPI FlashSD卡
- 學會Zynq(11)RAW API的TCP和UDP程式設計APITCPUDP程式設計
- LWIP裸機移植
- Xilinx-ZYNQ7000系列-學習筆記(7):解決ZYNQ IP核自動佈線後會更改原有配置的問題筆記
- 機器學習簡介機器學習
- 隨機學習簡介隨機
- Java學習:JDBC簡介JavaJDBC
- 強化學習-簡介強化學習
- Daxue:大學眾籌簡介
- gcc簡介(學習筆記)GC筆記
- 元學習簡單介紹
- Unity學習系列一簡介Unity
- 3、Ktor學習-ApplicationCall簡介;APP
- Tensorflow 深度學習簡介(自用)深度學習
- 【機器學習】機器學習簡介機器學習
- 一、資訊學奧賽簡介
- MuJoCo 學習筆記:簡介 Overview筆記View
- 貝葉斯深度學習簡介深度學習
- 深度學習基本概念簡介深度學習
- python基礎學習-socket簡介Python
- 強化學習系列(1):簡介強化學習
- Go語言學習(1) - 簡介Go
- ECMAScript 2019(ES10)新特性簡介
- STM32 LwIP學習過程問題總結(一):LwIP ping不通,抓包發現ICMP校驗和為0x0000
- 《Python深度學習從零開始學》簡介Python深度學習
- 會話、cookie、JWT、令牌、SSO和OAuth 2.0簡介會話CookieJWTOAuth
- 004:ZYNQ_AXI匯流排學習筆記(1)筆記