首页程序设计STM32程序UIP1.0实现UDP通讯--方法2

UIP1.0实现UDP通讯--方法2

时间2016-04-20 14:09:21发布caterwang分类STM32程序浏览3707

    目的:实现被动接收然后上传,或是主动上传

    1.初始化

struct uip_udp_conn *myudp;
#if UIP_UDP //本地端口和远程端口均
	uip_listen(HTONS(uiUIP_UDP_lPORT));
	ucSerAddr[0] = unReIPAddress.ucUnPar[0];
	ucSerAddr[1] = unReIPAddress.ucUnPar[1];
	ucSerAddr[2] = unReIPAddress.ucUnPar[2];
	ucSerAddr[3] = unReIPAddress.ucUnPar[3];	
	uip_ipaddr(&ipaddr, ucSerAddr[0],ucSerAddr[1],ucSerAddr[2],ucSerAddr[3]);    //配置远程IP
	if(myudp!=NULL)
	{
		uip_udp_remove(myudp);
	}
	myudp=uip_udp_new(&ipaddr,HTONS(0));	//远程端口,接收状态
	if(myudp!=NULL)
	{
		for(i=0;i<UIP_UDP_CONNS;i++)
			uip_udp_bind(myudp+i,HTONS(uiUIP_UDP_lPORT));
	}
#endif

   2.为了实现同时主动上传和被动接收,除了初始化时要把远程端口设为0而外,还要对uip.c中内容进行修改

blob.png

    3.发送数时的处理方式

    3.1.

blob.png

        3.2. uip事件处理函数 uip_polling()的修改

        

blob.png


//uip事件处理函数
//必须将该函数插入用户主循环,循环调用.
void uip_polling(void)
{
	u8 i;
	static struct timer periodic_timer, arp_timer;
	static u8 timer_ok=0;	 
	if(timer_ok==0)//仅初始化一次
	{
		timer_ok = 1;
		timer_set(&periodic_timer,CLOCK_SECOND/10);  //创建1个0.1秒的定时器 
		timer_set(&arp_timer,CLOCK_SECOND*10);	   	//创建1个10秒的定时器 1000
	}				 
	uip_len=tapdev_read();	//从网络设备读取一个IP包,得到数据长度.uip_len在uip.c中定义

	if(uip_len>0) 			//有数据
	{   
		//处理IP数据包(只有校验通过的IP包才会被接收) 
		if(BUF->type == htons(UIP_ETHTYPE_IP))//是否是IP包? 
		{
			uip_arp_ipin();	//去除以太网头结构,更新ARP表
			uip_input();   	//IP包处理
			//当上面的函数执行后,如果需要发送数据,则全局变量 uip_len > 0
			//需要发送的数据在uip_buf, 长度是uip_len  (这是2个全局变量)		    
			if(uip_len>0)//需要回应数据
			{
				uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求
				tapdev_send();//发送数据到以太网
			}
		}else if (BUF->type==htons(UIP_ETHTYPE_ARP))//处理arp报文,是否是ARP请求包?
		{
			uip_arp_arpin();
 			//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0
			//需要发送的数据在uip_buf, 长度是uip_len(这是2个全局变量)
 			if(uip_len>0)
			{
				tapdev_send();//需要发送数据,则通过tapdev_send发送	
			}
		}
	}
	else if(timer_expired(&periodic_timer))	//0.5秒定时器超时
	{
		timer_reset(&periodic_timer);		//复位0.5秒定时器 
		//轮流处理每个TCP连接, UIP_CONNS缺省是40个  
		for(i=0;i<UIP_CONNS;i++)
		{
			uip_periodic(i);	//处理TCP通信事件  
	 		//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0
			//需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量)
	 		if(uip_len>0)
			{
				uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求
				tapdev_send();//发送数据到以太网
			}
		}
#if UIP_UDP
		//轮流处理每个UDP连接, UIP_UDP_CONNS缺省是10个
		for(i=0;i<UIP_UDP_CONNS;i++)
		{
			uip_udp_periodic(i);	//处理UDP通信事件
	 		//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0
			//需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量)
			if(uip_len > 0)
			{
				uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求
				tapdev_send();//发送数据到以太网
				uip_udp_conns[i].rport =HTONS(0);		//远程端口切换,更改状态为接收状态
			}
		}
#endif 
		//每隔10秒调用1次ARP定时器函数 用于定期ARP处理,ARP表10秒更新一次,旧的条目会被抛弃
		if(timer_expired(&arp_timer))
		{
			timer_reset(&arp_timer);
			uip_arp_timer();
		}
	}
}


    综上,相比之前的方法1,现在的方法,不仅对uip原代码改动最小,而且还能实现主动上传数据。这在部分场合是相当有用的。

凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!

展开全文READ MORE
STM32UIPUDPENC28J60
74HC165并入串出移位寄存器的读操作 不需要全功能J-Link也能完成stm32三线制调试工具J-Link ARM-OB制作

游客 回复需填写必要信息