1.LWIP介紹
lwip是瑞典計算機科學院網絡嵌入式系統小組(SICS)的Adam Dunkels(亞當·鄧克爾) 開發的一個小型開源的TCP/IP協議棧。實現的重點是在保持 TCP 協議主要功能的基礎上減少對RAM的占用。
LwIP是Light Weight(輕型)IP 協議,有無操作系統的支持都可以運行。LwIP 實現的重點是在保持TCP協議 主要功能的基礎上減少對RAM的占用,它只需十幾KB的RAM和 40K左右的ROM就可以運行,這使LwIP協議棧適合在低端的嵌入式系統中使用。lwip提供三種API:
- RAW API
- (NETCONN)lwip API
- BSD API
2.LWIP源碼下載
源碼下載地址:LWIP源碼
3 LWIP源碼移植
??這里以1.4.1為例。
?1.解壓文件
2.打開已完成DM9000驅動的工程,在工程中創建lwip文件夾,在lwip文件夾中創建src文件夾和lwip1.4_config文件夾:
?3.將lwip-1.4.1源碼中的src中所有文件復制到用戶創建的src中:
4.復制contrib中文件
5.刪除不必要文件
?6.打開工程,添加.c文件到工程中
7.添加.h文件路徑
8.編譯工程
9.修改sys_arch.c文件,只保留下面函數,其它全部刪除。
10.修改lwipopts.h文件
11.修改ethernetif.c文件
4.LWIP協議棧使用示例之 — 獲取動態IP
??在LWIP_confg目錄下創建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);//網卡初始化函數,原型在ethernetif.c中
extern void ethernetif_input(struct netif *netif);
/**************LWIP協議棧初始化***********/
struct netif lwip_netif; //結構體原型在lwip/netif.h中
void LWIP_Config_Init(void)
{
ip_addr_t ip_addr={0};//IP地址
ip_addr_t netmask={0};//子網掩碼
ip_addr_t gw={0};//網關
/*靜態分配IP*/
// IP4_ADDR(&ip_addr,192,168,12,23);//設置靜態IP
// IP4_ADDR(&netmask,255,255,255,0);//子網掩碼
// IP4_ADDR(&netmask,192,168,12,1);//網關
/*1.LWIP協議棧初始化*/
lwip_init();
/*2.添加新的網卡設備到LWIP協議棧中*/
/*err_t ethernet_input(struct pbuf *p, struct netif *netif)處理已經讀取從硬件接口發來的一個數據包*/
netif_add(&lwip_netif,&ip_addr,&netmask,&gw,NULL,ethernetif_init,ethernet_input);
/*3.設置網卡為LWIP協議棧默認設備*/
netif_set_default(&lwip_netif);
/*4.注冊網卡設備為默認接口*/
netif_set_up(&lwip_netif);
/*5.動態分配IP*/
dhcp_start(&lwip_netif);
}
/*****DHCP定期數據處理函數(輪詢方式實現數據更新)****/
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(); //對 TCP 數據進行解析
}
/*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 請求,判斷 IP 地址是否獲取成功
}
/*60S 更新一次*/
if(LWIP_UPDATE_DHCP_TIME_CNT>=DHCP_COARSE_TIMER_MSECS)
{
LWIP_UPDATE_DHCP_TIME_CNT=0;
dhcp_coarse_tmr(); //更新檢查 DHCP 的租約時間
}
ethernetif_input(&lwip_netif); //讀取網卡的數據進行上報
if(lwip_dhcp_stat==0)
{
LWIP_GetDHCP_Addr();
}
}
/******獲取動態分配的IP地址*************/
void LWIP_GetDHCP_Addr(void)
{
char buff[200];
u32 ip_addr;//IP地址
u32 netmask;//子網掩碼
u32 gw;//網關
ip_addr=lwip_netif.ip_addr.addr;//IP地址
netmask=lwip_netif.netmask.addr;//子網掩碼
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("子網掩碼:%d.%d.%d.%drn",(netmask>>0)&0xff,(netmask>>8)&0xff,(netmask>>16)&0xff,(netmask>>24)&0xff);
snprintf(buff,sizeof(buff),"子網掩碼:%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);//子網掩碼
printf("網關:%d.%d.%d.%drn",(gw>>0)&0xff,(gw>>8)&0xff,(gw>>16)&0xff,(gw>>24)&0xff);
snprintf(buff,sizeof(buff),"網關:%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);//子網掩碼
}
}
5.主函數
#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,"網卡信息");//顯示字符串
stat=DM9000_Get_SpeedAndDuplex();//獲取連接狀態和工作方式
if(stat!=0xff)
{
printf("網卡速度:%d Mbps 模式:%srn",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
snprintf(buff,sizeof(buff),"網卡速度:%d MHZt %s",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
LCD_ShowStr(30,30+20*3,16,(u8 *)buff);//網卡速度
}
else
{
printf("DM9000網卡狀態信息獲取失敗!rn");
LCD_ShowStr(30,30+20*3,16,(u8 *)"獲取網卡信息失敗!");//網卡速度
}
LWIP_Config_Init();//LWIP協議棧初始化
TIMx_Init(TIM6,72,1000);
TIM6->CR1|=1<<0;
while(1)
{
LWIP_DataUpdata();
}
}
6.運行效果
-
STM32
+關注
關注
2270文章
10895瀏覽量
355729 -
TCP
+關注
關注
8文章
1353瀏覽量
79055 -
DHCP
+關注
關注
0文章
104瀏覽量
19702 -
DM9000
+關注
關注
0文章
24瀏覽量
16887 -
LwIP
+關注
關注
2文章
86瀏覽量
27149
發布評論請先 登錄
相關推薦
評論