stm32+lwip(二):UDP测试

我是卓波,很高兴你来看我的博客。

 

系列文章:

stm32+lwip(一):使用STM32CubeMX生成项目

stm32+lwip(二):UDP测试

stm32+lwip(三):TCP测试

stm32+lwip(四):网页服务器测试

stm32+lwip(五):以太网帧发送测试

 

ST官方有lwip的例程,下载地址如下:

https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32070.html

本文例子参考ST官方给出的例程。

一、准备

ST例程文档关于lwip的介绍如下:

 

由此可以看到LWIP有三种API,在本文中,使用Raw API

本文用到的UDP Raw API如下:

二、udp client

  1 /**
  2   *****************************************************************************
  3   * @file    udp_client.c
  4   * @author  Zorb
  5   * @version V1.0.0
  6   * @date    2018-09-04
  7   * @brief   udp客户端的实现
  8   *****************************************************************************
  9   * @history
 10   *
 11   * 1. Date:2018-09-04
 12   *    Author:Zorb
 13   *    Modification:建立文件
 14   *
 15   *****************************************************************************
 16   */
 17 
 18 #include "stm32f4xx_hal.h"
 19 #include "lwip.h"
 20 #include "udp.h"
 21 #include "string.h"
 22 
 23 /* 定义端口号 */
 24 #define UDP_REMOTE_PORT    8881 /* 远端端口 */
 25 #define UDP_LOCAL_PORT     8880 /* 本地端口 */
 26 
 27 /* udp控制块 */
 28 static struct udp_pcb *upcb;
 29 
 30 /******************************************************************************
 31  * 描述  : 接收回调函数
 32  * 参数  : -
 33  * 返回  : 无
 34 ******************************************************************************/
 35 static void udp_receive_callback(void *arg, struct udp_pcb *upcb,
 36     struct pbuf *p, const ip_addr_t *addr, u16_t port)
 37 {
 38     uint32_t i;
 39     
 40     /* 数据回传 */
 41 //    udp_send(upcb, p);
 42 //    udp_sendto(upcb, p, addr, port);
 43     
 44     /* 打印接收到的数据 */
 45     printf("get msg from %d:%d:%d:%d port:%d:\r\n",
 46         *((uint8_t *)&addr->addr), *((uint8_t *)&addr->addr + 1),
 47         *((uint8_t *)&addr->addr + 2), *((uint8_t *)&addr->addr + 3), port);
 48     
 49     if (p != NULL)
 50     {
 51         struct pbuf *ptmp = p;
 52         
 53         while(ptmp != NULL)
 54         {
 55             for (i = 0; i < p->len; i++)
 56             {
 57                 printf("%c", *((char *)p->payload + i));
 58             }
 59             
 60             ptmp = p->next;
 61         }
 62         
 63         printf("\r\n");
 64     }
 65     
 66     /* 释放缓冲区数据 */
 67     pbuf_free(p);
 68 }
 69 
 70 /******************************************************************************
 71  * 描述  : 发送udp数据
 72  * 参数  : (in)pData 发送数据的指针
 73  * 返回  : 无
 74 ******************************************************************************/
 75 void udp_client_send(char *pData)
 76 {
 77     struct pbuf *p;
 78     
 79     /* 分配缓冲区空间 */
 80     p = pbuf_alloc(PBUF_TRANSPORT, strlen(pData), PBUF_POOL);
 81     
 82     if (p != NULL)
 83     {
 84         /* 填充缓冲区数据 */
 85         pbuf_take(p, pData, strlen(pData));
 86 
 87         /* 发送udp数据 */
 88         udp_send(upcb, p);
 89 
 90         /* 释放缓冲区空间 */
 91         pbuf_free(p);
 92     }
 93 }
 94 
 95 /******************************************************************************
 96  * 描述  : 创建udp客户端
 97  * 参数  : 无
 98  * 返回  : 无
 99 ******************************************************************************/
100 void udp_client_init(void)
101 {
102     ip_addr_t serverIP;
103     err_t err;
104 
105     IP4_ADDR(&serverIP, 192, 168, 2, 194);
106 
107     /* 创建udp控制块 */
108     upcb = udp_new();
109 
110     if (upcb!=NULL)
111     {
112         /* 配置本地端口 */
113         upcb->local_port = UDP_LOCAL_PORT;
114         
115         /* 配置服务器IP和端口 */
116         err= udp_connect(upcb, &serverIP, UDP_REMOTE_PORT);
117 
118         if (err == ERR_OK)
119         {
120             /* 注册接收回调函数 */
121             udp_recv(upcb, udp_receive_callback, NULL);
122             
123             /* 发送udp数据 */
124             udp_client_send("udp client connected");
125             
126             printf("udp client connected\r\n");
127         }
128         else
129         {
130             udp_remove(upcb);
131             
132             printf("can not connect udp pcb\r\n");
133         }
134     }
135 }
136 
137 /******************************** END OF FILE ********************************/

本例用到的上位机IP192.168.2.194,开放端口为8881

STM32IP192.168.2.8,开放端口为8880

先将网络调试助手的UDP连接打开,然后给STM32上电。

网络调试助手将会收到如下信息:

 

然后点击网络调试助手的发送,STM32调试串口输出以下信息:

get msg from 192:168:2:194 port:8881:
hello zorb

三、udp server

 1 /**
 2   *****************************************************************************
 3   * @file    udp_server.c
 4   * @author  Zorb
 5   * @version V1.0.0
 6   * @date    2018-09-04
 7   * @brief   udp服务端的实现
 8   *****************************************************************************
 9   * @history
10   *
11   * 1. Date:2018-09-04
12   *    Author:Zorb
13   *    Modification:建立文件
14   *
15   *****************************************************************************
16   */
17 
18 #include "stm32f4xx_hal.h"
19 #include "lwip.h"
20 #include "udp.h"
21 
22 /* 定义端口号 */
23 #define UDP_REMOTE_PORT    8881 /* 远端端口 */
24 #define UDP_LOCAL_PORT     8880 /* 本地端口 */
25 
26 /******************************************************************************
27  * 描述  : 接收回调函数
28  * 参数  : -
29  * 返回  : 无
30 ******************************************************************************/
31 static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb,
32     struct pbuf *p, const ip_addr_t *addr, u16_t port)
33 {
34     uint32_t i;
35     
36     /* 数据回传 */
37 //    udp_sendto(upcb, p, addr, port);
38     
39     /* 打印接收到的数据 */
40     printf("get msg from %d:%d:%d:%d port:%d:\r\n",
41         *((uint8_t *)&addr->addr), *((uint8_t *)&addr->addr + 1),
42         *((uint8_t *)&addr->addr + 2), *((uint8_t *)&addr->addr + 3), port);
43     
44     if (p != NULL)
45     {
46         struct pbuf *ptmp = p;
47         
48         while(ptmp != NULL)
49         {
50             for (i = 0; i < p->len; i++)
51             {
52                 printf("%c", *((char *)p->payload + i));
53             }
54             
55             ptmp = p->next;
56         }
57         
58         
59         printf("\r\n");
60     }
61     
62     /* 释放缓冲区数据 */
63     pbuf_free(p);
64 }
65 
66 /******************************************************************************
67  * 描述  : 初始化UDP服务器端
68  * 参数  : 无
69  * 返回  : 无
70 ******************************************************************************/
71 void udp_server_init(void)
72 {
73     struct udp_pcb *upcb;
74     err_t err;
75 
76     /* 创建udp控制块 */
77     upcb = udp_new();
78 
79     if (upcb)
80     {
81         /* 绑定端口接收,接收对象为所有ip地址 */
82         err = udp_bind(upcb, IP_ADDR_ANY, UDP_LOCAL_PORT);
83 
84         if(err == ERR_OK)
85         {
86             /* 注册接收回调函数 */
87             udp_recv(upcb, udp_server_receive_callback, NULL);
88         }
89         else
90         {
91             /* 删除控制块 */
92             udp_remove(upcb);
93             
94             printf("can not bind pcb\r\n");
95         }
96     }
97 }
98 
99 /******************************** END OF FILE ********************************/

本例用到的上位机IP192.168.2.194,开放端口为8881

STM32IP192.168.2.8,开放端口为8880

先将STM32上电,然后通过网络调试助手发送hello zorb

STM32调试串口输出以下信息:

get msg from 192:168:2:194 port:8881:
hello zorb

四、最后

本文测试了lwipudp功能,能正常收发,撒花。

 

github:https://github.com/54zorb/stm32-lwip

版权所有,转载请打赏哟

 

如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

posted @ 2018-09-08 13:46  54zorb  阅读(20207)  评论(3编辑  收藏  举报