Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
LWIP1.4.1
tcpip_thread
LWIP1.4.1 长时间工作会异常断开
发布于 2021-03-02 16:42:52 浏览:1620
订阅该版
软件平台用RT-Thread 硬件平台LPC1768开发板 把开发板做为服务器,以一路串口互相发送数据,过一段时间后,会异常断开,报错 tcpip_thread: invalid message Assertion: 141 in ..\..\components\net\lwip\src\api\tcpip.c 测试代码: #include "apptasks.h" #include
#include
/* 使用BSD Socket接口必须包含sockets.h这个头文件 */ #define BUFSZ (1024) #define MAX_CONNECT_NUM 10 //最大连接数 extern rt_device_t dev_uart1; extern rt_device_t dev_uart2; extern rt_device_t dev_uart3; //以太网 int tcpserver_connected; /*连接套接字*/ //int tcpserver1_connected; /*连接套接字*/ //int tcpserver2_connected; /*连接套接字*/ static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */ static char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */ static void tcp_server_handler_msg(void *parameter) { int ret; int bytes_received; while(1) { bytes_received = recv(tcpserver_connected,recv_data, 1024, 0); if (bytes_received < 0) { rt_kprintf("Received error, close the connect."); /* 接收失败,关闭这个connected socket */ lwip_close(tcpserver_connected); break; } else if(bytes_received == 0) { /* 打印recv函数返回值为0的警告信息 */ rt_kprintf("Received warning, recv function return 0."); lwip_close(tcpserver_connected); continue; } else { /* 有接收到数据,把末端清零 */ recv_data[bytes_received] = '\0'; if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) { /* 如果是首字母是q或Q,关闭这个连接 */ lwip_close(tcpserver_connected); break; } else if (strcmp(recv_data, "exit") == 0) { /* 如果接收的是exit,则关闭整个服务端 */ lwip_close(tcpserver_connected); break; } else { /* 在控制终端显示收到的数据 */ dev_uart1->write(dev_uart1, 0, recv_data, strlen(recv_data)); } // /* 发送数据到connected socket */ // ret = send(tcpserver_connected,send_data,strlen(send_data),0); // if (ret < 0) // { // rt_kprintf("send error, close the connect."); // lwip_close(tcpserver_connected); // break; // } // else if (ret == 0) // { // /* 打印send函数返回值为0的警告信息 */ // rt_kprintf("Send warning, send function return 0."); // } } } } void svr_task_thread_entry(void *p) { rt_thread_t tcp_handler_thread; int port = 5000; int sock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; socklen_t sin_size = sizeof(struct sockaddr_in); recv_data = rt_malloc(BUFSZ + 1); /* 分配接收用的数据缓冲 */ if (recv_data == RT_NULL) { rt_kprintf("No memory"); return; } //client 1 /* 1.一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */ if ((sock = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { rt_kprintf("Socket error\n"); goto _exit; } else { rt_kprintf("Socket pass\n"); } /* 初始化服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); /* 服务器工作端口 */ server_addr.sin_addr.s_addr = INADDR_ANY; rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero)); /* 2.绑定socket到服务端地址 */ if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { rt_kprintf("TCP socket bind failed!\n"); lwip_close(sock); //FRX add /* 释放已分配的接收缓冲 */ goto _exit; } /* 3.进入监听模式 */ if (listen(sock, MAX_CONNECT_NUM) == -1) { rt_kprintf("Listen error\n"); lwip_close(sock); //FRX add goto _exit; } rt_kprintf("\nTCPServer Waiting for client on port %d...\n", port); while(1) { /*4.接收连接请求 */ tcpserver_connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); /* 返回的是连接成功的socket */ if( tcpserver_connected < 0 ) // accept failed. { rt_kprintf("TCP setup accept failed.\n"); continue; } tcp_handler_thread = rt_thread_create("tcp_serv_handler", tcp_server_handler_msg, RT_NULL,//直接传地址 1024, 6,//优先级比原来的高 20); if (tcp_handler_thread != RT_NULL) { rt_thread_startup(tcp_handler_thread); } } _exit: return; } ///////////////////////////////////////////////////////////////// ///////串口 struct rt_semaphore rx0_sem; struct rt_semaphore rx1_sem; struct rt_semaphore rx2_sem; struct rt_semaphore tx1_sem; struct rt_semaphore tx2_sem; struct rt_semaphore tx3_sem; #define RX_BUF_SIZE 1024 static char rx_buf[RX_BUF_SIZE]; static char rx1_buf[RX_BUF_SIZE]; static char rx2_buf[RX_BUF_SIZE]; rt_device_t dev_uart1; rt_device_t dev_uart2; rt_device_t dev_uart3; //串口0读取回调函数 rt_err_t usart_rx_indicate(rt_device_t dev, rt_size_t size) { /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ while(size--) { rt_sem_release(&rx0_sem); } return RT_EOK; } //串口1读取回调函数 rt_err_t usart1_rx_indicate(rt_device_t dev, rt_size_t size) { /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ while(size--) { rt_sem_release(&rx1_sem); } return RT_EOK; } //串口2读取回调函数 rt_err_t usart2_rx_indicate(rt_device_t dev, rt_size_t size) { /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ while(size--) { rt_sem_release(&rx2_sem); } return RT_EOK; } //串口0发送回调函数 rt_err_t usart0_tx_complete(rt_device_t dev, void *pbuf) { rt_sem_release(&tx1_sem); return RT_EOK; } //串口1发送回调函数 rt_err_t usart1_tx_complete(rt_device_t dev, void *pbuf) { rt_sem_release(&tx2_sem); return RT_EOK; } //串口2发送回调函数 rt_err_t usart2_tx_complete(rt_device_t dev, void *pbuf) { rt_sem_release(&tx3_sem); return RT_EOK; } //串口初始化 void usart_dev_init(void) { rt_err_t res,res1; dev_uart1 = rt_device_find("uart0"); dev_uart2 = rt_device_find("uart1"); dev_uart3 = rt_device_find("uart2"); //串口0初始化 if (dev_uart1 != RT_NULL) { //设置设备接收回调函数 res = rt_device_set_rx_indicate(dev_uart1, usart_rx_indicate); if (res != RT_EOK) { rt_kprintf("set uart0 rx indicate error.%d\n",res); } //设置设备发送回调函数 res = rt_device_set_tx_complete(dev_uart1,usart0_tx_complete); if (res != RT_EOK) { rt_kprintf("set uart0 tx indicate error.%d\n",res); } //打开设备 res = rt_device_open(dev_uart1, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX ); if (res != RT_EOK) { rt_kprintf("open uart0 device error.%d\n",res); } } else { rt_kprintf("can't find uart0 device.\n"); } //串口1初始化 if (dev_uart2 != RT_NULL) { res1 = rt_device_set_rx_indicate(dev_uart2, usart1_rx_indicate); if (res1 != RT_EOK) { rt_kprintf("set uart1 rx indicate error.%d\n",res); } //设置设备发送回调函数 res1 = rt_device_set_tx_complete(dev_uart2,usart1_tx_complete); if (res1 != RT_EOK) { rt_kprintf("set uart0 tx indicate error.%d\n",res); } res1 = rt_device_open(dev_uart2, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX ); if (res1 != RT_EOK) { rt_kprintf("open uart1 device error.%d\n",res); } } else { rt_kprintf("can't find uart1 device.\n"); } //串口2初始化 if (dev_uart3 != RT_NULL) { //设置设备接收回调函数 res = rt_device_set_rx_indicate(dev_uart3, usart2_rx_indicate); if (res != RT_EOK) { rt_kprintf("set uart2 rx indicate error.%d\n",res); } //设置设备发送回调函数 res = rt_device_set_tx_complete(dev_uart3,usart2_tx_complete); if (res != RT_EOK) { rt_kprintf("set uart2 tx indicate error.%d\n",res); } //打开设备 res = rt_device_open(dev_uart3, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX ); if (res != RT_EOK) { rt_kprintf("open uart2 device error.%d\n",res); } } else { rt_kprintf("can't find uart2 device.\n"); } } void usart0_rx_thread_entry(void *p) { /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ while(rt_sem_take(&rx0_sem,RT_WAITING_FOREVER) == RT_EOK) { int len=0; do { // recv usart0 len=rt_device_read(dev_uart1, 0, rx_buf, RX_BUF_SIZE/2); if(len) { send(tcpserver_connected, rx_buf, len, 0); } }while( len != 0); } rt_kprintf("Error taking semaphore, usart0 rx exit!\n"); } void usart1_rx_thread_entry(void *p) { /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ while(rt_sem_take(&rx1_sem,RT_WAITING_FOREVER) == RT_EOK) { int len=0; do { // recv usart1 len=rt_device_read(dev_uart2, 0, rx1_buf, RX_BUF_SIZE/2); if(len) send(tcpserver1_connected, rx1_buf, len, 0); }while( len != 0); } rt_kprintf("Error taking semaphore, usart1 rx exit!\n"); } void usart2_rx_thread_entry(void *p) { /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ while(rt_sem_take(&rx2_sem,RT_WAITING_FOREVER) == RT_EOK) { int len=0; do { // recv usart2 len=rt_device_read(dev_uart3, 0, rx2_buf, RX_BUF_SIZE/2); if(len) send(tcpserver2_connected, rx2_buf, len, 0); }while( len != 0); } rt_kprintf("Error taking semaphore, usart2 rx exit!\n"); } //////////////////////////////////////////////////////////////////////// // Init all ipc objects. CPU性能=IPC(CPU每一时钟周期内所执行的指令多少)×频率(MHz时钟速度) static void ipcs_init(void) { rt_sem_init(&rx0_sem,"semrx0",0,RT_IPC_FLAG_FIFO); //串口0读 信号量 rt_sem_init(&rx1_sem,"semrx1",0,RT_IPC_FLAG_FIFO); //串口1读 信号量 rt_sem_init(&rx2_sem,"semrx2",0,RT_IPC_FLAG_FIFO); //串口2读 信号量 rt_sem_init(&tx1_sem,"semtx0",1,RT_IPC_FLAG_FIFO); //串口0发 信号量 rt_sem_init(&tx2_sem,"semtx1",1,RT_IPC_FLAG_FIFO); //串口1发 信号量 rt_sem_init(&tx3_sem,"semtx2",1,RT_IPC_FLAG_FIFO); //串口1发 信号量 } //线程初始化 static void threads_init(void) { rt_thread_t usart0_rx_thread; rt_thread_t usart1_rx_thread; rt_thread_t usart2_rx_thread; rt_thread_t svr_task_thread; // USART0 rx thread. rx is interrupt. usart0_rx_thread = rt_thread_create("urx0",usart0_rx_thread_entry, RT_NULL,1024, 3, 5); rt_thread_startup(usart0_rx_thread); // USART1 rx thread. rx is interrupt. usart1_rx_thread = rt_thread_create("urx1",usart1_rx_thread_entry, RT_NULL,1024, 3, 5); rt_thread_startup(usart1_rx_thread); // USART2 rx thread. rx is interrupt. usart2_rx_thread = rt_thread_create("urx2",usart2_rx_thread_entry, RT_NULL,1024, 3, 5); rt_thread_startup(usart2_rx_thread); // TCP server init thread. svr_task_thread = rt_thread_create("svr_task",svr_task_thread_entry,RT_NULL,2048, 7, 10); if ( svr_task_thread != RT_NULL) { rt_thread_startup( svr_task_thread); rt_kprintf("svr_task\n"); } } //应用初始化 void apps_init(void) { // ipc 初始化 ipcs_init(); //串口初始化 usart_dev_init(); //线程初始化 threads_init(); } 里面有串口123的线程,可以略过,求大佬解惑 这个错误是啥原因
查看更多
2
个回答
默认排序
按发布时间排序
FengRX
2021-03-02
这家伙很懒,什么也没写!
有时候通信3个小时才出问题,有时候通信一天才出问题
sync
2021-03-03
这家伙很懒,什么也没写!
没用1.4.1,有可能是lwip参数配置不合适,建议打开lwip调试,一点点查吧
撰写答案
登录
注册新账号
关注者
0
被浏览
1.6k
关于作者
FengRX
这家伙很懒,什么也没写!
提问
5
回答
5
被采纳
0
关注TA
发私信
相关问题
1
studio建立f429工程使用 lwip 运行错误
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
2
RT-Thread EtherKit开源以太网硬件正式发布
3
如何在master上的BSP中添加配置yml文件
4
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
5
RT-Thread 发布 EtherKit开源以太网硬件!
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
MicroPython
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
15
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部