Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Network
lwip组件问题,在多个平台上都发现问题
发布于 2019-04-27 03:07:13 浏览:5356
订阅该版
rtt版本:4.0 lwup版本:1.4.1/2.1.0 测试平台:STM32H743(采用rtt的网卡驱动)/TM4C129(采用rtt的网卡驱动)/STM32F429(外挂SPI网卡,自己的驱动)。 测试方法:开发板做server,阻塞等待链接,收到一个链接后开一个线程处理链接收据,处理方式为数据回环,收啥回啥。 碰到的问题:我测试的时候用4路client链接开发板,每路client间隔100ms发送1024字节,一开始的时候都正常,跑几分钟就会报错 pbuf_free: p->ref > 0 Assertion: 753 in ..\..\components
et\lwip-2.1.0\src\core\pbuf.c, thread tcpip (0) assertion failed at function:sys_arch_assert, line number:631 STM32H743和TM4C129都会有这个问题,这两个都是自带网卡用的rtt驱动,但是STM32F429我用了一个外挂的SPI网卡采用查询式接收就没问题 都是用的一样的测试程序,只是LWIP网卡驱动不同。 是否是中断式接受产生的问题?找了好久定位到pbuf后就找不下去了,貌似是pbuf调用冲突引起的。
查看更多
35
个回答
默认排序
按发布时间排序
armink
2019-04-27
这家伙很懒,什么也没写!
可以在 menuconfig 中打开 lwip 调试日志,这样能看到更多错误日志信息
还没想好
2019-04-27
这家伙很懒,什么也没写!
看起来像是 pbuf 重复释放了,楼主是不是在驱动中有释放 pbuf?看看释放 pbuf 的地方逻辑是否合理。检测 pbuf 已经上报到协议栈后,驱动释放 pbuf 的问题
xiaoqi
2019-04-27
这家伙很懒,什么也没写!
>看起来像是 pbuf 重复释放了,楼主是不是在驱动中有释放 pbuf?看看释放 pbuf 的地方逻辑是否合理。检测 pb ... --- 驱动我没改,用的RTT自带的,所以怀疑RTT这个驱动有问题,只连接1路socket跑了一晚上没问题,只要一连接多路过一会就死机了
tsx1983
2019-04-27
这家伙很懒,什么也没写!
曾经一个客户也遇到过,单路可以,多路不行,那时候还是用的1.4.1版本
xiaoqi
2019-04-27
这家伙很懒,什么也没写!
>曾经一个客户也遇到过,单路可以,多路不行,那时候还是用的1.4.1版本 --- 貌似和版本关系也不大,1.4.1以及2.1.0我都碰到这个问题,不同平台也都有这个问题,如果用外挂SPI网卡就不会有这个问题,当然SPI网卡驱动是自己在项目上用的。所以说LWIP应该也没问题。
bernard
2019-04-27
这家伙很懒,什么也没写!
可以提供复现的测试代码吗?
xiaoqi
2019-04-27
这家伙很懒,什么也没写!
>可以提供复现的测试代码吗? --- /* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2009-01-05 Bernard the first version * 2014-04-27 Bernard make code cleanup. * 2017-08-25 LongfeiMa transplantation for stm32h7xx */ #include
#include
#include
#include
//#include
#include
#include "netdb.h" //#include "netif/ethernetif.h" #define BUFSZ (4096) static void rt_tcpclientthread_entry(void *parameter) { int *connected=(int *)parameter; uint16_t bytes_received; char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */ int ret; if(connected==NULL) { return; } recv_data = rt_malloc(BUFSZ + 1); /* 分配接收用的数据缓冲 */ if (recv_data == RT_NULL) { rt_kprintf("No memory\n"); return; } /* 客户端连接的处理 */ while (1) { /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */ bytes_received = recv(*connected, recv_data, BUFSZ, 0); if (bytes_received < 0) { /* 接收失败,关闭这个connected socket */ closesocket(*connected); rt_free(connected); rt_free(recv_data); return; } else if (bytes_received == 0) { /* 打印recv函数返回值为0的警告信息 */ rt_kprintf("\nReceived warning,recv function return 0.\r\n"); closesocket(*connected); rt_free(connected); rt_free(recv_data); return; } /* 有接收到数据,把末端清零 */ recv_data[bytes_received] = '\0'; if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0) { /* 如果是首字母是q或Q,关闭这个连接 */ closesocket(*connected); rt_free(connected); rt_free(recv_data); return; } else if (strcmp(recv_data, "exit") == 0) { /* 如果接收的是exit,则关闭整个服务端 */ closesocket(*connected); rt_free(connected); rt_free(recv_data); return; } else { /* 在控制终端显示收到的数据 */ //rt_kprintf("RECEIVED DATA = %s \n", recv_data); /* 发送数据到connected socket */ ret = send(*connected, recv_data, bytes_received, 0); if (ret < 0) { /* 发送失败,关闭这个连接 */ closesocket(*connected); rt_free(connected); rt_free(recv_data); rt_kprintf("\nsend error,close the socket.\r\n"); return; } else if (ret == 0) { /* 打印send函数返回值为0的警告信息 */ rt_kprintf("\n Send warning,send function return 0.\r\n"); } } } } static void rt_tcpserv_thread_entry(void *parameter) { int opt = 1; socklen_t sin_size; int sock; char name[10]; rt_thread_t client_thread; int *socket_client; struct sockaddr_in server_addr, client_addr; rt_bool_t stop = RT_FALSE; /* 停止标志 */ /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* 创建失败的错误处理 */ rt_kprintf("Socket error\n"); return; } /* 初始化服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(20108); /* 服务端工作的端口 */ server_addr.sin_addr.s_addr = htons(INADDR_ANY); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); /* 绑定socket到服务端地址 */ if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { /* 绑定失败 */ rt_kprintf("Unable to bind\n"); return; } /* 在socket上进行监听 */ if (listen(sock, 5) == -1) { rt_kprintf("Listen error\n"); /* release recv buffer */ return; } rt_kprintf("\nTCPServer Waiting for client on port 5000...\n"); while (stop != RT_TRUE) { sin_size = sizeof(struct sockaddr_in); socket_client=rt_malloc(sizeof(int)); /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */ *socket_client = accept(sock, (struct sockaddr *)&client_addr, &sin_size); /* 返回的是连接成功的socket */ if (*socket_client < 0) { rt_free(socket_client); rt_kprintf("accept connection failed! errno = %d\n", errno); continue; } setsockopt(*socket_client, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(int)); /* 接受返回的client_addr指向了客户端的地址信息 */ rt_kprintf("I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); sprintf(name,"client_%d",*socket_client); client_thread = rt_thread_create(name, rt_tcpclientthread_entry, (int *)socket_client, 4096, 15, 20); rt_thread_startup(client_thread); } } int main(void) { rt_thread_t tcpserv_thread; tcpserv_thread = rt_thread_create("socket_server", rt_tcpserv_thread_entry, RT_NULL, 4096, 20, 20); if (tcpserv_thread != RT_NULL) rt_thread_startup(tcpserv_thread); return 0; }
bernard
2019-04-27
这家伙很懒,什么也没写!
注意下,如果是H7,底层驱动是需要考虑cache的。stm32f4平台的,后面会进行测试下
xiaoqi
2019-04-27
这家伙很懒,什么也没写!
>注意下,如果是H7,底层驱动是需要考虑cache的。stm32f4平台的,后面会进行测试下 > ... --- 解决了,把网卡接收函数改了一下没再出现这个问题,具体为啥我还是不太清楚,屏蔽掉的是原来rtt自带的,下面那一段是我自己加上的,测了三四个小时了,没再出现那个问题 /* reception packet. */ struct pbuf *rt_lan8742_rx(rt_device_t dev) { struct pbuf* p = RT_NULL,*q; ETH_BufferTypeDef RxBuff; uint32_t framelength = 0; uint32_t curr_len=0; /* lock LAN8742 device */ rt_sem_take(&sem_lock, RT_WAITING_FOREVER); /* Clean and Invalidate data cache */ SCB_CleanInvalidateDCache(); if(HAL_ETH_GetRxDataBuffer(&EthHandle, &RxBuff) == HAL_OK) { // HAL_ETH_GetRxDataLength(&EthHandle, &framelength); // p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, framelength); // if(current_pbuf_idx < (ETH_RX_DESC_CNT -1)) // { // current_pbuf_idx++; // } // else // { // current_pbuf_idx = 0; // } HAL_ETH_GetRxDataLength(&EthHandle, &framelength); if(framelength!=0) { p = pbuf_alloc(PBUF_TRANSPORT, framelength, PBUF_RAM);//申请存储空间 if(p != NULL) { q = p; while(q != NULL) { memcpy(q->payload,RxBuff.buffer+curr_len,q->len); curr_len+=q->len; q=q->next; } } } } HAL_ETH_BuildRxDescriptors(&EthHandle); /* unlock LAN8742 device */ rt_sem_release(&sem_lock); return p; }
bernard
2019-04-28
这家伙很懒,什么也没写!
所以依然还是在驱动上?或者,HAL_ETH_GetRxDataLength有可能出现返回0程度的?
撰写答案
登录
注册新账号
关注者
0
被浏览
5.4k
关于作者
xiaoqi
这家伙很懒,什么也没写!
提问
3
回答
18
被采纳
0
关注TA
发私信
相关问题
1
lwip1.4.1连接经常会断开无法连接上,可以ping通
2
LPC1768:RTT+LWIP+webserver用IE刷网页出现硬件中断错误(已经解决)
3
求一些LWIP开发的经验,目前ping一直不稳定。
4
stm32f207+dp83848无法ping通
5
RTT下的LWIP传递机制
6
rtt内lwip的socket是否是线程安全?
7
Lwip+enc28j60无法ping通
8
坑爹的rtconfig.h lwip关掉了checksum
9
花了一个晚上,把RT2.0的LWIP、网卡驱动、文件系统整合起来了,发现一点小问题
10
lwip例程中udp发送时如何指定源端口发送到指定目的地端口
推荐文章
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
GD32F450 片内 flash驱动适配
2
STM32H7R7运行CherryUSB
3
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
4
使用RC522软件包驱动FM1722
5
常量数据类型和表达式陷阱分享
热门标签
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
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
YZRD
2
篇文章
3
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部