1.LWIP介紹
lwip是瑞典計(jì)算機(jī)科學(xué)院網(wǎng)絡(luò)嵌入式系統(tǒng)小組(SICS)的Adam Dunkels(亞當(dāng)·鄧克爾) 開發(fā)的一個(gè)小型開源的TCP/IP協(xié)議棧。實(shí)現(xiàn)的重點(diǎn)是在保持 TCP 協(xié)議主要功能的基礎(chǔ)上減少對(duì)RAM的占用。
LwIP是Light Weight(輕型)IP 協(xié)議,有無(wú)操作系統(tǒng)的支持都可以運(yùn)行。LwIP 實(shí)現(xiàn)的重點(diǎn)是在保持TCP協(xié)議 主要功能的基礎(chǔ)上減少對(duì)RAM的占用,它只需十幾KB的RAM和 40K左右的ROM就可以運(yùn)行,這使LwIP協(xié)議棧適合在低端的嵌入式系統(tǒng)中使用。lwip提供三種API:
- RAW API
- (NETCONN)lwip API
- BSD API
2.LWIP源碼下載
源碼下載地址:LWIP源碼
3 LWIP源碼移植
??這里以1.4.1為例。
?1.解壓文件
2.打開已完成DM9000驅(qū)動(dòng)的工程,在工程中創(chuàng)建lwip文件夾,在lwip文件夾中創(chuàng)建src文件夾和lwip1.4_config文件夾:
?3.將lwip-1.4.1源碼中的src中所有文件復(fù)制到用戶創(chuàng)建的src中:
4.復(fù)制contrib中文件
5.刪除不必要文件
?6.打開工程,添加.c文件到工程中
7.添加.h文件路徑
8.編譯工程
9.修改sys_arch.c文件,只保留下面函數(shù),其它全部刪除。
10.修改lwipopts.h文件
11.修改ethernetif.c文件
4.LWIP協(xié)議棧使用示例之 — 獲取動(dòng)態(tài)IP
??在LWIP_confg目錄下創(chuàng)建lwip_config.c和lwip_config.h文件
??lwip_config.c文件:
#include "lwip_config.h"
#include "lwip/ip_addr.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/tcp_impl.h"
extern err_t ethernetif_init(struct netif *netif);//網(wǎng)卡初始化函數(shù),原型在ethernetif.c中
extern void ethernetif_input(struct netif *netif);
/**************LWIP協(xié)議棧初始化***********/
struct netif lwip_netif; //結(jié)構(gòu)體原型在lwip/netif.h中
void LWIP_Config_Init(void)
{
ip_addr_t ip_addr={0};//IP地址
ip_addr_t netmask={0};//子網(wǎng)掩碼
ip_addr_t gw={0};//網(wǎng)關(guān)
/*靜態(tài)分配IP*/
// IP4_ADDR(&ip_addr,192,168,12,23);//設(shè)置靜態(tài)IP
// IP4_ADDR(&netmask,255,255,255,0);//子網(wǎng)掩碼
// IP4_ADDR(&netmask,192,168,12,1);//網(wǎng)關(guān)
/*1.LWIP協(xié)議棧初始化*/
lwip_init();
/*2.添加新的網(wǎng)卡設(shè)備到LWIP協(xié)議棧中*/
/*err_t ethernet_input(struct pbuf *p, struct netif *netif)處理已經(jīng)讀取從硬件接口發(fā)來(lái)的一個(gè)數(shù)據(jù)包*/
netif_add(&lwip_netif,&ip_addr,&netmask,&gw,NULL,ethernetif_init,ethernet_input);
/*3.設(shè)置網(wǎng)卡為L(zhǎng)WIP協(xié)議棧默認(rèn)設(shè)備*/
netif_set_default(&lwip_netif);
/*4.注冊(cè)網(wǎng)卡設(shè)備為默認(rèn)接口*/
netif_set_up(&lwip_netif);
/*5.動(dòng)態(tài)分配IP*/
dhcp_start(&lwip_netif);
}
/*****DHCP定期數(shù)據(jù)處理函數(shù)(輪詢方式實(shí)現(xiàn)數(shù)據(jù)更新)****/
u32 LWIP_TCP_TIME_CNT=0;
u32 LWIP_ARP_TIME_CNT=0;
u32 LWIP_DHCP_TIME_CNT=0;
u32 LWIP_UPDATE_DHCP_TIME_CNT=0;
u8 lwip_dhcp_stat=0;
void LWIP_DataUpdata(void)
{
/*250MS 更新一次*/
if(LWIP_TCP_TIME_CNT>=TCP_TMR_INTERVAL)
{
LWIP_TCP_TIME_CNT=0;
tcp_tmr(); //對(duì) TCP 數(shù)據(jù)進(jìn)行解析
}
/*5000ms 更新一次*/
if(LWIP_ARP_TIME_CNT>=ARP_TMR_INTERVAL)
{
LWIP_ARP_TIME_CNT=0;
etharp_tmr();//清理 ARP 緩存表
}
//500ms獲取一次
if(LWIP_DHCP_TIME_CNT>=DHCP_FINE_TIMER_MSECS )
{
LWIP_DHCP_TIME_CNT=0;
dhcp_fine_tmr(); //解析 DHCP 請(qǐng)求,判斷 IP 地址是否獲取成功
}
/*60S 更新一次*/
if(LWIP_UPDATE_DHCP_TIME_CNT>=DHCP_COARSE_TIMER_MSECS)
{
LWIP_UPDATE_DHCP_TIME_CNT=0;
dhcp_coarse_tmr(); //更新檢查 DHCP 的租約時(shí)間
}
ethernetif_input(&lwip_netif); //讀取網(wǎng)卡的數(shù)據(jù)進(jìn)行上報(bào)
if(lwip_dhcp_stat==0)
{
LWIP_GetDHCP_Addr();
}
}
/******獲取動(dòng)態(tài)分配的IP地址*************/
void LWIP_GetDHCP_Addr(void)
{
char buff[200];
u32 ip_addr;//IP地址
u32 netmask;//子網(wǎng)掩碼
u32 gw;//網(wǎng)關(guān)
ip_addr=lwip_netif.ip_addr.addr;//IP地址
netmask=lwip_netif.netmask.addr;//子網(wǎng)掩碼
gw=lwip_netif.gw.addr;
if(ip_addr!=0)
{
lwip_dhcp_stat=1;//成功獲取到IP地址
printf("IP地址:%d.%d.%d.%drn",(ip_addr>>0)&0xff,(ip_addr>>8)&0xff,(ip_addr>>16)&0xff,(ip_addr>>24)&0xff);
snprintf(buff,sizeof(buff),"IP地址:%d.%d.%d.%d",(ip_addr>>0)&0xff,(ip_addr>>8)&0xff,(ip_addr>>16)&0xff,(ip_addr>>24)&0xff);
LCD_ShowStr(30,30+20*4,16,(u8 *)buff);//IP地址
printf("子網(wǎng)掩碼:%d.%d.%d.%drn",(netmask>>0)&0xff,(netmask>>8)&0xff,(netmask>>16)&0xff,(netmask>>24)&0xff);
snprintf(buff,sizeof(buff),"子網(wǎng)掩碼:%d.%d.%d.%drn",(netmask>>0)&0xff,(netmask>>8)&0xff,(netmask>>16)&0xff,(netmask>>24)&0xff);
LCD_ShowStr(30,30+20*5,16,(u8 *)buff);//子網(wǎng)掩碼
printf("網(wǎng)關(guān):%d.%d.%d.%drn",(gw>>0)&0xff,(gw>>8)&0xff,(gw>>16)&0xff,(gw>>24)&0xff);
snprintf(buff,sizeof(buff),"網(wǎng)關(guān):%d.%d.%d.%drn",(gw>>0)&0xff,(gw>>8)&0xff,(gw>>16)&0xff,(gw>>24)&0xff);
LCD_ShowStr(30,30+20*6,16,(u8 *)buff);//子網(wǎng)掩碼
}
}
5.主函數(shù)
#include "dm9000.h"
#include "lwip_config.h"
u8 dm9000_tx_buff[64]={0x11,0x22,0x33,0x44,0x55};
u8 dm9000_rx_buff[1024];
int main()
{
char buff[200];
u8 stat;
Beep_Init();
Led_Init();
Key_Init();
W25Q64_Init();
Usartx_Init(USART1,115200,72);
TIMx_Init(TIM2,72,20*1000);
IIC_Init();
printf("初始化完成rn");
NT35310_Init();
/*DM9000初始化*/
LCD_ShowStr(30,30,16,"DM9000初始化中。。。");//顯示字符串
if(DM9000_Init()==0)
{
printf("DM9000初始化成功rn");
LCD_ShowStr(30,30+20,16,"DM9000t OK!");//顯示字符串
}
else
{
printf("DM9000初始化失敗rn");
LCD_ShowStr(30,30+20,16,"DM9000t ERR!");//顯示字符串
}
/*獲取DM9000工作模式*/
LCD_ShowStr(128,30+20*2,16,"網(wǎng)卡信息");//顯示字符串
stat=DM9000_Get_SpeedAndDuplex();//獲取連接狀態(tài)和工作方式
if(stat!=0xff)
{
printf("網(wǎng)卡速度:%d Mbps 模式:%srn",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
snprintf(buff,sizeof(buff),"網(wǎng)卡速度:%d MHZt %s",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
LCD_ShowStr(30,30+20*3,16,(u8 *)buff);//網(wǎng)卡速度
}
else
{
printf("DM9000網(wǎng)卡狀態(tài)信息獲取失敗!rn");
LCD_ShowStr(30,30+20*3,16,(u8 *)"獲取網(wǎng)卡信息失敗!");//網(wǎng)卡速度
}
LWIP_Config_Init();//LWIP協(xié)議棧初始化
TIMx_Init(TIM6,72,1000);
TIM6->CR1|=1<<0;
while(1)
{
LWIP_DataUpdata();
}
}
6.運(yùn)行效果
-
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
355985 -
TCP
+關(guān)注
關(guān)注
8文章
1353瀏覽量
79070 -
DHCP
+關(guān)注
關(guān)注
0文章
105瀏覽量
19716 -
DM9000
+關(guān)注
關(guān)注
0文章
24瀏覽量
16895 -
LwIP
+關(guān)注
關(guān)注
2文章
86瀏覽量
27169
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論