完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、硬件平台:原子精英板 stm32f103zet6+esp8266 开发板作为client,网络调试助手模拟server 学习研究AT SOCKET有一段时间了,之前逛论坛提问解决了一些问题。遇到的问题如下: 1、at socket关闭不彻底,导致重连server时,socket连接号一直递增。(已解决) 2、socket连接断开,报错 esp0 device socket(0) wait connect result timeout.(已解决) 3、AT Client接收数据失败,串口获取数据提示超时,该问题会在程序运行一段时间后出现,还未找到原因? [E/at_client] AT Client receive failed, uart device get data error(-2) 4、程序运行一段时间后, 提示 [W/UART] Warning: There is no enough buffer for saving data, please increase the RT_SERIAL_RB_BUFSZ option. 论坛里关于这个问题的回答是:增大缓存、及时处理串口数据、降低串口波特率(目前AT串口波特率115200) 结合调试记录,当出现这个提示后,串口会一直卡在串口中断里,如下图: 针对这个问题,网络调试助手端每隔2秒会下发指令,长度24.目前RT_SERIAL_RB_BUFSZ设置为1024 我觉得增大缓存和降低波特率并不能真正彻底解决问题。还是串口数据处理不及时造成,但我没理解这句话(或者说怎样才算是及时把数据取走了), client端使用的select方式接收数据,按照个人理解,recv接收数据,不就是把数据取走了吗?至于把数据拿去做什么应该和接收没什么关系了。请问这里该如何理解呢? 这个问题的出现最终会导致client再也连不上server。 我的client开了三个线程, A:socket连接状态判断线程 B:接收线程 C:发送线程(发送线程里面模拟了心跳) 线程间通信用的event. 代码如下,可否帮忙看下问题出在哪里 static rt_thread_t tid25 = RT_NULL; static rt_thread_t rx_tid25 = RT_NULL; static rt_thread_t tx_tid25 = RT_NULL; static rt_event_t socket_event = RT_NULL; //socket接收线程 #define CLIENT_THREAD_PRIORITY 25 #define CLIENT_THREAD_STACK_SIZE 1024 #define CLIENT_THREAD_TIMESLICE 10 #define TCPCLIENT_CLOSE (1 << 0) //连接关闭 #define TCPCLIENT_TX (1 << 1) //发送 #define TCPCLIENT_PARSE (1 << 2) //解析接收数据 #define TCPCLIENT_RX_EXIT (1 << 3) //退出接收线程 #define TCPCLIENT_TX_EXIT (1 << 4) //退出发送线程 //连接服务器 static int tcp_connect1(void) {
RECONNETC:
} // 接收线程入口函数 */ static void tcp_rx_thread(void *parameter) {
} // 发送线程入口函数 */ static void tcp_tx_thread(void *parameter) {
} //判断连接状态线程 static void client_connect_state(void *parameter) {
RECONNECT:
} //创建线程 int fnUserClient(void) {
} |
|
相关推荐
10个回答
|
|
1.recv 接口是把数据取走,取走后释放了存储接收到的数据的空间。函数执行如下,接收的 URC 函数将数据放到 recvpkt_list 中,然后 recv() 函数从 recvpkt_list 中取出数据。
#define recv(s, mem, len, flags) sal_recvfrom(s, mem, len, flags, NULL, NULL) // sal_socket/include/socket/sys_socket/sys/socket.h #define recvfrom(s, mem, len, flags, from, fromlen) sal_recvfrom(s, mem, len, flags, from, fromlen) // sal_socket/include/socket/sys_socket/sys/socket.h |-> sal_recvfrom // sal_socket.c |-> SAL_SOCKET_OBJ_GET // sal_socket.c |-> SAL_NETDEV_IS_UP // sal_socket.c |-> SAL_NETDEV_SOCKETOPS_VALID // sal_socket.c |-> pf->skt_ops->recvfrom // sal_socket.c |-> at_recvfrom // at/at_socket/at_socket.c |-> at_get_socket // at/at_socket/at_socket.c |-> at_recvpkt_get(&(sock->recvpkt_list)...) // 从链表中获取数据 at/at_socket/at_socket.c |-> at_recvpkt_node_delete // 从链表中删除数据释放空间 at/at_socket/at_socket.c 2.获取网络的连接状态可以通过读取网络设备的标志位来获取,如下所示。在网络连接时会与 "link.rt-thread.org" 的 8101 端口进行数据收发测试,进而修改网络设备的连接标志,可以参考文章 AT组件源码解析 /** * @Brief 获取esp8266的链接状态 * @Return 无 * @return 成功返回0,失败返回-1 */ int get_esp8266_link_status(void) { /* "esp8266" 名字来源于设备注册时使用的名字,在文件 packages/at_device-latest/samples/at_sample_esp8266.c 中定义 */ struct at_device * esp8266_dev = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, "esp0"); if (esp8266_dev == RT_NULL) { LOG_E("func: %s. get esp8266 at device failed", __FUNCTION__); return -1; } if (esp8266_dev->is_init == RT_FALSE) // 是否初始化 { //LOG_E("%s is not init", "esp0"); return -1; } if (netdev_is_up(esp8266_dev->netdev) == 0) // 网络设备不存在 { return -1; } if (netdev_is_internet_up(esp8266_dev->netdev)) // 判断是否联网 { return 0; } else { return -1; } } |
|
|
|
对于回复的第1点,将接收线程优先级设置最高,及时用recv取走数据,是不应该出现串口溢出的
|
|
|
|
以EC200(AT设备)为例,接收到的数据会调用回调函数 urc_recv_func,在这个函数里面把收到的数据存储到了 recvpkt_list 链表中(动态开辟空间,挂在链表上),读取不读取不会影响存储,回调函数的执行逻辑如下。
urc_recv_func /* at_socket_ec200x.c */ |-> recv_buf = (char *) rt_calloc(1, bfsz); /* 申请空间,供 at_recv_pkt 使用,挂载在 rlist 列表中 */ |-> at_client_obj_recv /* at_client.c */ |-> at_client_getchar /* at_client.c */ |-> at_evt_cb_set[AT_SOCKET_EVT_RECV](socket, AT_SOCKET_EVT_RECV, recv_buf, bfsz); /* at_socket_ec200x.c */ |-> at_recv_notice_cb /* at_socket.c */ |-> at_recvpkt_put(&(sock->recvpkt_list), buff, bfsz); /* at_socket.c */ |-> pkt->buff = (char *) ptr; /* 将buff指向之前申请到的空间at_socket.c */ |-> rt_slist_append /* 挂载到链表中 */ 读取数据就是把链表中的数据取出来,不读取链表中的内容就会越来越多,也就是说收到数据后就把收到的内容开辟出了一块空间存储起来了。 |
|
|
|
另外我觉得你应该提高一下 AT 解析线程的优先级,这个线程里面执行了了 URC 回调函数,而你读取的优先级不用很高
client->parser = rt_thread_create(name, (void (*)(void *parameter))client_parser, client, 1024 + 512, RT_THREAD_PRIORITY_MAX / 3 - 1, 5); |
|
|
|
根据你的答复,继续优化了业务逻辑,就目前的测试效果看没再出现串口溢出提示
[W/UART] Warning: There is no enough buffer for saving data, please increase the RT_SERIAL_RB_BUFSZ option. 但是还是会出现接收数据超时错误 [E/at_client] AT Client receive failed, uart device get data error(-2). [E/at.skt.esp] esp0 device receive size(24) data failed. |
|
|
|
esp8266 和 服务器的通讯过程是怎样的?通讯频率和数据包的大小呢?
|
|
|
|
1、通信链路:开发板客户端<——>ESP8266<——>SERVER 2、数据交互流程 server这边每隔2秒轮询一次开发板数据,指令间发送间隔设的250ms.规定下发指令长度24字节,反馈数据长度42字节。根据server端log,发现读取1号数据时,第一次反馈的数据会丢失几个字节。 |
|
|
|
要是增大轮询周期呢?
|
|
|
|
|
|
|
|
跟一下源码调试一下试试,看看什么问题
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
655 浏览 0 评论
AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV
2448 浏览 0 评论
tms320280021 adc采样波形,为什么adc采样频率上来波形就不好了?
1292 浏览 0 评论
1895 浏览 0 评论
1486 浏览 0 评论
74873 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 18:13 , Processed in 1.009480 second(s), Total 89, Slave 71 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号