使用STM32CubeIDE 1.17.0生成和编辑的STM32H743XIH6代码,使用了FreeRTOS+lwip,sockets实现的TCP客户端,对服务器端发送超过128个字节会卡死,进入硬件错误中断,参考的例子如下链接STM32H750+CubeIDE+FreeRTOS+ETH(LAN8720A)+LWIP_stm32h750 lan8720a-CSDN博客
。
请问这个例子是否正确?或者说有什么教程可以正确的参考吗
#include "tcpclient.h"
#include "lwip/sockets.h"
#include "ctype.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lwip/netdb.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include "usb_device.h"
//struct sockaddr_in serverAddr;
int client_socket = -1;
// 定义一个标志变量来控制重连次数
int reconnect_attempts = 0;
void myDelay(int ms) {
vTaskDelay(pdMS_TO_TICKS(ms));
}
bool is_connected = false;
bool isConnected() {
return is_connected;
}
void tcp_client_init(void) {
struct sockaddr_in serverAddr;
int enable = 1;
client_socket = socket(AF_INET, SOCK_STREAM, 0);//AF_INET:IPV4,SOCK_STREAM:协议类型为TCP
if (client_socket < 0)
{
usb_printf("创建socket失败\n");
return;
}
// 设置 socket 选项
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));//允许本地地址重用
// 设置读取超时
struct timeval timeout;
timeout.tv_sec = 5; // 5秒超时
timeout.tv_usec = 0;
setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
//连接的服务器
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(TCP_CLIENT_PORT);
serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
int ret = connect(client_socket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
// 连接到服务器
if (ret < 0) {
usb_printf("连接服务器失败\n");
lwip_close(client_socket);
client_socket = -1;
is_connected = false;
} else {
usb_printf("TCP 连接成功\n");
is_connected = true;
reconnect_attempts = 0; // 重置重连次数
}
}
// 读取数据
void tcp_read_data(void) {
char buffer[1024];
ssize_t bytes_read;
// 读取数据
bytes_read = lwip_recv(client_socket, buffer, sizeof(buffer) - 1, 0);
if (bytes_read > 0)
{
buffer[bytes_read] = '\0';
usb_printf("读取的数据: %s\n", buffer);
}
else if (bytes_read == 0)
{
usb_printf("服务器关闭连接\n");
lwip_close(client_socket);
client_socket = -1;
is_connected = false;
}
else
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
{
usb_printf("读取超时\n");
}
else
{
usb_printf("数据读取失败: %d\n", errno);
lwip_close(client_socket);
client_socket = -1;
is_connected = false;
}
}
}
// 发送数据
void tcp_send_data(const char *data) {
if (is_connected)
{
ssize_t bytes_sent =lwip_send(client_socket, data, strlen(data), 0);
if (bytes_sent < 0)
{
usb_printf("数据发送失败: %d\n", errno);
lwip_close(client_socket);//断开连接
client_socket = -1;
is_connected = false;
}
else
{
// usb_printf("发送数据: %s\n", data);
}
}
else
{
usb_printf("未连接,无法发送数据\n");
}
}
|
没有打开LWIP用户内存池
再就是看看LWIP相关的配置,比方发送缓冲区大小 TCP_SND_BUF、发送窗口 TCP_WND这些,你可以参考ST提供的相关例程的默认配置;
你先下载STM32Cubeh7固件库, 在。。。\STM32Cube_FW_H7_V1.12.0\Projects\STM32H743I-EVAL\Applications\LwIP 有很多例程。
你检查下你的发送函数本身是否有问题,尤其有关数据长度的参数,不要发送越界了;
官方例程在哪里找?
这里就有很多:
。。。。\STM32Cube_FW_H7_V1.12.0\Projects\STM32H743I-EVAL\Applications\LwIP