新聞動态
NEWS FEED
您現在的位置:
首頁
-
-
-
在i.MX RT中(zhōng)使用LwIP協議棧淺析

在i.MX RT中(zhōng)使用LwIP協議棧淺析

  • 分(fēn)類:行業動态
  • 作者:Henry Lu@NXP
  • 來源:恩智浦MCU加油站
  • 發布時間:2022-11-03 11:35
  • 訪問量:

【概要描述】 LWIP協議與網絡分(fēn)層 LwIP(Light weight IP),是一(yī)種輕量化且開(kāi)源的TCP/IP協議棧,它可以在有限的RAM和ROM條件下(xià),實現一(yī)個完整的TCP/IP 協議棧。此外(wài),LwIP既可以移植到操作系統上運行,也可以在無操作系統的情況下(xià)獨立運行。    TCP/IP協議棧的模型結構如下(xià)圖所示,由于TCP/IP協議棧的出現時間較早,所以沒有按照傳統的7層OSI網絡模型進行設計,一(yī)共隻分(fēn)爲了4層,分(fēn)别爲網絡接口層,網絡層,傳輸層以及應用層,LwIP協議棧的網絡模型與之類似。 網絡接口層主要通過雙絞線,光纖,無線等方式進行網絡上數據幀的發送和接收。網絡接口層将網絡層的數據組裝成自己特定的幀進行發送,同時也會接收數據幀進行解析,并将解析過後的數據發送給網絡層。     網絡層負責在主機之間的通信過程之中(zhōng)選擇數據包的傳輸路徑,并且在接收到傳入的數據報時會檢驗其有效性,并遞交給上層。     傳輸層主要提供應用程序之間的通信服務,它會系統的管理兩端數據之間的交互。    應用層簡單來說就是利用傳輸層提供的功能發送自己的數據到對方。   LWIP協議棧初始化 在開(kāi)始傳輸數據之前,首先要進行一(yī)系列的初始化操作,本文以i.MX RT1060 SDK中(zhōng)的Demo "evkmimxrt1060_lwip_udppecho_bm"爲例,該代碼可以通過MCUXpresso IDE進行導入。 netif_add函數用來挂載網絡接口,并完成網絡通信之前的大(dà)部分(fēn)初始化工(gōng)作,包括PHY芯片的初始化,i.MX RT1060上ENET外(wài)設初始化,以及一(yī)些通信過程中(zhōng)用到的相關數據結構的初始化。 PHY芯片的初始化是在ethernetif_phy_init之中(zhōng)完成,包括MDIO初始化,網口自動協商(shāng),網口連接等操作。 PHY初始化函數以及ENET初始化函數都在ethernetif0_init函數中(zhōng)被調用,并且該函數被作爲一(yī)個實參傳入netif_add之中(zhōng)并被在其中(zhōng)被調用,因此netif_add不僅完成了網絡接口的挂載,還完成了接口相關的一(yī)系列初始化工(gōng)作。 此外(wài),在進行網絡接口相關初始化的同時,也完成了對一(yī)系列數據結構的初始化,此處介紹一(yī)些在網絡通信過程中(zhōng)用到的結構體(tǐ)。 enet_rx_bd_struct_t, 該結構體(tǐ)一(yī)般用來定義buffer descriptor,網絡接口層接收到的數據一(yī)般就封裝在buffer descriptor之中(zhōng)。 結構體(tǐ)定義如下(xià)圖所示,其中(zhōng)length代表buffer descriptor之中(zhōng)數據的長度,control之中(zhōng)會存儲一(yī)些與buffer descriptor相關的狀态信息,并且支持enhanced buffer descriptor。 enet_rx_bd_ring_t結構體(tǐ),如下(xià)圖所示,每一(yī)條ring都是由buffer descriptor組成的。 Ring結構體(tǐ)中(zhōng)的rxBdBase成員(yuán)就是第一(yī)個buffer descriptor的地址,rxGenIdx指的是當前buffer descriptor的序号,rxRingLen指的是這條Ring中(zhōng)共有幾個buffer descriptor。 pbuf結構體(tǐ),pbuf結構體(tǐ)是用來描述lwip協議棧中(zhōng)數據包的結構體(tǐ)。它是以鏈表的形式存在的,pbuf之中(zhōng)會存在指針指向下(xià)一(yī)個pubf 。 由于在case之中(zhōng),使用的是UDP通信,因此還需要進行一(yī)些UDP相關的初始化設置。例如調用udp_bind函數,對UDP控制塊中(zhōng)的local_port,local_ip等參數進行綁定,以及調用udp_recv在udp控制塊上進行一(yī)些回調函數的綁定等等,至于什麽是UDP控制塊,在後面會進行介紹。 LWIP網絡接口層 網絡接口層數據接收 在udpecho demo之中(zhōng)是通過輪詢的方法來實現數據接收,使用的是raw/callback api, 除了這種api之外(wài)lwip還提供socket api等,不過需要操作系統的支持。 在while循環中(zhōng)首先會去(qù)調用ethernetif_input函數,該函數中(zhōng)會調用ethernetif_linkinput函數,在ethernetif_linkinput之中(zhōng)又(yòu)會去(qù)調用ENET_GetRxFrame和ethernetif_rx_frame_to_pbufs函數。    在ENET_GetRxFrame函數中(zhōng)會把網絡接口中(zhōng)接收到的數據搬運到RxFrame之中(zhōng),然後ethernetif_rx_frame_to_pbufs函數又(yòu)會把RxFrame之中(zhōng)的數據搬運到pbufs之中(zhōng),接下(xià)來就會調用ethernet_input函數,在lwip源碼之中(zhōng)的ethernet.c文件中(zhōng)被定義,主要用于無操作系統時候網絡層去(qù)處理接收到的數據幀,然後往上層遞交,對于不同的數據包進行不同的處理,如果是 ARP包,則調用etharp_input函數;如果是 IP 包,則調用 ip4_input函數,通過這些函數将數據包遞交給 IP 層處理。 網絡接口層數據發送 在網絡層發送數據時,會調用網絡接口層的ethernet_output函數,ethernet_output函數之中(zhōng)又(yòu)會去(qù)調用ethernetif_linkoutput函數,當數據較大(dà)需要用多個pbuf進行存儲的時候,pbuf以鏈表的形式存在,所以需要将這些鏈表中(zhōng)的數據進行合并,如下(xià)圖所示。 操作完成後通過ENET_SendFrame函數來完成數據的發送;最後數據會通過網絡接口傳輸出去(qù)。   LWIP網絡層 IP協議 IP協議是一(yī)種經典的網絡層協議,IP協議(Internet Protocol),又(yòu)稱之爲網際協議,IP 協議處于IP層工(gōng)作,它是整個TCP/IP協議棧的核心協議,上層協議都要依賴IP協議提供的服務,IP協議負責将數據報從源主機發送到目标主機,并通過IP地址作爲唯一(yī)識别碼。簡單來說,不同主機之間的IP地址是不一(yī)樣的,在發送數據報的過程中(zhōng),IP協議還可能對數據報進行分(fēn)片處理,同時在接收數據報的時候,還可能需要對分(fēn)片的數據報進行重裝等等。 IP協議是一(yī)種無連接的不可靠數據報交付協議,協議本身不提供任何的錯誤檢查與恢複機制,需要傳輸層協議來完成這些功能。 IP地址 在TCP/IP設計過程中(zhōng),設計人員(yuán)爲每一(yī)台主機分(fēn)配一(yī)個32bit的IP地址,隻有具有有效的IP地址的主機才能接入互聯網中(zhōng)與其他主機進行通信。 IP數據報 IP數據包一(yī)般由IP首部和數據組成,首部一(yī)般有20-60字節,其中(zhōng)有40字節是可選的,一(yī)般首部僅由20字節組成,IP數據報結構如下(xià)圖所示。 爲了方便對IP首部進行讀取或寫入操作,在lwip源碼之中(zhōng)定義了ip_hdr結構體(tǐ)來表示ip數據報首部。 IP層數據接收 在上文提到,對于不同的數據包進行不同的處理,如果是ARP包,則調用etharp_input函數去(qù)處理;如果是IP包,則交給IP相關函數去(qù)處理。 在udpecho demo中(zhōng)使用的是IPV4協議,因此,會調用ip4_input函數。 在ip4_input函數中(zhōng)會對ip數據報的相關字段進行檢驗,例如長度,校驗和,版本号等等,也會判斷該數據包是否是發送給本地的,如果不是發送給本地的數據包,可能還要對其進行轉發或者丢棄,如果數據報沒有問題,IP層就會根據傳輸層的協議類型将數據包傳送到不同的入口函數之中(zhōng),例如udp_input, tcp_input函數等。 IP層數據發送 在傳輸層協議需要通過IP層來發送數據時,在上層函數之中(zhōng)會調用ip4_output_if_src函數,在該函數中(zhōng),又(yòu)會去(qù)調用ip4_output_if_opt_src函數,它會将傳輸數據封裝到ip數據報之中(zhōng),填寫數據報之中(zhōng)的目标IP地址,源IP地址,協議類型等相關信息。然後再去(qù)調用etharp_output(),它會解析MAC地址,組裝以太網幀并并發送。在etharp_output()函數之中(zhōng),最終會去(qù)調用網絡接口層的相關發送函數。 LWIP傳輸層與應用層 網絡層已經通過IP協議等完成了數據報在各台主機之間傳輸的的功能,但是數據還沒有到達最終目的地—主機上的某個特定應用程序。 IP層通過傳輸層的協議将數據包遞交給應用程序,常用的傳輸層協議有UDP協議,TCP協議等。 此處以UDP協議爲例,它是一(yī)種較爲簡單的傳輸層協議,經常應用于局域網環境以及視頻(pín)播放(fàng)領域,以UDP爲例結合SDK代碼講解一(yī)下(xià)傳輸層是如何實現數據交互的。   UDP報文 在使用UDP傳輸數據時,它會将數據封裝在UDP報文之中(zhōng),在IP層又(yòu)會将數據包封裝在IP報文之中(zhōng),在物(wù)理層又(yòu)會将IP數據包封裝在物(wù)理數據幀之中(zhōng)。 一(yī)份用戶數據在被發送時共經曆了三次封裝。 UDP相關數據結構 在LWIP源碼的udp.h之中(zhōng),定義了報文首部數據結構以及UDP控制塊。 LwIP報文首部數據結構爲udp_hdr, 定義了 UDP 報文首部的各個字段, 分(fēn)别爲16位源端口号src, 16位目标端口号dest, 16位用戶數據報總長度, 以及16位的校驗和。 LwIP還定義了UDP控制塊,記錄與UDP通信的所有相關信息,如源端口号、目标端口号、源IP地址、目标IP地址以及收到數據時的回調函數等等,系統會爲每一(yī)個基于UDP協議的進程創建一(yī)個UDP控制塊,并且将其與對應的端口綁定,并将所有的UDP控制塊用一(yī)個鏈表連接起來。當UDP接收到一(yī)個報文的時候,會去(qù)遍曆鏈表上的所有控制塊,通過端口号來找到匹配的控制塊,并将數據通過回調函數傳遞到上層應用。 UDP報文接收 在IP層,當接收到一(yī)個包含UDP報文的數據報時,udp_input函數就會被調用,該函數之中(zhōng)進行了一(yī)些報文合法性的檢測,然後根據報文中(zhōng)的端口信息查找UDP控制塊,最後通過UDP控制塊之中(zhōng)的回調函數recv_udp将數據傳遞到應用層,如果找不到對應的端口,那麽會返回一(yī)個端口不可達數據包。 UDP報文發送 UDP報文發送依靠IP層提供的服務,用戶在發送數據時需要在應用程序之中(zhōng)調用udp_send或者是udp_sendto,應用程序之中(zhōng)将用戶數據填到pbuf數據區域,并将pubf作爲參數傳入udp_send或udp_sendto之中(zhōng)。 udp_send和udp_sendto之間的區别就是udp_sendto将數據發送到指定的ip地址和端口号,udp_send将數據發送到UDP控制塊之中(zhōng)定義的ip地址和端口号。udp_send實際上也是調用udp_sendto來進行數據的發送,最終這兩個函數都是會去(qù)調用udp_sendto_if。 dp_sendto_if函數之中(zhōng)會完成udp報文的組裝和發送,最終會調用Ip層的發送函數去(qù)發送報文。   LWIP應用層 在應用層一(yī)般會通過調用傳輸層的一(yī)些函數來編寫特定的應用程序,從而實現數據的傳遞,在udpecho demo之中(zhōng),當接收到數據之後,在udp控制塊中(zhōng)綁定的接收回調函數中(zhōng)又(yòu)會去(qù)調用udp_sendto函數。 除了上面介紹的一(yī)些協議外(wài),LWIP還支持ICMP、IGMP、PPP、DHCP等協議,并且SOCKET API以及NETCONN API使用起來更加簡單,但是RAW/Callback API的使用有助于更好的理解LWIP協議。 對LWIP協議棧感興趣的讀者可自行深入了解。   關注威旺達網站及微信公衆号,了解 NXP MCU更多信息.

在i.MX RT中(zhōng)使用LwIP協議棧淺析

【概要描述】


LWIP協議與網絡分(fēn)層




LwIP(Light weight IP),是一(yī)種輕量化且開(kāi)源的TCP/IP協議棧,它可以在有限的RAM和ROM條件下(xià),實現一(yī)個完整的TCP/IP 協議棧。此外(wài),LwIP既可以移植到操作系統上運行,也可以在無操作系統的情況下(xià)獨立運行。 

  TCP/IP協議棧的模型結構如下(xià)圖所示,由于TCP/IP協議棧的出現時間較早,所以沒有按照傳統的7層OSI網絡模型進行設計,一(yī)共隻分(fēn)爲了4層,分(fēn)别爲網絡接口層,網絡層,傳輸層以及應用層,LwIP協議棧的網絡模型與之類似。



網絡接口層主要通過雙絞線,光纖,無線等方式進行網絡上數據幀的發送和接收。網絡接口層将網絡層的數據組裝成自己特定的幀進行發送,同時也會接收數據幀進行解析,并将解析過後的數據發送給網絡層。 

   網絡層負責在主機之間的通信過程之中(zhōng)選擇數據包的傳輸路徑,并且在接收到傳入的數據報時會檢驗其有效性,并遞交給上層。 

   傳輸層主要提供應用程序之間的通信服務,它會系統的管理兩端數據之間的交互。

   應用層簡單來說就是利用傳輸層提供的功能發送自己的數據到對方。

 




LWIP協議棧初始化




在開(kāi)始傳輸數據之前,首先要進行一(yī)系列的初始化操作,本文以i.MX RT1060 SDK中(zhōng)的Demo "evkmimxrt1060_lwip_udppecho_bm"爲例,該代碼可以通過MCUXpresso IDE進行導入。

netif_add函數用來挂載網絡接口,并完成網絡通信之前的大(dà)部分(fēn)初始化工(gōng)作,包括PHY芯片的初始化,i.MX RT1060上ENET外(wài)設初始化,以及一(yī)些通信過程中(zhōng)用到的相關數據結構的初始化。

PHY芯片的初始化是在ethernetif_phy_init之中(zhōng)完成,包括MDIO初始化,網口自動協商(shāng),網口連接等操作。



PHY初始化函數以及ENET初始化函數都在ethernetif0_init函數中(zhōng)被調用,并且該函數被作爲一(yī)個實參傳入netif_add之中(zhōng)并被在其中(zhōng)被調用,因此netif_add不僅完成了網絡接口的挂載,還完成了接口相關的一(yī)系列初始化工(gōng)作。

此外(wài),在進行網絡接口相關初始化的同時,也完成了對一(yī)系列數據結構的初始化,此處介紹一(yī)些在網絡通信過程中(zhōng)用到的結構體(tǐ)。



enet_rx_bd_struct_t, 該結構體(tǐ)一(yī)般用來定義buffer descriptor,網絡接口層接收到的數據一(yī)般就封裝在buffer descriptor之中(zhōng)。
結構體(tǐ)定義如下(xià)圖所示,其中(zhōng)length代表buffer descriptor之中(zhōng)數據的長度,control之中(zhōng)會存儲一(yī)些與buffer descriptor相關的狀态信息,并且支持enhanced buffer descriptor。



enet_rx_bd_ring_t結構體(tǐ),如下(xià)圖所示,每一(yī)條ring都是由buffer descriptor組成的。

Ring結構體(tǐ)中(zhōng)的rxBdBase成員(yuán)就是第一(yī)個buffer descriptor的地址,rxGenIdx指的是當前buffer descriptor的序号,rxRingLen指的是這條Ring中(zhōng)共有幾個buffer descriptor。





pbuf結構體(tǐ),pbuf結構體(tǐ)是用來描述lwip協議棧中(zhōng)數據包的結構體(tǐ)。它是以鏈表的形式存在的,pbuf之中(zhōng)會存在指針指向下(xià)一(yī)個pubf 。



由于在case之中(zhōng),使用的是UDP通信,因此還需要進行一(yī)些UDP相關的初始化設置。例如調用udp_bind函數,對UDP控制塊中(zhōng)的local_port,local_ip等參數進行綁定,以及調用udp_recv在udp控制塊上進行一(yī)些回調函數的綁定等等,至于什麽是UDP控制塊,在後面會進行介紹。




LWIP網絡接口層




網絡接口層數據接收

在udpecho demo之中(zhōng)是通過輪詢的方法來實現數據接收,使用的是raw/callback api, 除了這種api之外(wài)lwip還提供socket api等,不過需要操作系統的支持。

在while循環中(zhōng)首先會去(qù)調用ethernetif_input函數,該函數中(zhōng)會調用ethernetif_linkinput函數,在ethernetif_linkinput之中(zhōng)又(yòu)會去(qù)調用ENET_GetRxFrame和ethernetif_rx_frame_to_pbufs函數。

   在ENET_GetRxFrame函數中(zhōng)會把網絡接口中(zhōng)接收到的數據搬運到RxFrame之中(zhōng),然後ethernetif_rx_frame_to_pbufs函數又(yòu)會把RxFrame之中(zhōng)的數據搬運到pbufs之中(zhōng),接下(xià)來就會調用ethernet_input函數,在lwip源碼之中(zhōng)的ethernet.c文件中(zhōng)被定義,主要用于無操作系統時候網絡層去(qù)處理接收到的數據幀,然後往上層遞交,對于不同的數據包進行不同的處理,如果是 ARP包,則調用etharp_input函數;如果是 IP 包,則調用 ip4_input函數,通過這些函數将數據包遞交給 IP 層處理。



網絡接口層數據發送

在網絡層發送數據時,會調用網絡接口層的ethernet_output函數,ethernet_output函數之中(zhōng)又(yòu)會去(qù)調用ethernetif_linkoutput函數,當數據較大(dà)需要用多個pbuf進行存儲的時候,pbuf以鏈表的形式存在,所以需要将這些鏈表中(zhōng)的數據進行合并,如下(xià)圖所示。

操作完成後通過ENET_SendFrame函數來完成數據的發送;最後數據會通過網絡接口傳輸出去(qù)。

 




LWIP網絡層




IP協議

IP協議是一(yī)種經典的網絡層協議,IP協議(Internet Protocol),又(yòu)稱之爲網際協議,IP 協議處于IP層工(gōng)作,它是整個TCP/IP協議棧的核心協議,上層協議都要依賴IP協議提供的服務,IP協議負責将數據報從源主機發送到目标主機,并通過IP地址作爲唯一(yī)識别碼。簡單來說,不同主機之間的IP地址是不一(yī)樣的,在發送數據報的過程中(zhōng),IP協議還可能對數據報進行分(fēn)片處理,同時在接收數據報的時候,還可能需要對分(fēn)片的數據報進行重裝等等。

IP協議是一(yī)種無連接的不可靠數據報交付協議,協議本身不提供任何的錯誤檢查與恢複機制,需要傳輸層協議來完成這些功能。

IP地址

在TCP/IP設計過程中(zhōng),設計人員(yuán)爲每一(yī)台主機分(fēn)配一(yī)個32bit的IP地址,隻有具有有效的IP地址的主機才能接入互聯網中(zhōng)與其他主機進行通信。

IP數據報

IP數據包一(yī)般由IP首部和數據組成,首部一(yī)般有20-60字節,其中(zhōng)有40字節是可選的,一(yī)般首部僅由20字節組成,IP數據報結構如下(xià)圖所示。

爲了方便對IP首部進行讀取或寫入操作,在lwip源碼之中(zhōng)定義了ip_hdr結構體(tǐ)來表示ip數據報首部。

IP層數據接收

在上文提到,對于不同的數據包進行不同的處理,如果是ARP包,則調用etharp_input函數去(qù)處理;如果是IP包,則交給IP相關函數去(qù)處理。

在udpecho demo中(zhōng)使用的是IPV4協議,因此,會調用ip4_input函數。

在ip4_input函數中(zhōng)會對ip數據報的相關字段進行檢驗,例如長度,校驗和,版本号等等,也會判斷該數據包是否是發送給本地的,如果不是發送給本地的數據包,可能還要對其進行轉發或者丢棄,如果數據報沒有問題,IP層就會根據傳輸層的協議類型将數據包傳送到不同的入口函數之中(zhōng),例如udp_input, tcp_input函數等。



IP層數據發送

在傳輸層協議需要通過IP層來發送數據時,在上層函數之中(zhōng)會調用ip4_output_if_src函數,在該函數中(zhōng),又(yòu)會去(qù)調用ip4_output_if_opt_src函數,它會将傳輸數據封裝到ip數據報之中(zhōng),填寫數據報之中(zhōng)的目标IP地址,源IP地址,協議類型等相關信息。然後再去(qù)調用etharp_output(),它會解析MAC地址,組裝以太網幀并并發送。在etharp_output()函數之中(zhōng),最終會去(qù)調用網絡接口層的相關發送函數。






LWIP傳輸層與應用層




網絡層已經通過IP協議等完成了數據報在各台主機之間傳輸的的功能,但是數據還沒有到達最終目的地—主機上的某個特定應用程序。

IP層通過傳輸層的協議将數據包遞交給應用程序,常用的傳輸層協議有UDP協議,TCP協議等。

此處以UDP協議爲例,它是一(yī)種較爲簡單的傳輸層協議,經常應用于局域網環境以及視頻(pín)播放(fàng)領域,以UDP爲例結合SDK代碼講解一(yī)下(xià)傳輸層是如何實現數據交互的。

 




UDP報文




在使用UDP傳輸數據時,它會将數據封裝在UDP報文之中(zhōng),在IP層又(yòu)會将數據包封裝在IP報文之中(zhōng),在物(wù)理層又(yòu)會将IP數據包封裝在物(wù)理數據幀之中(zhōng)。

一(yī)份用戶數據在被發送時共經曆了三次封裝。

UDP相關數據結構

在LWIP源碼的udp.h之中(zhōng),定義了報文首部數據結構以及UDP控制塊。

LwIP報文首部數據結構爲udp_hdr, 定義了 UDP 報文首部的各個字段, 分(fēn)别爲16位源端口号src, 16位目标端口号dest, 16位用戶數據報總長度, 以及16位的校驗和。

LwIP還定義了UDP控制塊,記錄與UDP通信的所有相關信息,如源端口号、目标端口号、源IP地址、目标IP地址以及收到數據時的回調函數等等,系統會爲每一(yī)個基于UDP協議的進程創建一(yī)個UDP控制塊,并且将其與對應的端口綁定,并将所有的UDP控制塊用一(yī)個鏈表連接起來。當UDP接收到一(yī)個報文的時候,會去(qù)遍曆鏈表上的所有控制塊,通過端口号來找到匹配的控制塊,并将數據通過回調函數傳遞到上層應用。



UDP報文接收

在IP層,當接收到一(yī)個包含UDP報文的數據報時,udp_input函數就會被調用,該函數之中(zhōng)進行了一(yī)些報文合法性的檢測,然後根據報文中(zhōng)的端口信息查找UDP控制塊,最後通過UDP控制塊之中(zhōng)的回調函數recv_udp将數據傳遞到應用層,如果找不到對應的端口,那麽會返回一(yī)個端口不可達數據包。



UDP報文發送

UDP報文發送依靠IP層提供的服務,用戶在發送數據時需要在應用程序之中(zhōng)調用udp_send或者是udp_sendto,應用程序之中(zhōng)将用戶數據填到pbuf數據區域,并将pubf作爲參數傳入udp_send或udp_sendto之中(zhōng)。

udp_send和udp_sendto之間的區别就是udp_sendto将數據發送到指定的ip地址和端口号,udp_send将數據發送到UDP控制塊之中(zhōng)定義的ip地址和端口号。udp_send實際上也是調用udp_sendto來進行數據的發送,最終這兩個函數都是會去(qù)調用udp_sendto_if。



dp_sendto_if函數之中(zhōng)會完成udp報文的組裝和發送,最終會調用Ip層的發送函數去(qù)發送報文。

 




LWIP應用層




在應用層一(yī)般會通過調用傳輸層的一(yī)些函數來編寫特定的應用程序,從而實現數據的傳遞,在udpecho demo之中(zhōng),當接收到數據之後,在udp控制塊中(zhōng)綁定的接收回調函數中(zhōng)又(yòu)會去(qù)調用udp_sendto函數。



除了上面介紹的一(yī)些協議外(wài),LWIP還支持ICMP、IGMP、PPP、DHCP等協議,并且SOCKET API以及NETCONN API使用起來更加簡單,但是RAW/Callback API的使用有助于更好的理解LWIP協議。

對LWIP協議棧感興趣的讀者可自行深入了解。

 

關注威旺達網站及微信公衆号,了解 NXP MCU更多信息.

  • 分(fēn)類:行業動态
  • 作者:Henry Lu@NXP
  • 來源:恩智浦MCU加油站
  • 發布時間:2022-11-03 11:35
  • 訪問量:
詳情

LWIP協議與網絡分(fēn)層

LwIP(Light weight IP),是一(yī)種輕量化且開(kāi)源的TCP/IP協議棧,它可以在有限的RAM和ROM條件下(xià),實現一(yī)個完整的TCP/IP 協議棧。此外(wài),LwIP既可以移植到操作系統上運行,也可以在無操作系統的情況下(xià)獨立運行。 

  TCP/IP協議棧的模型結構如下(xià)圖所示,由于TCP/IP協議棧的出現時間較早,所以沒有按照傳統的7層OSI網絡模型進行設計,一(yī)共隻分(fēn)爲了4層,分(fēn)别爲網絡接口層,網絡層,傳輸層以及應用層,LwIP協議棧的網絡模型與之類似。

網絡接口層主要通過雙絞線,光纖,無線等方式進行網絡上數據幀的發送和接收。網絡接口層将網絡層的數據組裝成自己特定的幀進行發送,同時也會接收數據幀進行解析,并将解析過後的數據發送給網絡層。 

   網絡層負責在主機之間的通信過程之中(zhōng)選擇數據包的傳輸路徑,并且在接收到傳入的數據報時會檢驗其有效性,并遞交給上層。 

   傳輸層主要提供應用程序之間的通信服務,它會系統的管理兩端數據之間的交互。

   應用層簡單來說就是利用傳輸層提供的功能發送自己的數據到對方。

 

LWIP協議棧初始化

在開(kāi)始傳輸數據之前,首先要進行一(yī)系列的初始化操作,本文以i.MX RT1060 SDK中(zhōng)的Demo "evkmimxrt1060_lwip_udppecho_bm"爲例,該代碼可以通過MCUXpresso IDE進行導入。

netif_add函數用來挂載網絡接口,并完成網絡通信之前的大(dà)部分(fēn)初始化工(gōng)作,包括PHY芯片的初始化,i.MX RT1060上ENET外(wài)設初始化,以及一(yī)些通信過程中(zhōng)用到的相關數據結構的初始化。

PHY芯片的初始化是在ethernetif_phy_init之中(zhōng)完成,包括MDIO初始化,網口自動協商(shāng),網口連接等操作。

PHY初始化函數以及ENET初始化函數都在ethernetif0_init函數中(zhōng)被調用,并且該函數被作爲一(yī)個實參傳入netif_add之中(zhōng)并被在其中(zhōng)被調用,因此netif_add不僅完成了網絡接口的挂載,還完成了接口相關的一(yī)系列初始化工(gōng)作。

此外(wài),在進行網絡接口相關初始化的同時,也完成了對一(yī)系列數據結構的初始化,此處介紹一(yī)些在網絡通信過程中(zhōng)用到的結構體(tǐ)。

  • enet_rx_bd_struct_t, 該結構體(tǐ)一(yī)般用來定義buffer descriptor,網絡接口層接收到的數據一(yī)般就封裝在buffer descriptor之中(zhōng)。
    結構體(tǐ)定義如下(xià)圖所示,其中(zhōng)length代表buffer descriptor之中(zhōng)數據的長度,control之中(zhōng)會存儲一(yī)些與buffer descriptor相關的狀态信息,并且支持enhanced buffer descriptor。

enet_rx_bd_ring_t結構體(tǐ),如下(xià)圖所示,每一(yī)條ring都是由buffer descriptor組成的。

Ring結構體(tǐ)中(zhōng)的rxBdBase成員(yuán)就是第一(yī)個buffer descriptor的地址,rxGenIdx指的是當前buffer descriptor的序号,rxRingLen指的是這條Ring中(zhōng)共有幾個buffer descriptor。

  • pbuf結構體(tǐ),pbuf結構體(tǐ)是用來描述lwip協議棧中(zhōng)數據包的結構體(tǐ)。它是以鏈表的形式存在的,pbuf之中(zhōng)會存在指針指向下(xià)一(yī)個pubf 。

由于在case之中(zhōng),使用的是UDP通信,因此還需要進行一(yī)些UDP相關的初始化設置。例如調用udp_bind函數,對UDP控制塊中(zhōng)的local_port,local_ip等參數進行綁定,以及調用udp_recv在udp控制塊上進行一(yī)些回調函數的綁定等等,至于什麽是UDP控制塊,在後面會進行介紹。

LWIP網絡接口層

網絡接口層數據接收

在udpecho demo之中(zhōng)是通過輪詢的方法來實現數據接收,使用的是raw/callback api, 除了這種api之外(wài)lwip還提供socket api等,不過需要操作系統的支持。

在while循環中(zhōng)首先會去(qù)調用ethernetif_input函數,該函數中(zhōng)會調用ethernetif_linkinput函數,在ethernetif_linkinput之中(zhōng)又(yòu)會去(qù)調用ENET_GetRxFrame和ethernetif_rx_frame_to_pbufs函數。

   在ENET_GetRxFrame函數中(zhōng)會把網絡接口中(zhōng)接收到的數據搬運到RxFrame之中(zhōng),然後ethernetif_rx_frame_to_pbufs函數又(yòu)會把RxFrame之中(zhōng)的數據搬運到pbufs之中(zhōng),接下(xià)來就會調用ethernet_input函數,在lwip源碼之中(zhōng)的ethernet.c文件中(zhōng)被定義,主要用于無操作系統時候網絡層去(qù)處理接收到的數據幀,然後往上層遞交,對于不同的數據包進行不同的處理,如果是 ARP包,則調用etharp_input函數;如果是 IP 包,則調用 ip4_input函數,通過這些函數将數據包遞交給 IP 層處理。

網絡接口層數據發送

在網絡層發送數據時,會調用網絡接口層的ethernet_output函數,ethernet_output函數之中(zhōng)又(yòu)會去(qù)調用ethernetif_linkoutput函數,當數據較大(dà)需要用多個pbuf進行存儲的時候,pbuf以鏈表的形式存在,所以需要将這些鏈表中(zhōng)的數據進行合并,如下(xià)圖所示。

操作完成後通過ENET_SendFrame函數來完成數據的發送;最後數據會通過網絡接口傳輸出去(qù)。

 

LWIP網絡層

IP協議

IP協議是一(yī)種經典的網絡層協議,IP協議(Internet Protocol),又(yòu)稱之爲網際協議,IP 協議處于IP層工(gōng)作,它是整個TCP/IP協議棧的核心協議,上層協議都要依賴IP協議提供的服務,IP協議負責将數據報從源主機發送到目标主機,并通過IP地址作爲唯一(yī)識别碼。簡單來說,不同主機之間的IP地址是不一(yī)樣的,在發送數據報的過程中(zhōng),IP協議還可能對數據報進行分(fēn)片處理,同時在接收數據報的時候,還可能需要對分(fēn)片的數據報進行重裝等等。

IP協議是一(yī)種無連接的不可靠數據報交付協議,協議本身不提供任何的錯誤檢查與恢複機制,需要傳輸層協議來完成這些功能。

IP地址

在TCP/IP設計過程中(zhōng),設計人員(yuán)爲每一(yī)台主機分(fēn)配一(yī)個32bit的IP地址,隻有具有有效的IP地址的主機才能接入互聯網中(zhōng)與其他主機進行通信。

IP數據報

IP數據包一(yī)般由IP首部和數據組成,首部一(yī)般有20-60字節,其中(zhōng)有40字節是可選的,一(yī)般首部僅由20字節組成,IP數據報結構如下(xià)圖所示。

爲了方便對IP首部進行讀取或寫入操作,在lwip源碼之中(zhōng)定義了ip_hdr結構體(tǐ)來表示ip數據報首部。

IP層數據接收

在上文提到,對于不同的數據包進行不同的處理,如果是ARP包,則調用etharp_input函數去(qù)處理;如果是IP包,則交給IP相關函數去(qù)處理。

在udpecho demo中(zhōng)使用的是IPV4協議,因此,會調用ip4_input函數。

在ip4_input函數中(zhōng)會對ip數據報的相關字段進行檢驗,例如長度,校驗和,版本号等等,也會判斷該數據包是否是發送給本地的,如果不是發送給本地的數據包,可能還要對其進行轉發或者丢棄,如果數據報沒有問題,IP層就會根據傳輸層的協議類型将數據包傳送到不同的入口函數之中(zhōng),例如udp_input, tcp_input函數等。

IP層數據發送

在傳輸層協議需要通過IP層來發送數據時,在上層函數之中(zhōng)會調用ip4_output_if_src函數,在該函數中(zhōng),又(yòu)會去(qù)調用ip4_output_if_opt_src函數,它會将傳輸數據封裝到ip數據報之中(zhōng),填寫數據報之中(zhōng)的目标IP地址,源IP地址,協議類型等相關信息。然後再去(qù)調用etharp_output(),它會解析MAC地址,組裝以太網幀并并發送。在etharp_output()函數之中(zhōng),最終會去(qù)調用網絡接口層的相關發送函數。

LWIP傳輸層與應用層

網絡層已經通過IP協議等完成了數據報在各台主機之間傳輸的的功能,但是數據還沒有到達最終目的地—主機上的某個特定應用程序。

IP層通過傳輸層的協議将數據包遞交給應用程序,常用的傳輸層協議有UDP協議,TCP協議等。

此處以UDP協議爲例,它是一(yī)種較爲簡單的傳輸層協議,經常應用于局域網環境以及視頻(pín)播放(fàng)領域,以UDP爲例結合SDK代碼講解一(yī)下(xià)傳輸層是如何實現數據交互的。

 

UDP報文

在使用UDP傳輸數據時,它會将數據封裝在UDP報文之中(zhōng),在IP層又(yòu)會将數據包封裝在IP報文之中(zhōng),在物(wù)理層又(yòu)會将IP數據包封裝在物(wù)理數據幀之中(zhōng)。

一(yī)份用戶數據在被發送時共經曆了三次封裝。

UDP相關數據結構

在LWIP源碼的udp.h之中(zhōng),定義了報文首部數據結構以及UDP控制塊。

LwIP報文首部數據結構爲udp_hdr, 定義了 UDP 報文首部的各個字段, 分(fēn)别爲16位源端口号src, 16位目标端口号dest, 16位用戶數據報總長度, 以及16位的校驗和。

LwIP還定義了UDP控制塊,記錄與UDP通信的所有相關信息,如源端口号、目标端口号、源IP地址、目标IP地址以及收到數據時的回調函數等等,系統會爲每一(yī)個基于UDP協議的進程創建一(yī)個UDP控制塊,并且将其與對應的端口綁定,并将所有的UDP控制塊用一(yī)個鏈表連接起來。當UDP接收到一(yī)個報文的時候,會去(qù)遍曆鏈表上的所有控制塊,通過端口号來找到匹配的控制塊,并将數據通過回調函數傳遞到上層應用。

UDP報文接收

在IP層,當接收到一(yī)個包含UDP報文的數據報時,udp_input函數就會被調用,該函數之中(zhōng)進行了一(yī)些報文合法性的檢測,然後根據報文中(zhōng)的端口信息查找UDP控制塊,最後通過UDP控制塊之中(zhōng)的回調函數recv_udp将數據傳遞到應用層,如果找不到對應的端口,那麽會返回一(yī)個端口不可達數據包。

UDP報文發送

UDP報文發送依靠IP層提供的服務,用戶在發送數據時需要在應用程序之中(zhōng)調用udp_send或者是udp_sendto,應用程序之中(zhōng)将用戶數據填到pbuf數據區域,并将pubf作爲參數傳入udp_send或udp_sendto之中(zhōng)。

udp_send和udp_sendto之間的區别就是udp_sendto将數據發送到指定的ip地址和端口号,udp_send将數據發送到UDP控制塊之中(zhōng)定義的ip地址和端口号。udp_send實際上也是調用udp_sendto來進行數據的發送,最終這兩個函數都是會去(qù)調用udp_sendto_if。

dp_sendto_if函數之中(zhōng)會完成udp報文的組裝和發送,最終會調用Ip層的發送函數去(qù)發送報文。

 

LWIP應用層

在應用層一(yī)般會通過調用傳輸層的一(yī)些函數來編寫特定的應用程序,從而實現數據的傳遞,在udpecho demo之中(zhōng),當接收到數據之後,在udp控制塊中(zhōng)綁定的接收回調函數中(zhōng)又(yòu)會去(qù)調用udp_sendto函數。

除了上面介紹的一(yī)些協議外(wài),LWIP還支持ICMP、IGMP、PPP、DHCP等協議,并且SOCKET API以及NETCONN API使用起來更加簡單,但是RAW/Callback API的使用有助于更好的理解LWIP協議。

對LWIP協議棧感興趣的讀者可自行深入了解。

 

關注威旺達網站及微信公衆号,了解 NXP MCU更多信息.

關鍵詞:

掃二維碼用手機看

相關新聞

無創血糖儀的優勢與挑戰:解讀新技術的前景與限制

無創血糖儀的優勢與挑戰:解讀新技術的前景與限制

在中(zhōng)國,改革開(kāi)放(fàng)以來,人們的生(shēng)活水平逐步提高,從吃飽到吃好,現在更多數人選擇吃的健康。因爲現在的人類基本都在得“富貴病”,肥胖,高血壓,高血脂,高血糖等。其中(zhōng),血糖監測是糖尿病管理的重要組成部分(fēn),《中(zhōng)國血糖監測臨床應用指南(nán)(2021版)》顯示,臨床常用的血糖監測方法包括毛細血管血糖監測、糖化血紅蛋白(bái)(HbA1c)、糖化白(bái)蛋白(bái)(GA)和持續葡萄糖(CGM)監測等。
2023-07-12
恩智浦發布新一(yī)代安全高能效i.MX 91系列,爲廣泛的邊緣應用擴展Linux功能!

恩智浦發布新一(yī)代安全高能效i.MX 91系列,爲廣泛的邊緣應用擴展Linux功能!

恩智浦半導體(tǐ)正式發布i.MX 91應用處理器系列。憑借恩智浦二十多年來在開(kāi)發多市場應用處理器方面的領先優勢,i.MX 91系列提供了安全、多功能、高能效的優化組合,可滿足下(xià)一(yī)代基于Linux的物(wù)聯網和工(gōng)業應用的需求。 
2023-06-15
恩智浦人工(gōng)智能創新實踐平台正式啓動!

恩智浦人工(gōng)智能創新實踐平台正式啓動!

  恩智浦半導體(tǐ)宣布,設于天津的人工(gōng)智能應用創新中(zhōng)心二期項目——人工(gōng)智能創新實踐平台(以下(xià)稱“創新實踐平台”)正式啓動。天津市科學技術局副局長梅志(zhì)紅,天津經濟技術開(kāi)發區管理委員(yuán)會副主任金香花;恩智浦全球銷售執行副總裁Ron Martino,恩智浦資(zī)深副總裁兼大(dà)中(zhōng)華區主席李廷偉博士出席活動,共同見證恩智浦進一(yī)步深耕中(zhōng)國市場、服務中(zhōng)國客戶的決心和切實行動。
2023-05-26
MCU在煙感傳感器上如何選型

MCU在煙感傳感器上如何選型

獨立煙感全稱獨立式光電(diàn)感煙火(huǒ)災探測報警器,是煙霧報警器系列産品中(zhōng)的一(yī)種,報警器采用的光電(diàn)式感煙器件具有優良的生(shēng)産工(gōng)藝,工(gōng)作穩定,抗輻射性好,當煙霧進入報警器探頭,煙霧改變了探頭感知(zhī)的光線強度,繼而觸發報價;故障自檢,自動上報,無需人工(gōng)檢修;此外(wài)無需外(wài)部供電(diàn),單獨9V電(diàn)池供電(diàn),搭載低功耗廣域網物(wù)聯網模塊,如NBIOT,Lora,RF射頻(pín)模塊後,省去(qù)了繁瑣的布線,施工(gōng)成本低,安裝簡單;發生(shēng)火(huǒ)災時除了自身報警外(wài),還可以通過無線上傳到消防預警中(zhōng)心,并通過語音電(diàn)話(huà),app等形式通知(zhī)安全責任人,第一(yī)時間處理火(huǒ)情;再加上傳統的消防設備安裝和出現故障維修極其不便,傳統的煙感大(dà)部分(fēn)年久失靈,必須進行設備的升級;故獨立煙感可廣泛用于工(gōng)廠,商(shāng)場,賓館、門店(diàn)、飯店(diàn)、住宅等場所進行火(huǒ)災安全監測及其傳統消防設備的改造上,普通用戶也可自行采購放(fàng)置在家中(zhōng)作爲火(huǒ)災監控預警。
2023-05-26

20多年專注半導體(tǐ)

爲國内各行業廣大(dà)用戶提供高品質的NXP半導體(tǐ)産品

SINCE 1997

 爲您量身定制解決方案

聯系我(wǒ)(wǒ)們

電(diàn)話(huà)

全國統一(yī)服務熱線

地址:北(běi)京市朝陽區廣渠路15号金茂府小(xiǎo)區23号院

公衆号

威旺達公衆号

Copyright © 2022  北(běi)京威旺達電(diàn)子科技有限責任公司  All rights reserved