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

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:20   2289   0
  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
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP