<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用LwIP協議棧淺析實戰分析(i.MX RT)

哈哈hfgfdf ? 來源:嵌入式學習資料 ? 作者:嵌入式學習資料 ? 2024-02-02 17:05 ? 次閱讀

LWIP協議與網絡分層

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

TCP/IP協議棧的模型結構如下圖所示,由于TCP/IP協議棧的出現時間較早,所以沒有按照傳統的7層OSI網絡模型進行設計,一共只分為了4層,分別為網絡接口層,網絡層,傳輸層以及應用層,LwIP協議棧的網絡模型與之類似。

fee6a7cc-b33e-11ee-9b10-92fbcf53809c.png

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

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

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

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

LWIP協議棧初始化

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

netif_add函數用來掛載網絡接口,并完成網絡通信之前的大部分初始化工作,包括PHY芯片的初始化,i.MX RT1060上ENET外設初始化,以及一些通信過程中用到的相關數據結構的初始化。

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

fef8489c-b33e-11ee-9b10-92fbcf53809c.png

ENET外設的初始化在ENET_SetMacController之中完成,這里進行了ENET外設的一些配置,例如設置接口速率,以及接口類型(mii,Rmii)等等。

ff097838-b33e-11ee-9b10-92fbcf53809c.png

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

此外,在進行網絡接口相關初始化的同時,也完成了對一系列數據結構的初始化,此處介紹一些在網絡通信過程中用到的結構體。

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

ff17373e-b33e-11ee-9b10-92fbcf53809c.png

enet_rx_bd_ring_t結構體,如下圖所示,每一條ring都是由buffer descriptor組成的。
ffe414d4-b33e-11ee-9b10-92fbcf53809c.pngRing結構體中的rxBdBase成員就是第一個buffer descriptor的地址,rxGenIdx指的是當前buffer descriptor的序號,rxRingLen指的是這條Ring中共有幾個buffer descriptor。
ffed9aae-b33e-11ee-9b10-92fbcf53809c.png

pbuf結構體,pbuf結構體是用來描述lwip協議棧中數據包的結構體。它是以鏈表的形式存在的,pbuf之中會存在指針指向下一個pubf 。

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

LWIP網絡接口層

網絡接口層數據接收

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

在while循環中首先會去調用ethernetif_input函數,該函數中會調用ethernetif_linkinput函數,在ethernetif_linkinput之中又會去調用ENET_GetRxFrame和ethernetif_rx_frame_to_pbufs函數。


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

ffff8c64-b33e-11ee-9b10-92fbcf53809c.png

網絡接口層數據發送

在網絡層發送數據時,會調用網絡接口層的ethernet_output函數,ethernet_output函數之中又會去調用ethernetif_linkoutput函數,當數據較大需要用多個pbuf進行存儲的時候,pbuf以鏈表的形式存在,所以需要將這些鏈表中的數據進行合并,如下圖所示。

001087e4-b33f-11ee-9b10-92fbcf53809c.png

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

LWIP網絡層

IP協議

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

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

IP地址

在TCP/IP設計過程中,設計人員為每一臺主機分配一個32bit的IP地址,只有具有有效的IP地址的主機才能接入互聯網中與其他主機進行通信。

IP數據報

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

002141f6-b33f-11ee-9b10-92fbcf53809c.png

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

0034d6e4-b33f-11ee-9b10-92fbcf53809c.png

IP層數據接收

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

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

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

0048f638-b33f-11ee-9b10-92fbcf53809c.png

IP層數據發送

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

005a8aba-b33f-11ee-9b10-92fbcf53809c.png

LWIP傳輸層與應用層

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

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

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

UDP報文

在使用UDP傳輸數據時,它會將數據封裝在UDP報文之中,在IP層又會將數據包封裝在IP報文之中,在物理層又會將IP數據包封裝在物理數據幀之中。

一份用戶數據在被發送時共經歷了三次封裝。

00677068-b33f-11ee-9b10-92fbcf53809c.png

UDP相關數據結構

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

LwIP報文首部數據結構為udp_hdr, 定義了 UDP 報文首部的各個字段, 分別為16位源端口號src, 16位目標端口號dest, 16位用戶數據報總長度, 以及16位的校驗和。

007e3870-b33f-11ee-9b10-92fbcf53809c.png

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

00919b2c-b33f-11ee-9b10-92fbcf53809c.png

UDP報文接收

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

00a5f568-b33f-11ee-9b10-92fbcf53809c.png

UDP報文發送

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

00b553d2-b33f-11ee-9b10-92fbcf53809c.png

udp_send和udp_sendto之間的區別就是udp_sendto將數據發送到指定的ip地址和端口號,udp_send將數據發送到UDP控制塊之中定義的ip地址和端口號。udp_send實際上也是調用udp_sendto來進行數據的發送,最終這兩個函數都是會去調用udp_sendto_if。

00d7b8b4-b33f-11ee-9b10-92fbcf53809c.png

udp_sendto_if函數之中會完成udp報文的組裝和發送,最終會調用Ip層的發送函數去發送報文。

LWIP應用層

在應用層一般會通過調用傳輸層的一些函數來編寫特定的應用程序,從而實現數據的傳遞,在udpecho demo之中,當接收到數據之后,在udp控制塊中綁定的接收回調函數中又會去調用udp_sendto函數。

00e818a8-b33f-11ee-9b10-92fbcf53809c.png

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

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

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 協議棧
    +關注

    關注

    2

    文章

    132

    瀏覽量

    33518
  • LwIP協議棧
    +關注

    關注

    0

    文章

    19

    瀏覽量

    7268
收藏 人收藏

    評論

    相關推薦

    使用i.MX RT500實現SPI/DMA AN14170應用指南

    電子發燒友網站提供《使用i.MX RT500實現SPI/DMA AN14170應用指南.pdf》資料免費下載
    發表于 02-01 10:05 ?0次下載
    使用<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>500實現SPI/DMA AN14170應用指南

    i.MX RT SDK的Wi-Fi TX功率表和信道掃描管理應用指南

    電子發燒友網站提供《i.MX RT SDK的Wi-Fi TX功率表和信道掃描管理應用指南.pdf》資料免費下載
    發表于 01-14 09:27 ?0次下載
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b> SDK的Wi-Fi TX功率表和信道掃描管理應用指南

    I.MX RT1052代碼執行在哪里?

    試用的開發板里有了I.MX RT1052 但是看I.MX RT1052有代碼與數據的SPI Flash,還有SRAM,還有片上的TCM 代碼可以執行在TCM上么?還是在SRAM上運行。
    發表于 11-09 06:49

    基于NXP i.MX RT117H智能人機界面方案

    基于NXP i.MX RT117H智能人機界面方案
    的頭像 發表于 10-30 18:22 ?395次閱讀
    基于NXP <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>117H智能人機界面方案

    i.MX RT中FlexSPI外設不常用的讀選通采樣時鐘源

    i.MX RT中FlexSPI外設不常用的讀選通采樣時鐘源
    的頭像 發表于 10-30 17:44 ?308次閱讀
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>中FlexSPI外設不常用的讀選通采樣時鐘源

    理解i.MX RT中FlexSPI外設lookupTable里配置訪問行列混合尋址Memory的參數值

    理解i.MX RT中FlexSPI外設lookupTable里配置訪問行列混合尋址Memory的參數值
    的頭像 發表于 10-30 17:23 ?314次閱讀
    理解<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>中FlexSPI外設lookupTable里配置訪問行列混合尋址Memory的參數值

    淺談i.MX RT10xx系列MCU外接24MHz晶振的作用

    淺談i.MX RT10xx系列MCU外接24MHz晶振的作用
    的頭像 發表于 10-30 17:22 ?444次閱讀
    淺談<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>10xx系列MCU外接24MHz晶振的作用

    i.MX RT1050上如何實現雙大容量存儲(MSC)設備

    i.MX RT1050上如何實現雙大容量存儲(MSC)設備
    的頭像 發表于 10-30 17:08 ?385次閱讀
    在<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>1050上如何實現雙大容量存儲(MSC)設備

    i.MX RT500/600系列上串行NOR Flash雙程序可交替啟動設計

    i.MX RT500/600系列上串行NOR Flash雙程序可交替啟動設計
    的頭像 發表于 10-27 09:36 ?290次閱讀
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>500/600系列上串行NOR Flash雙程序可交替啟動設計

    基于NXP微控制器i.MX RT1170的多人體實時檢測算法和系統

    基于NXP微控制器i.MX RT1170的多人體實時檢測算法和系統
    的頭像 發表于 10-26 16:27 ?769次閱讀
    基于NXP微控制器<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>1170的多人體實時檢測算法和系統

    i.MX RT的FlexRAM配置問題

    i.MX RT的FlexRAM配置問題
    的頭像 發表于 10-24 15:46 ?325次閱讀
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>的FlexRAM配置問題

    i.MX RT1010的I2C Slave時鐘延展功能小記

    i.MX RT1010的I2C Slave時鐘延展功能小記
    的頭像 發表于 09-27 16:22 ?1046次閱讀
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>1010的I2C Slave時鐘延展功能小記

    恩智浦i.MX RT1060/1010上串行NOR Flash冗余程序啟動設計

    恩智浦i.MX RT1060/1010上串行NOR Flash冗余程序啟動設計
    的頭像 發表于 09-26 16:53 ?476次閱讀
    恩智浦<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>1060/1010上串行NOR Flash冗余程序啟動設計

    基于NXP i.MX RT1021跨界MCU實現一個簡單的波形采集

    基于NXP i.MX RT1021跨界MCU實現一個簡單的波形采集,使用了RT1021設計了一個簡單的核心板,然后使用信號發生器產生波形
    發表于 09-13 17:25 ?551次閱讀
    基于NXP <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>1021跨界MCU實現一個簡單的波形采集

    如何配置i.MX RT1064的RTS_B初始狀態?

    我將 i.MX RT1064 引腳 B2 配置為 RTS_B,我注意到我無法配置此功能的初始狀態。這個管腳在RS-485應用中是可以工作的,但是我發現在MCU復位后這個管腳的初始狀態是高電平。在執行
    發表于 06-12 07:17
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>