LWIP--无操作系统移植笔记

6 篇文章 1 订阅
5 篇文章 1 订阅

移植项目使用的是正点原子战舰V3开发板,网卡采用DM9000,DM9000属于链路层(PHY层+MAC层);LWIP属于互联层传输层应用层就是用户自己根据自己想要的功能实现,例如MQTT协议、HTTP协议等。

运行LWIP需要十几KB的RAM40K左右的ROM

移植第一步:将LwIP添加到裸机工程

打开lwip-2.1.2   LWIP官网下载:lwIP - A Lightweight TCP/IP stack - Summary [Savannah]http://savannah.nongnu.org/projects/lwip/

将LWIP的src移植到工程文件中

 src重命名LWIP

 添加api core netif文件夹到工程文件中

 添加图中.C文件到API中

  添加图中.C文件到core中

 添加图中.C文件到netif中

在工程添加头文件

 

移植第二步:移植头文件

在工程添加头文件 lwipopts.h、cc.h、pref.h  

打开LwIP的contrib包

在contrib-2.1.0\examples\example_app 找到lwipopts.h

contrib-2.1.0\ports\unix\port\include\arch找到cc.h、pref.h

把3个头文件添加到arch文件夹里

打开lwipopts.h,并在文件内部写入修改以下配置

 #ifndef __LWIPOPTS_H__
 #define __LWIPOPTS_H__

 /**
 * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
 * critical regions during buffer allocation, deallocation and memory
 * allocation and deallocation.
 */
 #define SYS_LIGHTWEIGHT_PROT    0     //* SYS_LIGHTWEIGHT_PROT==1:如果你想要确定的跨任务保护 *在缓冲区分配,回收和内存的关键区域 *分配和回收。

 /**
 * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
 * use lwIP facilities.
 */
 #define NO_SYS                  1     //NO_SYS表示无操作系统模拟层,这个宏非常重要, 因为无操作系统与有操作系统的移植和编写是完全不一样的, 
                                        //我们现在是无操作系统移植,所以将这个宏定义为1。               
 /**
 * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1
 * Mainly for compatibility to old versions.
 */
 #define NO_SYS_NO_TIMERS        0    // NO_SYS_NO_TIMERS==1:当NO_SYS==1时,取消对sys_timeout的支持 *主要是为了兼容旧版本。

 /* ---------- Memory options ---------- */
 /* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
     lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
     byte alignment -> define MEM_ALIGNMENT to 2. */
 #define MEM_ALIGNMENT           4    //使用4字节对齐模式                

 /* MEM_SIZE: the size of the heap memory. If the application will send
 a lot of data that needs to be copied, this should be set high. */
 #define MEM_SIZE                (10*512)        //堆内存的大小。如果应用程序将发送很多需要复制的数据应该设置得大一点。     

 /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
     sends a lot of data out of ROM (or other static memory), this
     should be set high. */
 #define MEMP_NUM_PBUF           50    // MEMP_NUM_PBUF: memp结构pbuf的数量。如果应用程序从ROM(或其他静态内存)发送大量数据,这应该设得高一些。
 /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
     per active UDP "connection". */
 #define MEMP_NUM_UDP_PCB        6    //MEMP_NUM_UDP_PCB: UDP协议控制块的数量。一个每个活跃的UDP“连接”。
 /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
     connections. */
 #define MEMP_NUM_TCP_PCB        10   //TCP协议控制块的数量。一个每个活跃的tcp“连接”。
 /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
     connections. */
 #define MEMP_NUM_TCP_PCB_LISTEN 6   //正在监听的TCP数量连接。
 /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
     segments. */
 #define MEMP_NUM_TCP_SEG        12   //同时排队的TCP段数。
 /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
     timeouts. */
 #define MEMP_NUM_SYS_TIMEOUT    10   //同时活动的超时次数。

 /* ---------- Pbuf options ---------- */
 /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
 #define PBUF_POOL_SIZE          10      //PBUF_POOL内存池中内存块数量。            

 /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
 #define PBUF_POOL_BUFSIZE       500     //PBUF_POOL内存池中每个内存块大小。            

 /* ---------- TCP options ---------- */
 #define LWIP_TCP                1    //开启TCP
 #define TCP_TTL                 255  //TCP生存时间

 /* Controls if TCP should queue segments that arrive out of
     order. Define to 0 if your device is low on memory. */
 #define TCP_QUEUE_OOSEQ         0   //控制TCP是否应该对到达的段进行排队秩序。如果设备内存不足,则定义为0。

 /* TCP Maximum segment size. */
 #define TCP_MSS                 (1500 - 40)    //TCP协议报文最大长度。             

 /* TCP sender buffer space (bytes). */
 #define TCP_SND_BUF             (4*TCP_MSS)    //允许TCP协议使用的最大发送缓冲区空间(字节)。     

 /*  TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
 as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */

 #define TCP_SND_QUEUELEN        (2* TCP_SND_BUF/TCP_MSS)  //TCP发送端缓冲区空间(pbufs)。这一定是至少最多为(2 * TCP_SND_BUF/TCP_MSS)。

 /* TCP receive window. */
 #define TCP_WND                 (2*TCP_MSS)   //TCP接收窗口大小。      

 /* ---------- ICMP options ---------- */
 #define LWIP_ICMP                       1

 /* ---------- DHCP options ---------- */
 /* Define LWIP_DHCP to 1 if you want DHCP configuration of
 interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
 turning this on does currently not work. */
 #define LWIP_DHCP               1

 /* ---------- UDP options ---------- */
 #define LWIP_UDP                1
 #define UDP_TTL                 255

 /* ---------- Statistics options ---------- */  //统计功能
 #define LWIP_STATS 0  
 #define LWIP_PROVIDE_ERRNO 1

 /* ---------- link callback options ---------- */
 /* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
 * whenever the link changes (i.e., link down)
 */
 #define LWIP_NETIF_LINK_CALLBACK        0  //支持来自接口的回调函数当链接改变时(即链接向下)
 /*
     --------------------------------------
     ---------- Checksum options ----------
     --------------------------------------
 */

 /*The STM32F4x7 allows comput
 ing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
 - To use this feature let the following define uncommented.
 - To disable it and process by CPU comment the  the checksum. 
 */
// #define CHECKSUM_BY_HARDWARE

 #ifdef CHECKSUM_BY_HARDWARE  //硬件效验
 /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
 #define CHECKSUM_GEN_IP                 0
 /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
 #define CHECKSUM_GEN_UDP                0
 /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
 #define CHECKSUM_GEN_TCP                0
 /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
 #define CHECKSUM_CHECK_IP               0
 /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
 #define CHECKSUM_CHECK_UDP              0
 /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
 #define CHECKSUM_CHECK_TCP              0
 /*CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
 #define CHECKSUM_GEN_ICMP               0
 #else                      //软件效验
 /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
 #define CHECKSUM_GEN_IP                 1
 /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
 #define CHECKSUM_GEN_UDP                1
 /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
 #define CHECKSUM_GEN_TCP                1
 /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
 #define CHECKSUM_CHECK_IP               1
 /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
 #define CHECKSUM_CHECK_UDP              1
 /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
 #define CHECKSUM_CHECK_TCP              1
 /*CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/
 #define CHECKSUM_GEN_ICMP               1
 #endif

 /*
     ----------------------------------------------
     ---------- Sequential layer options ----------
     ----------------------------------------------
 */
 /**
 * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
 */
 #define LWIP_NETCONN                    0            //开启/关闭netconn功能

 /*
     ------------------------------------
     ---------- Socket options ----------
     ------------------------------------
 */
 /**
 * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
 */
 #define LWIP_SOCKET                     0            //开启/关闭socket功能

 /*
     ----------------------------------------
     ---------- Lwip Debug options ----------
     ----------------------------------------
 */
 //#define LWIP_DEBUG                      1

 #endif /* __LWIPOPTS_H__ */

 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 

打开cc.h,并在文件内部写入修改以下配置

 #ifndef __CC_H__
 #define __CC_H__

 #include "stdio.h"

 #include "main.h"

 #define LWIP_NO_STDINT_H  1

 typedef unsigned   char    u8_t;
 typedef signed     char    s8_t;
 typedef unsigned   short   u16_t;
 typedef signed     short   s16_t;
 typedef unsigned   long    u32_t;
 typedef signed     long    s32_t;
 typedef u32_t mem_ptr_t;
 typedef int sys_prot_t;


 #define U16_F "hu"
 #define S16_F "d"
 #define X16_F "hx"
 #define U32_F "u"
 #define S32_F "d"
 #define X32_F "x"
 #define SZT_F "uz"



 /* 选择小端模式 */
 #define BYTE_ORDER LITTLE_ENDIAN

 /* define compiler specific symbols */
 #if defined (__ICCARM__)

 #define PACK_STRUCT_BEGIN
 #define PACK_STRUCT_STRUCT
 #define PACK_STRUCT_END
 #define PACK_STRUCT_FIELD(x) x
 #define PACK_STRUCT_USE_INCLUDES

 #elif defined (__CC_ARM)

 #define PACK_STRUCT_BEGIN __packed
 #define PACK_STRUCT_STRUCT
 #define PACK_STRUCT_END
 #define PACK_STRUCT_FIELD(x) x

 #elif defined (__GNUC__)

 #define PACK_STRUCT_BEGIN
 #define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
 #define PACK_STRUCT_END
 #define PACK_STRUCT_FIELD(x) x

 #elif defined (__TASKING__)

 #define PACK_STRUCT_BEGIN
 #define PACK_STRUCT_STRUCT
 #define PACK_STRUCT_END
 #define PACK_STRUCT_FIELD(x) x

 #endif


 #define LWIP_PLATFORM_ASSERT(x) do {printf(x);}while(0)


 extern u32_t sys_now(void);

 #endif /* __CC_H__ */

打开perf.h,并在文件内部写入修改以下配置

 #ifndef __PERF_H__
 #define __PERF_H__

 #define PERF_START    /* null definition */
 #define PERF_STOP(x)  /* null definition */

 #endif /* __PERF_H__ */

移植第三步:移植网卡驱动

打开ethernetif.c移植网卡驱动  low_level_outputlow_level_input 这里是采用DM9000网卡的收发驱动,根据不同网卡的收发驱动直接换就可以用。

#include "ethernetif.h" 
#include "dm9000.h"  
#include "lwip_comm.h" 
  

#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/timeouts.h"
#include "netif/ethernet.h"
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include "ethernetif.h"
#include <string.h>

#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "netif/ppp/pppoe.h"

#define IFNAME0 'e'
#define IFNAME1 'n'


struct ethernetif {
  struct eth_addr *ethaddr;
  /* Add whatever per-interface state that is needed here. */
};

//由ethernetif_init()调用用于初始化硬件
//netif:网卡结构体指针 
//返回值:ERR_OK,正常
//       其他,失败
static void low_level_init(struct netif *netif)
{
	netif->hwaddr_len = ETHARP_HWADDR_LEN; //设置MAC地址长度,为6个字节
	//初始化MAC地址,设置什么地址由用户自己设置,但是不能与网络中其他设备MAC地址重复
	netif->hwaddr[0]=lwipdev.mac[0]; 
	netif->hwaddr[1]=lwipdev.mac[1]; 
	netif->hwaddr[2]=lwipdev.mac[2];
	netif->hwaddr[3]=lwipdev.mac[3];
	netif->hwaddr[4]=lwipdev.mac[4];
	netif->hwaddr[5]=lwipdev.mac[5];
	netif->mtu=1500; //最大允许传输单元,允许该网卡广播和ARP功能
	netif->flags = NETIF_FLAG_BROADCAST|NETIF_FLAG_ETHARP|NETIF_FLAG_LINK_UP;	
    
//    mymacinit(lwipdev.mac); // 调用自己实际的网卡初始化函数
    
} 
//用于发送数据包的最底层函数(lwip通过netif->linkoutput指向该函数)
//netif:网卡结构体指针
//p:pbuf数据结构体指针
//返回值:ERR_OK,发送正常
//       ERR_MEM,发送失败
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
	DM9000_SendPacket(p);
	return ERR_OK;
}  
///用于接收数据包的最底层函数
//neitif:网卡结构体指针
//返回值:pbuf数据结构体指针
static struct pbuf * low_level_input(struct netif *netif)
{  
	struct pbuf *p;
	p=DM9000_Receive_Packet();
	return p;
}
//网卡接收数据(lwip直接调用)
//netif:网卡结构体指针
//返回值:ERR_OK,发送正常
//       ERR_MEM,发送失败
void ethernetif_input(struct netif *netif)
{
	err_t err;
	struct pbuf *p;
	p=low_level_input(netif);   //调用low_level_input函数接收数据
	if(p!=NULL)
    {
        err=netif->input(p, netif); //调用netif结构体中的input字段(一个函数)来处理数据包
        if(err!=ERR_OK)
        {
            printf("1111\r\n");
            LWIP_DEBUGF(NETIF_DEBUG,("ethernetif_input: IP input error\n"));
            pbuf_free(p);
            p = NULL;
        } 
	}
} 
//使用low_level_init()函数来初始化网络
//netif:网卡结构体指针
//返回值:ERR_OK,正常
//       其他,失败
err_t ethernetif_init(struct netif *netif)
{
  struct ethernetif *ethernetif;

  LWIP_ASSERT("netif != NULL", (netif != NULL));

  ethernetif = mem_malloc(sizeof(struct ethernetif));
  if (ethernetif == NULL) {
    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
    printf("ethernetif_init: out of memory\r\n");
    return ERR_MEM;
  }

#if LWIP_NETIF_HOSTNAME
  /* Initialize interface hostname */
  netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */

  /*
   * Initialize the snmp variables and counters inside the struct netif.
   * The last argument should be replaced with your link speed, in units
   * of bits per second.
   */
  // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);

  netif->state = ethernetif;
  netif->name[0] = IFNAME0;
  netif->name[1] = IFNAME1;
  /* We directly use etharp_output() here to save a function call.
   * You can instead declare your own function an call etharp_output()
   * from it if you have to do some checks before sending (e.g. if link
   * is available...) */
#if LWIP_IPV4
  netif->output = etharp_output;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
  netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
  netif->linkoutput = low_level_output;

  ethernetif->ethaddr = (struct eth_addr *) & (netif->hwaddr[0]);

  /* initialize the hardware */
  low_level_init(netif);

  return ERR_OK;
}









我们还需要一个ethernetif.h文件,主要是对函数的一些声明

 #ifndef __ETHERNETIF_H__
 #define __ETHERNETIF_H__

 #include "lwip/err.h"
 #include "lwip/netif.h"

 err_t ethernetif_init(struct netif *netif);

 void ethernetif_input(struct netif *netif);
 void ethernetif_update_config(struct netif *netif);
 void ethernetif_notify_conn_changed(struct netif *netif);

 #endif

移植第四步:LWIP时基    

一般我们在STM32中,一般采用SysTick作为LwIP的时基定时器,将SysTick产生中断的频率设置为1000HZ,也就是1ms触发一次中断,每次产生中断的时候,系统变量就会加1。

而我是使用(10ms定时器3) 每10ms加10,sys_now()函数中直接返回lwip_localtime值

//为LWIP提供计时
extern uint32_t lwip_localtime;//lwip本地时间计数器,单位:ms

u32_t sys_now(void)
    {
        return lwip_localtime;
    }
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
	{
		lwip_localtime +=10; //加10
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

移植第五步:协议栈初始化 

#include "lwip_comm.h" 
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/init.h"
#include "ethernetif.h" 
//#include "lwip/timers.h"
//#include "lwip/tcp_impl.h"
//#include "lwip/ip_frag.h"
#include "lwip/tcpip.h" 
#include "delay.h"
#include "usart.h"  
#include <stdio.h>
#include "lwip/ip_addr.h"
//	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK 战舰开发板 V3
//lwip通用驱动 代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2015/3/15
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved									  
//*******************************************************************************
//修改信息
//无
// 	   
   
__lwip_dev lwipdev;						//lwip控制结构体 
struct netif lwip_netif;				//定义一个全局的网络接口

extern u32 memp_get_memorysize(void);	//在memp.c里面定义
extern u8_t *memp_memory;				//在memp.c里面定义.
extern u8_t *ram_heap;					//在mem.c里面定义.

u32 TCPTimer=0;			//TCP查询计时器
u32 ARPTimer=0;			//ARP查询计时器
u32 lwip_localtime;		//lwip本地时间计数器,单位:ms


//lwip中mem和memp的内存申请
//返回值:0,成功;
//    其他,失败


//lwip 默认IP设置
//lwipx:lwip控制结构体指针
void lwip_comm_default_ip_set(__lwip_dev *lwipx)
{
	//默认远端IP为:192.168.1.100
	lwipx->remoteip[0]=192;	
	lwipx->remoteip[1]=168;
	lwipx->remoteip[2]=1;
	lwipx->remoteip[3]=100;
	//MAC地址设置(高三字节固定为:2.0.0,低三字节用STM32唯一ID)
	lwipx->mac[0]=dm9000cfg.mac_addr[0];
	lwipx->mac[1]=dm9000cfg.mac_addr[1];
	lwipx->mac[2]=dm9000cfg.mac_addr[2];
	lwipx->mac[3]=dm9000cfg.mac_addr[3];
	lwipx->mac[4]=dm9000cfg.mac_addr[4];
	lwipx->mac[5]=dm9000cfg.mac_addr[5]; 
	//默认本地IP为:192.168.1.30
	lwipx->ip[0]=192;	
	lwipx->ip[1]=168;
	lwipx->ip[2]=1;
	lwipx->ip[3]=30;
	//默认子网掩码:255.255.255.0
	lwipx->netmask[0]=255;	
	lwipx->netmask[1]=255;
	lwipx->netmask[2]=255;
	lwipx->netmask[3]=0;
	//默认网关:192.168.1.1
	lwipx->gateway[0]=192;	
	lwipx->gateway[1]=168;
	lwipx->gateway[2]=1;
	lwipx->gateway[3]=1;	
	lwipx->dhcpstatus=0;//没有DHCP	
} 

//LWIP初始化(LWIP启动的时候使用)
//返回值:0,成功
//      1,内存错误
//      2,DM9000初始化失败
//      3,网卡添加失败.
u8 lwip_comm_init(void)
{
	struct netif *Netif_Init_Flag;		//调用netif_add()函数时的返回值,用于判断网络初始化是否成功
	ip4_addr_t ipaddr;  			//ip地址
	ip4_addr_t netmask; 			//子网掩码
	ip4_addr_t gw;      			//默认网关   
	lwip_init();						//初始化LWIP内核
	lwip_comm_default_ip_set(&lwipdev);	//设置默认IP等信息
    
	IP4_ADDR(&ipaddr,lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
	IP4_ADDR(&netmask,lwipdev.netmask[0],lwipdev.netmask[1] ,lwipdev.netmask[2],lwipdev.netmask[3]);
	IP4_ADDR(&gw,lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
	printf("网卡en的MAC地址为:................%d.%d.%d.%d.%d.%d\r\n",lwipdev.mac[0],lwipdev.mac[1],lwipdev.mac[2],lwipdev.mac[3],lwipdev.mac[4],lwipdev.mac[5]);
	printf("静态IP地址........................%d.%d.%d.%d\r\n",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
	printf("子网掩码..........................%d.%d.%d.%d\r\n",lwipdev.netmask[0],lwipdev.netmask[1],lwipdev.netmask[2],lwipdev.netmask[3]);
	printf("默认网关..........................%d.%d.%d.%d\r\n",lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
    
    
	Netif_Init_Flag=netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,&ethernetif_init,&ethernet_input);//向网卡列表中添加一个网口
	
	
	if(Netif_Init_Flag==NULL)return 3;//网卡添加失败 
	else//网口添加成功后,设置netif为默认值,并且打开netif网口
	{
         netif_set_default(&lwip_netif); //设置netif为默认网口
         if (netif_is_link_up(&lwip_netif))
         {
         /*When the netif is fully configured this function must be called */
             netif_set_up(&lwip_netif);
             printf("1\r\n");
         }
         else
         {
             /* When the netif link is down this function must be called */
             netif_set_down(&lwip_netif);
             printf("2\r\n");
         }
    }
	return 0;//操作OK.
}   

//当接收到数据后调用 
void lwip_pkt_handle(void)
{
	//从网络缓冲区中读取接收到的数据包并将其发送给LWIP处理 
	ethernetif_input(&lwip_netif);
}

移植第六步:ping获取数据包   

最后一步设置主函数 因为没有操作系统 死循环轮询lwip_pkt_handle()

int main(void)
{   
    u32 i,b;
    
	delay_init();	    	//延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    LED_Init();			    //LED端口初始化
	uart_init(115200);	 	//串口1波特率默认为115200
	KEY_Init();	 			//初始化按键
	TIM3_Int_Init(1000,719);//定时器3频率为100hz 10ms   
//    TIM4_Int_Init(3000,7199); //定时器4 默认频率为3000hz 300ms TCP分包时间
    DM9000_Init();
    

    b=lwip_comm_init();
    printf("b:%d\r\n",b);
    
    while(1)
    {
        lwip_pkt_handle();
        i++;
		if(i==50000)
		{
			LED0=~LED0;
            printf("OK\r\n");
			i=0;
		}
    }
}
  • 9
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值