【2】嵌入式TCP/IP协议——————RAW接口UDP实验

  1. 简述
    1. UDP概述之前已经写过,请参阅:https://blog.csdn.net/Linux_ARM9/article/details/106008881
    2. 此处只写实验例程
  2. UDP层函数关系
  3. RAW 中与UDP相关的函数
    1. udp_new(); 新建一个UDP的PCB块
    2. udp_remove(); 将一个PCB控制块从链表中删除,并且释放这个控制块的内存
    3. udp_bind(); 为udp的PCB控制块绑定一个IP地址和端口号
    4. udp_connect(); 连接到指定IP地址主机的指定端口上,其它就是设置PCB控制块的remote_ip和remote_port
    5. udp_disconnect(); 断开链接,将控制块设置为非连接状态,其实就是清除remote_ip和remote_port字段
    6. udp_send(); 通过一个PCB控制块发送数据
    7. udp_recv(); 需要创建一一个回调函数,当接收到数据的时候被调用
  4. 复制例程中的udp_demo.c和udp_demo.h两个文件
  5. udp_demo.c函数详解
    1. udp_demo_set_remoteip();设置远端IP地址,UDP连接的时候要用到这个地址
    2. udp_demo_test(); UDP实验测试函数
    3. udp_demo_recv(); UDP接收数据回调函数
    4. udp_demo_senddata(); 发送数据
    5. udp_demo_connection_close(); 关闭UDP连接
  6. 软件设计
    1. 创建一个UDP的控制块
    2. 连接到指定IP地址和端口号
    3. 绑定IP地址和端口号
    4. 注册接收回调函数
    5. 回调函数内接收数据
    6. 发送数据
    7. 断开连接,并释放内存
    8. 在接收/发送数据的循环中需要调用lwip_periodic_handle()函数,否则网络无法运行
  7. 例程代码
    1. //UDP测试
      void udp_demo_test(void)
      {
       	err_t err;
      	struct udp_pcb *udppcb;  	//定义一个TCP服务器控制块
      	struct ip_addr rmtipaddr;  	//远端ip地址
       	
      	u8 *tbuf;
       	u8 key;
      	u8 res=0;		
      	u16 t=0; 
       	
      	udp_demo_set_remoteip();//先选择IP
      	BSP_LCD_Clear(WHITE);	//清屏
      	POINT_COLOR=RED; 	//红色字体
      	BSP_LCD_ShowString(30,30,200,16,16,"Apollo STM32F4&F7");
      	BSP_LCD_ShowString(30,50,200,16,16,"RAW UDP Test");
      	BSP_LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");  
      	BSP_LCD_ShowString(30,90,200,16,16,"KEY0:Send data");  
      	BSP_LCD_ShowString(30,110,200,16,16,"KEY_UP:Quit"); 
      	BSP_LCD_ShowString(30,130,200,16,16,"KEY1:Connect");
      	tbuf=mymalloc(SRAMIN,200);	//申请内存
      	if(tbuf==NULL)return ;		//内存申请失败了,直接退出
      	sprintf((char*)tbuf,"Local IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);//服务器IP
      	BSP_LCD_ShowString(30,150,210,16,16,tbuf);  
      	sprintf((char*)tbuf,"Remote IP:%d.%d.%d.%d",lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);//远端IP
      	BSP_LCD_ShowString(30,170,210,16,16,tbuf);  
      	sprintf((char*)tbuf,"Remote Port:%d",UDP_DEMO_PORT);//客户端端口号
      	BSP_LCD_ShowString(30,190,210,16,16,tbuf);
      	POINT_COLOR=BLUE;
      	BSP_LCD_ShowString(30,210,210,16,16,"STATUS:Disconnected"); 
      	udppcb=udp_new();
      	if(udppcb)//创建成功
      	{ 
      		IP4_ADDR(&rmtipaddr,lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);
      		err=udp_connect(udppcb,&rmtipaddr,UDP_DEMO_PORT);//UDP客户端连接到指定IP地址和端口号的服务器
      		if(err==ERR_OK)
      		{
      			err=udp_bind(udppcb,IP_ADDR_ANY,UDP_DEMO_PORT);//绑定本地IP地址与端口号
      			if(err==ERR_OK)	//绑定完成
      			{
      				udp_recv(udppcb,udp_demo_recv,NULL);//注册接收回调函数 
      				BSP_LCD_ShowString(30,210,210,16,16,"STATUS:Connected   ");//标记连接上了(UDP是非可靠连接,这里仅仅表示本地UDP已经准备好)
      				udp_demo_flag |= 1<<5;			//标记已经连接上
      				POINT_COLOR=RED;
      				BSP_LCD_ShowString(30,230,BSP_LCD_InitStructure.width-30,BSP_LCD_InitStructure.height-190,16,"Receive Data:");//提示消息		
      				POINT_COLOR=BLUE;//蓝色字体
      			}
                  else 
                      res=1;
      		}
              else 
                  res=1;		
      	}
          else
              res=1;
      	while(res==0)
      	{
      		key=BSP_KEY_Scan(0);
      		if(key==Key_WkUP_PA0_Value)break;
      		if(key==Key0_PH3_Value)//KEY0按下了,发送数据
      		{
      			udp_demo_senddata(udppcb);
      		}
      		if(udp_demo_flag&1<<6)//是否收到数据?
      		{
      			BSP_LCD_Fill(30,250,BSP_LCD_InitStructure.width-1,BSP_LCD_InitStructure.height-1,WHITE);//清上一次数据
      			BSP_LCD_ShowString(30,250,BSP_LCD_InitStructure.width-30,BSP_LCD_InitStructure.height-230,16,udp_demo_recvbuf);//显示接收到的数据			
      			udp_demo_flag&=~(1<<6);//标记数据已经被处理了.
      		} 
      		lwip_periodic_handle();
      		delay_us(100);
      		t++;
      		if(t==2000)
      		{
      			t=0;
      			LED0_Toggle;
      		}
      	}
      	udp_demo_connection_close(udppcb); 
      	myfree(SRAMIN,tbuf);
      } 

       

  8. 总结
  9. 参考资料:
    1. 正点原子《STM32F767开发指南(HAL库版)》
    2. 正点原子《STM32F767 LWIP手册》
    3. 野火《STM32 HAL库开发实战指南》
    4. 野火《LWIP应用开发实战指南》
    5. 官方源码
  10. 硬件平台:
    1. 正点原子阿波罗F767
  11. 软件平台:
    1. MDK5.2.5
  12. 库版本:
    1. TM32Cube_FW_F7_V1.4.0
  13. LWIP版本
    1. lwip-1.4.1
    2. contrib-1.4.1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值