本文轉(zhuǎn)自公眾號歡迎關(guān)注
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-無OS環(huán)境移植LWIP (qq.com)
https://mp.weixin.qq.com/s/u1Bv6s_oh7jZ3sjS3nxbEA
一.前言
前面我們實現(xiàn)了數(shù)據(jù)的收發(fā),現(xiàn)在我們就可以移植協(xié)議棧了。LWIP是一個適合嵌入式平臺的著名的輕量級協(xié)議棧,我們這一篇就來無OS環(huán)境移植LWIP,下一篇再基于RTOS移植LWIP。
二.源碼
LWIP官網(wǎng)如下
https://savannah.nongnu.org/projects/lwip/
下載源碼git clone https://git.savannah.nongnu.org/git/lwip.git
LWIP的代碼可移植性非常好src下的源碼完全可移植不需要任何修改,移植參考contribports下的模板即可,已經(jīng)有了unix,freertos,win32的移植可參考。
三.NONEOS移植
3.1添加文件
將src復(fù)制到自己的工程路徑
然后添加一個port文件夾和src并列,無OS移植就添加一個noneos子目錄。
.
其中port如下,相關(guān)的文件可以從其他port下復(fù)制過來修改。
ports/
添加源文件
將src文件夾復(fù)制到自己的工程,添加源碼
src/api下所有c
src/core下所有c
src/core/ipv4下所有c
src/core/ipv6下所有c
src/netif/ethernet.c,netif下還有其他很多接口實現(xiàn),用到可以使用對應(yīng)的,我們這里只需要使用ethernet.c
頭文件路徑
將目錄src/include,ports/noneos/include添加到頭文件包含路徑。
3.2 移植文件
修改修改的文件
Ports下文件是需要修改的
ports/
lwipopts.h
配置文件,使用宏對LWIP進(jìn)行配置。
Cc.h
必須位于arch目錄下
Perf.h/perf.c
portethif.h/portethif.c
sys_arch.c
錯誤碼
lwipopts.h中定義#define LWIP_PROVIDE_ERRNO 1則
src/include/lwip/errno.h中定義錯誤編碼和變量errno。
(我們這里使用該方式)
否則cc.h中需要include 或者自己實現(xiàn)錯誤碼宏定義和errno變量。
src/include/lwip/errno.h中可知,如果已經(jīng)有了對應(yīng)的頭文件則
可以定義LWIP_ERRNO_STDINCLUDE則自動#include
否則錯誤頭文件由LWIP_ERRNO_INCLUDE定義。
隨機數(shù)產(chǎn)生接口
如果有stdint.h則直接使用庫函數(shù),否則自行實現(xiàn)
Cc.h中
#include
extern unsigned int lwip_port_rand(void);
#define LWIP_RAND() (lwip_port_rand())
portethif.c中實現(xiàn)
#include
uint32_t lwip_port_rand(void)
{
return (uint32_t)rand();
}
斷言
不使用斷言,Cc.h中定義
#define LWIP_NOASSERT 1
如果定義了LWIP_NOASSERT則LWIP_ASSERT為空
如果使用斷言,沒有定義LWIP_NOASSERT
則src/lib/lwip/lwip/src/include/lwip/debug.h中
#define LWIP_ASSERT(message, assertion) do { if (!(assertion)) {
LWIP_PLATFORM_ASSERT(message); }} while(0)
此時需要實現(xiàn)LWIP_PLATFORM_ASSERT宏,
如果沒有定義LWIP_PLATFORM_ASSERT宏則默認(rèn)使用printf
則src/lib/lwip/lwip/src/include/lwip/arch.h中
#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion "%s" failed at line %d in %sn",
x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
atoi
Stdlib.h中有實現(xiàn),如果沒有該庫可以如下源碼實現(xiàn)
/*----------------------------------------------*/
lwip/ports/noneos/sys_arch.c下實現(xiàn)
u32_t sys_now(void)返回mS的全局時間。
存儲管理
lwip/ports/noneos/include/lwipopts.h中配置
堆管理
LWIP_RAM_HEAP_POINTER定義堆地址,必須要空間足夠大。
未定義則mem.c中定義大數(shù)組ram_heap
MEM_ALIGNMENT設(shè)置堆對齊
MEM_SIZE設(shè)置堆字節(jié)大小
lwip_init->mem_init時初始化,代碼位于mem.c
內(nèi)存池
pbuf.c調(diào)用memp.的接口
lwip_init->memp_init時初始化,代碼位于memp.c
lwip/priv/memp_priv.h中定義各個組件需要的內(nèi)存池
lwip/ports/noneos/include/lwipopts.h中MEMP_NUM_xxx定義大小。
性能測試接口
lwipopts.h中如果配置LWIP_PERF宏則
arch/perf.h需要實現(xiàn)兩個宏
PERF_START
PERF_STOP
在perf.c/perf.h中具體實現(xiàn)
否則這兩個宏自動置空。
一個參考實現(xiàn)如下
Perf.h
#ifndef LWIP_ARCH_PERF_H
perf.c
#include
可以看到指定接口執(zhí)行時間打印如下
系統(tǒng)層接口
無OS時不需要實現(xiàn)相關(guān)接口
src/lib/lwip/ports/noneos/include/lwipopts.h中
#define NO_SYS 1
NO_SYS=1時不能使用socket相關(guān)接口
#define LWIP_NETCONN 0
#define LWIP_SOCKET 0
以太網(wǎng)收發(fā)接口相關(guān)
實現(xiàn)以下幾個函數(shù)即可
實現(xiàn)初始化函數(shù)lwip_port_eth_init
在netif_add(&netif, (const ip_addr_t *)&ipaddr, (const ip_addr_t *)&netmask, (const ip_addr_t *)&gw, NULL, &lwip_port_eth_init, eernet_input);時調(diào)用執(zhí)行l(wèi)wip_port_eth_init
實現(xiàn)low_level_output,在執(zhí)行l(wèi)wip_port_eth_init時綁定到回調(diào)函數(shù)
netif->linkoutput = low_level_output;
收到一包數(shù)據(jù)時調(diào)用
lwip_port_eth_input
Portethif.h
#ifndef LWIP_TAPIF_H
Portethif.c
#include
四.測試
以下忽略了平臺相關(guān)的操作,比如以太網(wǎng)驅(qū)動初始化等,僅保留lwip相關(guān)內(nèi)容。
#include "lwip/netif.h"
收到包時調(diào)用
lwip_port_eth_input(&netif, p_data, len);
初始化與主循環(huán)
/* 在PHY初始化后,尤其是RXC輸出之后才調(diào)用,因為GMAC復(fù)位需要RXC */
使用網(wǎng)口調(diào)試工具,發(fā)送數(shù)據(jù)收到后原樣返回。
五.總結(jié)
LWIP代碼移植性非常好,無OS支持也非常好,移植只需要實現(xiàn)平臺相關(guān)的配置和宏,實現(xiàn)網(wǎng)口收發(fā)接口即可。
審核編輯 黃宇
-
以太網(wǎng)
+關(guān)注
關(guān)注
40文章
5460瀏覽量
172709 -
LwIP
+關(guān)注
關(guān)注
2文章
88瀏覽量
27359 -
驅(qū)動開發(fā)
+關(guān)注
關(guān)注
0文章
130瀏覽量
12106
發(fā)布評論請先 登錄
相關(guān)推薦
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-MAC幀格式介紹
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-MAC幀格式介紹](https://file1.elecfans.com//web2/M00/A0/61/wKgZomTtSJaABjpaAALBTTqyRbY287.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-MDIO驅(qū)動編寫與測試
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-MDIO<b class='flag-5'>驅(qū)動</b>編寫與測試](https://file1.elecfans.com/web2/M00/A0/C8/wKgZomTunOeAY-b0AACkJcvFr6E062.jpg)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-描述符鏈表介紹
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-描述符鏈表介紹](https://file1.elecfans.com/web2/M00/A0/C9/wKgZomTunYKAeNxaAAC6LPl4TyY517.jpg)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-數(shù)據(jù)流驗證過程
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-數(shù)據(jù)流驗證過程](https://file1.elecfans.com//web2/M00/A2/63/wKgaomTv7TmARPccAAB715-4tFs084.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-收發(fā)驅(qū)動編寫與調(diào)試
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-收發(fā)<b class='flag-5'>驅(qū)動</b>編寫與調(diào)試](https://file1.elecfans.com//web2/M00/A3/03/wKgaomT2hgmADaIUAABCBsgW8uA618.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的內(nèi)存池介紹
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的內(nèi)存池介紹](https://file1.elecfans.com//web2/M00/A3/58/wKgaomT5Jw6AbNkLAAPYEkmgmX8781.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的堆管理介紹
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的堆管理介紹](https://file1.elecfans.com//web2/M00/A3/84/wKgaomT6e8mAOc3CAABfv0oF-p8552.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的堆(內(nèi)存池)未對齊導(dǎo)致問題的案例分享
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的堆(內(nèi)存池)未對齊導(dǎo)致問題的案例分享](https://file1.elecfans.com//web2/M00/A2/56/wKgZomT8eX6AMEQ-AABzY0VnW3o925.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-RTOS環(huán)境移植LWIP與性能測試
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-RTOS<b class='flag-5'>環(huán)境</b><b class='flag-5'>移植</b><b class='flag-5'>LWIP</b>與性能測試](https://file1.elecfans.com//web2/M00/A2/5E/wKgZomT9Ts-ATRWJAADLKvIGyzM770.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP在PC上進(jìn)行開發(fā)調(diào)試
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>在PC上進(jìn)行<b class='flag-5'>開發(fā)</b>調(diào)試](https://file1.elecfans.com//web2/M00/A3/CB/wKgaomT-a4eASU5pAAN8tVb5SkU139.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的定時器模塊詳解
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的定時器模塊詳解](https://file1.elecfans.com/web2/M00/A3/86/wKgZomUHqJGABbQlAABLKy467rY277.jpg)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的ARP模塊介紹
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的ARP模塊介紹](https://file1.elecfans.com/web2/M00/A4/F1/wKgaomUHqQyAReY7AACPaMWkHrQ113.jpg)
設(shè)計軟件核心以太網(wǎng)服務(wù)質(zhì)量數(shù)據(jù)手冊免費下載
![設(shè)計軟件核心<b class='flag-5'>以太網(wǎng)</b>服務(wù)質(zhì)量數(shù)據(jù)手冊免費下載](https://file.elecfans.com/web1/M00/AB/25/pIYBAF2vx2yAFK0UAAC_559CBf4816.png)
基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-包過濾
![基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-包過濾](https://file1.elecfans.com/web2/M00/A2/BE/wKgaomTyiFmAEDEkAAEeA1jXwxY649.jpg)
評論