Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Network
CME-M7
【已解决】CME-M7芯片RTT+LWIP求助[遗留一个8小时固定死机问题]
发布于 2015-04-03 12:17:56 浏览:8355
订阅该版
我是一个撸代码的,本职是进行上层软件开发,最近使用RTT+LWIP搭建一个通过FIFO串口、TCP音频网络传输系统。 使用了以下几个方案: 1、建立1个socket,通过2个独立线程对这个socket分别进行发、收。发送实时性好,不定时死机(运行灯闪烁,网络芯片没有挂,推测是RTT挂了),没有任何错误信息打印。 eg: ```c int sock; tid_audio = rt_thread_create("audio_recv", init_tcp_recv, &sock, 2048, THREAD_PRIORITY+1, THREAD_TIME); tid_audio = rt_thread_create("audio_send", init_tcp_send, &sock, 2048, THREAD_PRIORITY+1, THREAD_TIME); ``` 问题:进行了2种单线程收,单线程发的测试,没有死机现象。那么我可以认为RTT对多线程操作单个socket读写是有缺陷的? 2、建立2个socket,通过2个独立线程分别进行发、收。暂时没有死机情况,实时性差,音频有卡顿现象。修改建立线程时的优先级和时间,略有改善。 问题:由问题1我进行了程序优化,避免了多线程操作同一个socket的情况,但是音频实时性显著下降(声音有明显的顿感,并不是收发不同步),因为我不了解操作系统对线程的调度方式,从1和2体现的问题来看,我个人已经一头雾水了。 不知道大家有没有遇到过同类的问题?个人觉得RTT是一个不错的操作系统,但是有一些细节上的东西,并没有文档能说明的很详细?
查看更多
27
个回答
默认排序
按发布时间排序
aozima
2015-04-03
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
收发音频不需要buffer吗?
toasun
2015-04-03
这家伙很懒,什么也没写!
>收发音频不需要buffer吗? 下面这个程序是问题2里的,我个人感觉能用的……其他程序也类似。 ```c #define THREAD_TIME 1 #define THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX - 2) ``` ```c tid_audio = rt_thread_create("audio_int", init_tcp_recv, RT_NULL, 2048, THREAD_PRIORITY+1, THREAD_TIME); if (tid_audio != RT_NULL) rt_thread_startup(tid_audio);[/code] [code]//tcp连接线程 static void init_tcp_send(void* parameter) { struct sockaddr_in local_addr,server_addr; int sock_audio_send = -1; int val = SO_KEEPALIVE; int keepIdle = 2; // 如该连接在2秒内没有任何数据往来,则进行探测 int keepInterval = 1; // 探测时发包的时间间隔为1 秒 int keepCount = 3;// 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发. //建立开关socket server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port_audio); server_addr.sin_addr.s_addr = inet_addr(server_ip); //使用INADDR_ANY 指示任意地址 rt_memset(&(server_addr.sin_zero),0,sizeof(server_addr.sin_zero)); //接收客户端 while(1) { //通道没有全部退出不接收客户端 if (lock_send_audio == 1) { rt_thread_delay(DELAY_TIME); continue; } else if (lock_send_audio == 0) { #ifdef DBG rt_kprintf("set up send! "); #endif //通道全部退出,释放已结束的socket if ( sock_audio_send!= -1) { #ifdef DBG rt_kprintf("close sock_audio_send socket! "); #endif lwip_close(sock_audio_send); sock_audio_send = -1; } //建立新socket sock_audio_send = socket(AF_INET, SOCK_STREAM, 0); if(sock_audio_send == -1) { rt_kprintf("sock_audio_send error "); rt_thread_delay(DELAY_TIME); continue; } //心跳帧 setsockopt(sock_audio_send, SOL_SOCKET, SO_KEEPALIVE, &val, 4); setsockopt(sock_audio_send, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle)); setsockopt(sock_audio_send, IPPROTO_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval)); setsockopt(sock_audio_send,IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount)); //打开开关量发送线程 while (1) { if (connect(sock_audio_send, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { rt_kprintf("connect sock_audio_send faild! "); rt_thread_delay(DELAY_TIME); continue; } break; } rt_kprintf("sock_audio_send: %d! ",sock_audio_send); lock_send_audio = 1; //hl_thread_start(&sock_audio_send,SEND_AUDIO); send_audio_thread(&sock_audio_send); } } } //音频发送线程 static void send_audio_thread(void* parameter) { int sock = *(int *)parameter; int i; int ret; rt_err_t result; uint32_t *buf_audio; uint8_t buf[(BUFF_AUDIO_LEN+4)*4]; uint8_t signal; lock_send_audio = 1; buf_audio = (uint32_t *)buf; #ifdef DBG rt_kprintf("send_audio_thread enter: %d ",sock); #endif buf_audio[0] = 0x01eeeeee; buf_audio[1] = 0x00000004;//保留2开关量1数量1 buf_audio[2] = 0x00000000;//时间2保留2 buf_audio[BUFF_AUDIO_LEN+3] = 0xdddddd00; while(1) { buf_audio[2] += (0x0001<<16);//时间累加 signal = GPIO_getBits(KGL_IN_0) + GPIO_getBits(KGL_IN_1)*2 + GPIO_getBits(KGL_IN_2)*4 + GPIO_getBits(KGL_IN_3)*8; buf[8] = signal; //连接服务器 fp0_int_enable(); result=rt_sem_take(&sem_fifo_a,RT_WAITING_FOREVER); if(result==RT_EOK) { for(i = 3;i < BUFF_AUDIO_LEN+3;i+=2) { buf_audio[i] = FIFO_AHB_a->fifo_data; buf_audio[i+1] = FIFO_AHB_c->fifo_data; //test //FIFO_AHB_b->fifo_data = fifo_ram_a[i]; } ret = send(sock,(uint8_t*)buf,(BUFF_AUDIO_LEN+4)*4,0); if(ret < 0) { rt_kprintf("send_audio_thread lost connection! "); break; } } fp0_int_enable();//开FIFO中断 } #ifdef DBG rt_kprintf("send_audio_thread.....leave. "); #endif lock_send_audio = 0; }; ```
bernard
2015-04-03
这家伙很懒,什么也没写!
"通过2个独立线程对这个socket分别进行发、收。" 这个就不对了,lwIP不支持多线程操作一个socket。
toasun
2015-04-03
这家伙很懒,什么也没写!
>"通过2个独立线程对这个socket分别进行发、收。" 这个就不对了,lwIP不支持多线程操作一个socket。 --- 是的,所以我在第二种情况也说了我的问题……网络是没有问题了,感觉线程的执行效率出问题了?
bernard
2015-04-03
这家伙很懒,什么也没写!
可以用select来操作,不是类似你这样去使用。
toasun
2015-04-03
这家伙很懒,什么也没写!
>可以用select来操作,不是类似你这样去使用。 --- 好的,我正想尝试一下。
toasun
2015-04-07
这家伙很懒,什么也没写!
>可以用select来操作,不是类似你这样去使用。 现在非阻塞操作基本完成了,问题的原因有几个: 1、接收的时候 ```c recv(sock,buf_recv,BUFF_MAX_RECV,MSG_DONTWAIT); ``` 如果我实际发送的数据长度为400(没有强制不拼包),BUFF_MAX_RECV如果没有足够大,在没有强制不拼包的时候会出错,具体原因我也没有再仔细研究,这里会让系统直接跑飞。不知道有教主能给我解释一下吗? 2、处理异常断线的时候,我采用下面的方法 ```c ret = send(sock,buf_send,(BUFF_AUDIO_LEN+4)*4,MSG_DONTWAIT); if(ret != (BUFF_AUDIO_LEN+4)*4)//发送数据长度错误 { #ifdef DBG rt_kprintf("send_audio: send len %d ",ret); #endif fail_count ++; //错误100次认为断开连接 if (fail_count > 100) { #ifdef DBG rt_kprintf("send_audio: send %d times ",fail_count); #endif lock_audio_recv = 0; } } else { fail_count = 0; } ``` 然后调用`lwip_close()`函数,但是我发现每次成功断开,建立新的socket重连的时候产生了如下错误(警告?),但是仍然成功建立了连接并可以成功收发了: `memp_malloc: out of memory in pool TCP_SEG` 我看了半天,没有具体看到这里是socket建立时申请套接字资源的内存错误还是程序中申请接收发送buffer的错误? 好像并不是个错误,是我打开了lwip的dbg信息~ 好了,接下来进行压力测试看看~
amsl
2015-04-08
这家伙很懒,什么也没写!
判断链接是否断了,是否使用心跳机制较好,就像人的心跳停了,这个人可能死了。断开链接后还要回收所有资源。
小ARM菜菜
2015-04-13
这家伙很懒,什么也没写!
这个多线程操作一个socket并非一定使用selcet.我就讨厌这个风格。后来采取了世纪华联的建议。开启TCPIP的LOCK。目前测试比较OK。这个收发主要是阻塞在一个信号量上,加锁后相当于互斥了。就不死了。 不是RTT死掉。可能是LWIP挂了吧,再查查
小ARM菜菜
2015-04-13
这家伙很懒,什么也没写!
断线检测这个最好用keepalive我认为的
撰写答案
登录
注册新账号
关注者
0
被浏览
8.4k
关于作者
toasun
这家伙很懒,什么也没写!
提问
1
回答
15
被采纳
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
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
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
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
a1012112796
13
个答案
1
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部