基于STM32 DM9000 LWIP之自动获取IP

      第一次写博客,不足之处各位同仁多多纠正。最近在做一个IP智能广播公共系统,类似于IP服务器点播之类。以前做过IP音乐播放器终端,服务端发PCM流给终端设备,终端设备解码放歌,IP地址固定分配的,当时用的uIP,uIP主要以占内存和ROM少著称,实用8位16位32位单片机,但功能强大不如LWIP。IP智能广播终端设备基本不在一个地方,有可能跨小区基本是多栋楼宇之间设备语音通信,一个局域网之间数据共享多个路由器连接,这个时候嵌入式终端自动获取是重之重要。

     首先介绍下LWIP移植过程。类似于文件管理,EMWIN GUI它们之间都有很大共性(个人见解),它们最重要的是在“读”和“写”之间谋划的,现在程序设计已是很成熟了,应用层以基本走向完善,这完全感谢前人为我们做出的贡献,所以你只要把一样东西最原始的操作方式交给协议栈,协议栈就可以在最原始的方法衍生不同的类。文件管理也是,你知道把储存设备的读页写页交给它,它以最合理的方式帮你管理文件资源,GUI软件也是,你只要把LCD读像素点和写像素点交给它,它就为你提供丰富的控件。

    废话少说,上代码。LWIP移植也是要你交给它一个读包和写包它才能为你提供服务。

在LWIP协议栈中找到ethernetif.c文件在下个函数提供一个读包的底层函数

static struct pbuf *low_level_input( struct netif *netif )
{                                                   


struct pbuf *q,*p = NULL;
u16 Len = 0; 


  int i =0;

Len = etherdev_read(Data_Buf,1520 *4); //这个就是读包的底层函数


if ( Len == 0 ) return 0;

p = pbuf_alloc(PBUF_RAW, Len, PBUF_POOL);

if (p != NULL) 
{


        for (q = p; q != NULL; q = q->next) 
{  
             memcpy((u8_t*)q->payload, (u8_t*)&Data_Buf[i], q->len);


             i = i + q->len;
        }
if( i != p->tot_len ){ return 0;} 
    }


return p;
}

在下列函数写入一个发送包的底层函数

static err_t low_level_output( struct netif *netif, struct pbuf *p )  /*µ×²ã·¢ËÍÊý¾Ýº¯Êý*/
{     
  struct pbuf *q;
  int i = 0;   


  err_t xReturn = ERR_OK;


  /* Parameter not used. */
  for(q = p; q != NULL; q = q->next) 
  {
    memcpy(&Tx_Data_Buf[i], (u8_t*)q->payload, q->len); 
    i = i + q->len;
  }
  dm9k_send_packet(Tx_Data_Buf,i); //这个就是要写入发送包函数


    return xReturn;
}

两大要点准备好了接下来就把网络设备初始化交这协议栈

在下列函数写入初始化函数

static void low_level_init( struct netif *netif )
{
/* set MAC hardware address length */
netif->hwaddr_len = 6;


/* set MAC hardware address */

netif->hwaddr[0] = macaddress[0];
netif->hwaddr[1] = macaddress[1];
netif->hwaddr[2] = macaddress[2];
netif->hwaddr[3] = macaddress[3];
netif->hwaddr[4] = macaddress[4];
netif->hwaddr[5] = macaddress[5];


/* maximum transfer unit */

netif->mtu = netifMTU;


/* broadcast capability */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;


/* Initialise the EMAC.  This routine contains code that polls status bits.  
If the Ethernet cable is not plugged in then this can take a considerable 
time.  To prevent this starving lower priority tasks of processing time we
lower our priority prior to the call, then raise it back again once the
initialisation is complete. */


etherdev_init(netif->hwaddr); //这个就是要写入初始化的函数
}    

现在是万事俱备只欠东风,就如CPU它也需要一个晶振心脏它才能工作,协议栈也是,它也需要为提供一个心脏,这个心脏就是一个10ms自加的计数器

........

刚开始已静态IP形式工作,把程序写入板子,然后定义一个UDP服务器发送,已用来观察是否工作,用抓包软件观察其数据包效果图如下

基于STM32 DM9000 LWIP之自动获取IP_第1张图片

我设置的静态IP为192.168.1.31而抓包软件显示的却是192.169.129.31很明显中间两个字节数据错乱,第一和第四两个字节无错乱说明CPU给DM9000发数据时序是对的,因为DM9000我设置的是工作在8位字宽传送并非16字宽,后来打开PCB板数据以太网接收和发送差分对没等长,在Enc28J60没等长也正常工作,为什么呢?原因就是10MBps和100MBps区别,信号的完整性是跟频率有关系的,基于STM32 DM9000 LWIP之自动获取IP_第2张图片

通过查分等差调节第二次打板,已静态IP工作时序正确。

现在我们就开始让LWIP自动获取IP,LWIP有自动获取IP的源码,无需我们自己去写,找到lwipopts.h头文件将其设置为1,为1就是自动获取IP.

然后  通过netif_set_default(&DM9000);netif_set_up(&DM9000);函数使能DM9000烧入板子

通过抓包软件设置抓包为ARP0X0806

可以观察到

说明路由器已经给DM9000分配IP,然后ping 192.168.1.109基于STM32 DM9000 LWIP之自动获取IP_第3张图片

ping 通了,拔掉网口在ping无反应,说明192.168.1.109是DM9000自动获取的。

需要完整代码联系我[email protected]


你可能感兴趣的:(物联网,stm32,dm9000,LWIP)