使用at组件联网,联网不稳定情况下,有数据未发出或接收数据未处理时,在at_clnt线程中占用内存,累加到一定程度导致内存溢出,有什么办法解决吗?
可以参考一下文章 AT组件源码分析 来排查出现错误的原因。
AT组件把收到的数据放到 recvpkt_list
中,每次收到数据都会申请内存,然后把收到的数据挂到链表 recvpkt_list
上,如果长时间不处理的话就会导致这个链表上的内容越来越多,也就是申请的空间越来越多,过多就会出现内存不够的问题。
不知道你的应用是什么样的?为什么会出现一直不接收的情况。
感谢回复,我们分析是底层接收到数据同时判断离线了,离线后应用就不读取数据了,仿真时能看到增加的内存中有平台下发的也有设备上传的数据。
@晒月亮 按照 RTT 的 SAL 层代码逻辑,recv 实际是从单片机的内存中拿数据,分析如下。判断离线后重连服务器,接着 recv 会把上一次没读取的数据读出来。
@晒月亮 或者说一直 recv,一直 recv 到把内存中存储的收到的数据读完为止。因为你不处理收到的数据,收到的数据被AT组件放到了内存中,读出来才能把这部分的内存给释放掉。
@crystal266 联网后应用是一直在读数据的,但是读不出来那些数据,另外未释放内存中的数据不仅有平台下发的,还有设备上报的,能否告知下memtrace看到的at_clnt线程是在哪里存放接收和发送的数据吗
@晒月亮 可以参考一下文章 AT组件源码分析 ,这个详细分析了AT组件的源码,可以看 1.8.3 和 1.8.4 小节。
@晒月亮 简单摘抄一下里面的内容,(AT+SAL组件)对于接收来说收到了服务器下发的消息后,会调用接收的 URC 回调函数
urc_recv_func()
,最终会调用到at_recvpkt_put()
将收到的数据放到recvpkt_list
链表里。recv()
函数最终会调用at_recvpkt_get
从recvpkt_list
链表里面直接把数据取出来。对于发送来说,
send->at_sendto->xxx_socket_send
其中xxx_socket_send
就是封装的具体模组的发送函数,使用串口写AT指令来发送数据,发送不会占用很大内存。@crystal266 👍非常感谢,我们再研究下
@晒月亮 也可以尝试使用 PPP 拨号,不知道你们用的什么模组