stm32+lwip(三):TCP测试

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

系列文章:

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

stm32+lwip(二):UDP测试

stm32+lwip(三):TCP测试

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

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

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

STSW-STM32070 - LwIP TCP/IP stack demonstration for STM32F4x7 microcontrollers (AN3966) - STMicroelectronics

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

一、准备

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

 

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

本文用到的TCP Raw API如下:

二、tcp client

复制代码

  1 /**
  2   *****************************************************************************
  3   * @file    tcp_client.c
  4   * @author  Zorb
  5   * @version V1.0.0
  6   * @date    2018-09-04
  7   * @brief   tcp客户端的实现
  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 "tcp.h"
 21 #include "string.h"
 22 
 23 /* 定义端口号 */
 24 #define TCP_REMOTE_PORT    8881 /* 远端端口 */
 25 #define TCP_LOCAL_PORT     8880 /* 本地端口 */
 26 
 27 /******************************************************************************
 28  * 描述  : 数据接收回调函数
 29  * 参数  : -
 30  * 返回  : -
 31 ******************************************************************************/
 32 static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb,
 33                              struct pbuf *p, err_t err)
 34 {
 35     uint32_t i;
 36     
 37     /* 数据回传 */
 38     //tcp_write(tpcb, p->payload, p->len, 1);
 39     
 40     if (p != NULL)
 41     {
 42         struct pbuf *ptmp = p;
 43         
 44         /* 打印接收到的数据 */
 45         printf("get msg from %d:%d:%d:%d port:%d:\r\n",
 46             *((uint8_t *)&tpcb->remote_ip.addr),
 47             *((uint8_t *)&tpcb->remote_ip.addr + 1),
 48             *((uint8_t *)&tpcb->remote_ip.addr + 2),
 49             *((uint8_t *)&tpcb->remote_ip.addr + 3),
 50             tpcb->remote_port);
 51         
 52         while(ptmp != NULL)
 53         {
 54             for (i = 0; i < p->len; i++)
 55             {
 56                 printf("%c", *((char *)p->payload + i));
 57             }
 58             
 59             ptmp = p->next;
 60         }
 61         
 62         printf("\r\n");
 63         
 64         tcp_recved(tpcb, p->tot_len);
 65         
 66         /* 释放缓冲区数据 */
 67         pbuf_free(p);
 68     }
 69     else if (err == ERR_OK)
 70     {
 71         printf("tcp client closed\r\n");
 72         
 73         tcp_recved(tpcb, p->tot_len);
 74         
 75         return tcp_close(tpcb);
 76     }
 77 
 78     return ERR_OK;
 79 }
 80 
 81 /******************************************************************************
 82  * 描述  : 连接服务器回调函数
 83  * 参数  : -
 84  * 返回  : -
 85 ******************************************************************************/
 86 static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
 87 {
 88     printf("tcp client connected\r\n");
 89     
 90     tcp_write(tpcb, "tcp client connected", strlen("tcp client connected"), 0);
 91 
 92     /* 注册接收回调函数 */
 93     tcp_recv(tpcb, tcp_client_recv);
 94 
 95     return ERR_OK;
 96 }
 97 
 98 /******************************************************************************
 99  * 描述  : 创建tcp客户端
100  * 参数  : 无
101  * 返回  : 无
102 ******************************************************************************/
103 void tcp_client_init(void)
104 {
105     struct tcp_pcb *tpcb;
106     ip_addr_t serverIp;
107 
108     /* 服务器IP */
109     IP4_ADDR(&serverIp, 192, 168, 2, 194);
110 
111     /* 创建tcp控制块 */
112     tpcb = tcp_new();
113     
114     if (tpcb != NULL)
115     {
116         err_t err;
117         
118         /* 绑定本地端号和IP地址 */
119         err = tcp_bind(tpcb, IP_ADDR_ANY, TCP_LOCAL_PORT);
120 
121         if (err == ERR_OK)
122         {
123             /* 连接服务器 */
124             tcp_connect(tpcb, &serverIp, TCP_REMOTE_PORT, tcp_client_connected);
125         }
126         else
127         {
128             memp_free(MEMP_TCP_PCB, tpcb);
129             
130             printf("can not bind pcb\r\n");
131         }
132     }
133 }
134 
135 /******************************** END OF FILE ********************************/

复制代码

本例用到的上位机IP为192.168.2.194,开放端口为8881

STM32的IP为192.168.2.8,开放端口为8880

先将网络调试助手的TCP Server打开,然后给STM32上电。

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

 

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

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

三、tcp server

复制代码

  1 /**
  2   *****************************************************************************
  3   * @file    tcp_server.c
  4   * @author  Zorb
  5   * @version V1.0.0
  6   * @date    2018-09-04
  7   * @brief   tcp服务端的实现
  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 "tcp.h"
 21 #include "string.h"
 22 
 23 /* 定义端口号 */
 24 #define TCP_REMOTE_PORT    8881 /* 远端端口 */
 25 #define TCP_LOCAL_PORT     8880 /* 本地端口 */
 26 
 27 /******************************************************************************
 28  * 描述  : 接收回调函数
 29  * 参数  : -
 30  * 返回  : -
 31 ******************************************************************************/
 32 static err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb,
 33                              struct pbuf *p, err_t err)
 34 {
 35     uint32_t i;
 36     
 37     /* 数据回传 */
 38     //tcp_write(tpcb, p->payload, p->len, 1);
 39     
 40     if (p != NULL)
 41     {
 42         struct pbuf *ptmp = p;
 43         
 44         /* 打印接收到的数据 */
 45         printf("get msg from %d:%d:%d:%d port:%d:\r\n",
 46             *((uint8_t *)&tpcb->remote_ip.addr),
 47             *((uint8_t *)&tpcb->remote_ip.addr + 1),
 48             *((uint8_t *)&tpcb->remote_ip.addr + 2),
 49             *((uint8_t *)&tpcb->remote_ip.addr + 3),
 50             tpcb->remote_port);
 51         
 52         while(ptmp != NULL)
 53         {
 54             for (i = 0; i < p->len; i++)
 55             {
 56                 printf("%c", *((char *)p->payload + i));
 57             }
 58             
 59             ptmp = p->next;
 60         }
 61         
 62         printf("\r\n");
 63         
 64         tcp_recved(tpcb, p->tot_len);
 65         
 66         /* 释放缓冲区数据 */
 67         pbuf_free(p);
 68     }
 69     else if (err == ERR_OK)
 70     {
 71         printf("tcp client closed\r\n");
 72         
 73         tcp_recved(tpcb, p->tot_len);
 74         
 75         return tcp_close(tpcb);
 76     }
 77 
 78     return ERR_OK;
 79 }
 80 
 81 /******************************************************************************
 82  * 描述  : 客户端接入回调函数
 83  * 参数  : -
 84  * 返回  : -
 85 ******************************************************************************/
 86 static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
 87 {
 88     printf("tcp client connected\r\n");
 89     
 90     printf("ip %d:%d:%d:%d port:%d\r\n",
 91         *((uint8_t *)&newpcb->remote_ip.addr),
 92         *((uint8_t *)&newpcb->remote_ip.addr + 1),
 93         *((uint8_t *)&newpcb->remote_ip.addr + 2),
 94         *((uint8_t *)&newpcb->remote_ip.addr + 3),
 95         newpcb->remote_port);
 96     
 97     tcp_write(newpcb, "tcp client connected", strlen("tcp client connected"), 0);
 98     
 99     /* 注册接收回调函数 */
100     tcp_recv(newpcb, tcp_server_recv);
101 
102     return ERR_OK;
103 }
104 
105 /******************************************************************************
106  * 描述  : 创建tcp服务器
107  * 参数  : 无
108  * 返回  : 无
109 ******************************************************************************/
110 void tcp_server_init(void)
111 {
112     struct tcp_pcb *tpcb;
113 
114     /* 创建tcp控制块 */
115     tpcb = tcp_new();
116 
117     if (tpcb != NULL)
118     {
119         err_t err;
120         
121         /* 绑定端口接收,接收对象为所有ip地址 */
122         err = tcp_bind(tpcb, IP_ADDR_ANY, TCP_LOCAL_PORT);
123 
124         if (err == ERR_OK)
125         {
126             /* 监听 */
127             tpcb = tcp_listen(tpcb);
128 
129             /* 注册接入回调函数 */
130             tcp_accept(tpcb, tcp_server_accept);
131             
132             printf("tcp server listening\r\n");
133             printf("tcp server ip:%d:%d:%d:%d prot:%d\r\n",
134                 *((uint8_t *)&ipaddr.addr),
135                 *((uint8_t *)&ipaddr.addr + 1),
136                 *((uint8_t *)&ipaddr.addr + 2),
137                 *((uint8_t *)&ipaddr.addr + 3),
138                 tpcb->local_port);
139         }
140         else
141         {
142             memp_free(MEMP_TCP_PCB, tpcb);
143             
144             printf("can not bind pcb\r\n");
145         }
146 
147     }
148 }
149 
150 /******************************** END OF FILE ********************************/

复制代码

本例用到的上位机IP为192.168.2.194,开放端口为8881

STM32的IP为192.168.2.8,开放端口为8880

先将STM32上电,STM32调试串口输出以下信息:

tcp server listening
tcp server ip:192:168:2:8 prot:8880

然后通过网络调试助手连接到STM32的tcp服务器:

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

tcp client connected
ip 192:168:2:194 port:53538

在网络调试助手发送信息”hello zorb”,STM32调试串口输出以下信息:

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

四、最后

本文测试了lwip的tcp功能,能正常连接并收发数据,撒花。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现STM32 FreeRTOS LwIP TCP服务器需要按照以下步骤进行操作: 1. 首先,需要配置LwIP和FreeRTOS。可以在STM32CubeMX中选择配置相应的组件,生成对应的代码和初始化函数。 2. 在代码中创建任务来处理TCP服务器。通过创建一个任务,可以将其分配给特定的核心,以处理TCP请求和响应。 3. 在任务中,首先需要进行LwIP和FreeRTOS的初始化。这样可以确保网络和操作系统的适当设置。需要调用lwip_init()和vTaskStartScheduler()函数。 4. 配置和创建TCP服务器的套接字。可以通过调用lwip_socket()函数创建一个TCP套接字,并使用lwip_bind()函数将其与特定的IP地址和端口绑定。 5. 通过调用lwip_listen()函数监听TCP套接字,等待客户端的连接。 6. 使用lwip_accept()函数接受客户端的连接请求,并获得一个新的套接字来处理与该客户端之间的通信。 7. 通过调用lwip_recv()和lwip_send()函数来接收和发送数据。可以使用这些函数接收来自客户端的数据,并发送响应数据给客户端。 8. 当与客户端的通信完成后,使用lwip_close()函数关闭套接字。 9. 循环进行步骤6-8,以处理其他客户端的连接和通信请求。 需要注意的是,STM32系列芯片的内存和处理能力有限,因此在编写代码时需要谨慎处理内存和资源的分配和释放,以确保程序的稳定性和性能。 总结:通过以上步骤,可以在STM32上使用FreeRTOS和LwIP实现TCP服务器,使其能够接受和处理客户端的连接和通信请求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值