日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

rtthread工业使用_基于RTThread 的LwIP使用讲解

發布時間:2024/3/26 编程问答 77 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rtthread工业使用_基于RTThread 的LwIP使用讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在RT-Thread 1.1.x系列中默認使用lwIP 1.4.0作為TCP/IP協議棧,同時為了保持原有驅動的兼容性,

對lwIP 1.4初始移植做了調整,在驅動編寫,初始化順序上可以完整兼容lwIP 1.3.2的風格。

lwip 1.4 遷移指南

一、lwip,netif架構

+-----------------------+

|? ?driver interface? ? |

|? ?? ?? ?? ?? ?? ?? ???|

|? ?struct eth_device? ?|

| +-eth_rx_ready()? ?? ?|

+---->+-link_up()? ?? ?|? ? |

|? ?| +-link_down()? ? |? ? |

|? ?+------------------|----+

+-------------+ |? ?+------------------|----+? ? +-------------------+

| driver? ?? ?| |? ?|? ?ethernetif? ???|? ? |? ? | lwip 1.4? ?? ?? ? |

|? ?? ?? ?? ? | |? ?|? ?? ?? ?? ?? ?? ?V? ? |? ? |? ?? ?? ?? ?? ?? ? |

| isr() --------+? ?|? ?rx_thread? ?? ?? ???|? ? | tcpip_thread? ?? ?|

| rx()??input??------------>tcpip_input? ?? ? |

| tx()??output

|? ?? ?? ?? ? |? ???|? ?? ?? ?? ?? ?? ?? ???|? ? |? ?? ?? ?? ?? ?? ? |

+-------------+? ???+-----------------------+? ? +-------------------+

lwip 1.4的驅動架構和1.32相比并沒有太大的變化,不過細節方面有所改動,各個模塊之間功能劃分更明確:

1、驅動部分

驅動的輸入只有一個入口,就是isr。isr接收到各種中斷以后做相應的處理,包括接收到rx包,鏈路層通斷

消息等,然后調用ethernetif.h頭文件中的各個函數來通知netif層。

驅動的另一個主要需要實現的部分是rx和tx這兩個回調函數,它是提供給ethernetif來進行鏈路層數據收發使用。

rx函數一般會被netif中的rx線程調用,然后將數據包轉發給tcpip層。

tx函數有可能被netif中的tx線程調用(lwip1.32的實現)或者直接被tcpip的enetif_linkoutput調用,來進行鏈路層

發送數據包使用。

2、ethernetif

ethernetif輸入部分包含一個線程,用來接收rx消息,以及其他鏈路層狀態消息,然后反饋給lwip。

輸出部分由上層lwip調入netif→output函數,這里有可能作為消息傳入tx線程(1.32實現)或者直接送給驅動的tx()。

3、LwIP1.4

lwip1.4 初始化流程和1.32的流程方面有所區別,具體參見下一節。

二、lwip,netif架構 初始化流程

初始化的過程包括兩個獨立的部分:驅動初始化、lwip和netif的初始化。

例如在mini2440平臺上只需要分別執行連個函數即可:

rt_hw_dm9000_init();

lwip_enetif_init();

驅動的初始化可以放在啟動第一個進程之前進行,而第二個函數需要在線程上下文中執行。

1、驅動初始化部分

a.創建eth_device的繼承結構。

b.初始化eth_device中除了netif以外的所有域(netif結構會在ethernetif初始化結束以后填充)。

c.調用rt_device_register注冊結構體。

d.注冊中斷函數。

完成這幾件事情以后可能驅動部分就已經開始工作了,但是這時候lwip部分還完全沒有初始化。

所以驅動部分還不能把消息傳遞給lwip/netif層。在這里因為eth_device的netif指針仍沒有填充,

而這個指針是驅動通向netif的橋梁,所以雖然此時驅動在工作,例如可能接收中斷已經打開了,

但是所有的包都會被丟棄,而不會傳遞到lwip去處理。

2、lwip和netif的初始化部分

lwip初始化需要遵循一定的流程,主函數是lwip_enetif_init。

在RTOS的環境下需要調用tcpip_init來初始化多線程的tcpip環境,初始化tcpip的內容就放在這個

函數的參數中tcpip_init_done_callback。之所以需要把這些函數都放在這個callback函數中的緣故

是很多函數都必須在tcpip線程中執行,以避免并發問題,例如netif_set_up之類的函數。

在tcpip_init_done_callback中初始化了ethernetif并注冊到lwip中,以上這一部分一般來說應該是應

用相關的,這里只是提供一個公共的參考流程。

在初始化的最后,enetif_init函數中先將netif→linkoutput設置成了設備驅動對應的函數,在這一點

的時候實現了從netif到驅動的連接,然后又設置了dev→netif指針,于是從驅動到netif的連接也完成

了,到此為止lwip初始化完成。 有幾點需要注意的:

a.在啟動ethernetif的時候如果是啟用了DHCP則應該調用dhcp_start,

如果啟用AUTOIP則是autoip_start,否則調用netif_set_up。

b.包括像netif_set_up,dhcp_start之類的函數,凡是在tcpip線程以外調用的時候都需要以msg發送

給tcpip線程執行的形式來執行以避免并行問題。例如,可以使用netifapi_dhcp_start替代dhcp_start,

用netifapi_netif_set_up替代netif_set_up。

但是在tcpip線程中不能調用這類函數,否則肯定會進入信號堵塞。

三、從lwip1.32升級

從lwip1.32升級到lwip1.4主要需要修改的地方有下面三個:

1、驅動修改

以dm9000的驅動為例,需要將eth_device_ready函數換成eth_rx_ready,這主要是一個語義上的改動。

同樣,驅動還可以通過調用eth_linkup,eth_linkdown之類的函數來通知netif相應的狀態消息。

-? ?? ???eth_device_ready(&(dm9000_device.parent));

+? ?? ???eth_rx_ready(&(dm9000_device.parent));

在驅動初始化函數中,原先的eth_device_init需要刪除,然后添加初始化和注冊設備驅動函數。

-? ?? ???eth_device_init(&(dm9000_device.parent), "e0");

+? ?? ???dm9000_device.parent.parent.type = RT_Device_Class_NetIf;

+? ?? ???rt_device_register(&(dm9000_device.parent.parent), "eth0", RT_DEVICE_FLAG_RDWR);

最后,添加一個函數get_eth_dev,這個函數是在ethernetif最后被lwip初始化的時候獲得設備指

針用的。對ethernetif來說必須有一個驅動與之對應,在邏輯上netif并不是驅動的一部分,而是

注冊在lwip中的一部分,它必須由lwip來初始化,由lwip來使用。

+struct eth_device * get_eth_dev(void)

+{

+? ?? ???return (struct eth_device *)&dm9000_device;

+}

2、啟動調用

目前的啟動調用流程邏輯很清楚,按順序調用下面兩個函數即可。

rt_hw_dm9000_init();??//初始化設備驅動

lwip_enetif_init();? ?//初始化lwip,并間接初始化ethnetif,最后完成ethernetif和驅動的連接。

而原先的

lwip_sys_init(void);

eth_system_device_init();

rt_hw_dm9000_init();

只有第三個函數保留,但功能上會有變化,其余兩個函數不再使用。

四、lwip netconn 函數修改

lwip1.4修改了netconn調用接口,所有函數統一返回錯誤值,例如: lwip1.32中recv函數是

struct netbuf *

netconn_recv(struct netconn *conn)

到了lwip1.4中改為

err_t

netconn_recv(struct netconn *conn, struct netbuf **new_buf)

原先以返回值得到的netbuf改成通過參數返回,其他函數大同小異,可以此類推。

總結

以上是生活随笔為你收集整理的rtthread工业使用_基于RTThread 的LwIP使用讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。