异常断链吐血经历!拯救Air780EP模块紧急项目

我最近被老板驱使,要用合宙Air780EP模块做几个紧急项目。由于时间紧任务重,遇到了一些棘手问题,可把我给折腾死了……

这里把遇到的问题,排查记录下来,看能不能帮到因遇到类似的问题,并且一直没找到原因,而被老板要求加班解决的兄弟们。

一、相关背景简介 

不知道各位在用Cat.1模块的时候,会不会遇到收不到网络数据的问题呢?

比如:

"用TCP做长链接,在进入休眠场景后进行保活,但时常出现丢包的现象,应该怎么分析呢"、"MQTT服务器下行数据,模块有概率接收不到,服务器也有遇到收不到模块的上行数据,到底是什么情况"等等类似的问题。

但单纯通过模块这边看到的现象,也不能断定就是模块出了问题。

要想准确地找出这个“罪犯”,这种时候就需要通过网络抓包来分析排查是以下哪种原因:

  • 模块有发出数据->但服务器没收到

  • 模块未发出数据->导致服务器没收到

  • 服务器有发出数据->但模块没收到

  • 服务器未发出数据->导致模块没收到

以下通过最近遇到的一个实例,给各位提供个分析思路。

目前有个项目用的是AT开发,大致应用场景为TCP长链接,要求定时上报GPS/基站/Wi-Fi的定位数据,没有休眠需求。

但时不时在发送数据的时候,会出现AT+CIPSEND发数据发着发着返回+CME: ERROR 3的问题。

基本情况解析:

  • 使用的数据传输协议为TCP

  • 问题现象为偶现,小概率出现

  • 从模块查看到的异常情况为:
    AT+CIPSEND发送TCP数据的指令,出现了+CME: ERROR 3的错误码

首先按照+CME: ERROR 3这个错误码出现的条件,筛选一下可能出现的有哪些情况:

  • 最先想到的就是TCP链接已经不存在,断开了
    导致发送数据时检测TCP通道关闭,而出现AT+CIPSEND命令返回错误。

  • 发送的AT+CIPSEND命令前后携带了其他的字符
    一起作为一整条指令发送给了模块,导致模块解析出错。

AT+CIPSEND这条指令会出现+CME: ERROR 3,基本上就是以上两种情况了。

那么先尝试排除下第二条:

我在偶现第一次AT+CIPSEND出现错误之后,后面也尝试发送了的多条AT+CIPSEND命令发现也都会出错。

但中间穿插发送的AT+CEREG?、AT+CGATT?、AT+CSQ 查网络状态、信号强度的命令返回都正常,也没有报错。

而且把发送的整条数据转为以HEX格式来看,指令前后也没有多余的字符出现。

那可以排除第二种情况了。

接下来这个时候为了印证第一条的猜想,

就需要排查下问题是否为TCP链接已经断开了:

在挂测了一段时间再次复现问题的时候,
加一条AT+CIPSTATUS的命令查一下连接状态。

结果不出所料:

返回的结果是STATE: TCP CLOSED

TCP链接是断开的状态!

已经锁定问题原因是有概率出现TCP突然断链的现象。

由于目前条件抓不了服务器端的网络日志,只能暂且想办法从模块端排查问题。

出现断链也可以分为:
模块端发起断开连接和服务器端发起断开连接。

如果为模块端断接:
可以看下是否有主动发送AT+CIPCLOSE去断开连接,但我从AT流程的日志来看,明显程序中还没有走到AT+CIPCLOSE这一步,问题就已经复现了。

模块端如果没有主动通过指令断开连接:

那么在遇到网络波动、信号差、卡没流量等等,会影响网络的事件时,模块也可能会发起断开连接的请求。

但上面也已经排查过:
在出现AT+CIPSEND返回ERROR之后,
也发送了AT+CEREG?、AT+CGATT?、AT+CSQ这三条指令。

返回结果依次为:
+CEREG: 0,1
+CGATT: 1
+CSQ: 25

可以从CEREG和CGATT的返回结果看出,网络状态是正常已成功注册网络的,CSQ信号值为25,也很正常。

那这到底是怎么回事呢?
这下不得不通过网络抓包来进一步分析了。

二、准备工作要点 

根据项目需求准备相关硬件及软件,以下供参考:

  • 自制板子需要引出USB或者DBG_UART串口,二选一。

    但如果问题是只有在休眠环境下才能复现的,那么只能使用DBG_UART串口,进入休眠后USB要断开会导致抓不到休眠中的日志。

  • 如果使用DBG_UART串口,还需要准备一个高速串口工具(能支持6M波特率,例如ch343、ft4232)。

  • 合宙开发板默认有引出USB和DBG_UART串口,可以直接接线使用。

  • EPAT log工具 EPAT_V1.3.262.573,使用方式本文章也会简单说明,在EPAT软件 Manual 目录中也有一份使用介绍的PDF。

  • Wireshark网络包分析工具:

    下载链接:
    https://www.wireshark.org/

三、怎么抓日志 

3.1 选择正确且合适的日志输出端口

USB的虚拟端口其中有一个为底层日志的输出端口。

可从设备管理器端口属性中“设备实例路径”的值为:
"USB\VID_19D1&PID_0001&MI_04\xxxxxx&0&0004"
锁定到底层日志输出端口是哪一个。

图片

建议使用USB来抓取日志 

优点:USB虚拟端口输出速率很高,所以基本不会出现丢日志的现象;

缺点:连接USB时不会进入休眠。


DBG_UART串口需要以6M波特率输出底层日志,此串口输出的数据要通过EPAT工具才可以解析。

优点:进入休眠的日志也同样可以抓取。

缺点:但因为波特率要求在6M,所以对串口线的要求很高,如果引出的杜邦线太长或者质量不高,也会影响日志输出的数据,导致工具不能正常解析。

3.2 认识EPAT工具中的图标功能

以下从左至右依次介绍:

图片

1)重启模块;

2)勾选选择的端口从其他串口调试工具尝试打开是否可以正常输出数据(正常打开输出的就是乱码);

3)如果使用AT固件,默认DBG_UART端口输出是6M波特率。

可以通过:
AT+ECPCFG=logBaudrate,6000000 指令修改,
波特率设置请不要低于6M,不然很容易出现丢日志、抓的不全。

  • 打开日志文件
    需要在打开EPAT工具时跳出的"Select Data Source"选择框中选择"Select From Local Files",才能点击打开日志文件的功能,可以打开ZIP压缩包和Bin格式的日志文件。

  • 保存日志
    会将已抓取到的日志导出,以ZIP压缩包的方式保存,方便提供给技术同事或研发同事分析。

  • 更新解析日志的数据库文件
    在抓日志的时候,可以不匹配,等在使用EPAT打开日志文件的时候再做匹配解析。

  • 筛选查看日志
    如果不了解,用不到这个功能。

  • 启动开始抓日志
    如果没有日志出来,请检查日志端口有没有选择正确,有没有勾选打开;确认端口正确,也以勾选,还是没有日志出来,请尝试:

  • 暂停日志

  • 停止抓日志
    点击完停止后,就可以选择保存日志,发给技术/研发同事分析了。

  • 清除日志
    建议每次正式准备抓日志前清理一下日志,这样保存出来的日志给技术同事分析会方便很多。

  • 搜索当前view视图的日志内容

  • 设备端口配置界面

3.3 底层日志抓取步骤

3.3.1 打开EPAT工具,抓日志选择第一项“Serial Device”

图片

3.3.2 选择日志端口,准备抓取log

图片

接下来将从选择使用USB的虚拟日志端口 、选择使用DBG_UART串口,以及两个端口都使用的方式,分别进行详细讲解:

3.3.3 选择使用USB的虚拟日志端口

使用USB的虚拟日志端口流程 

  • 打开设备端口配置界面;

  • 关闭或打开端口,如果端口被占用,工具也不会提示"端口已被占用",所以如果发现端口选择正确,并且日志还是没有出来的话,可以确认下日志端口是否有被占用,而导致EPAT没有打开日志端口。

  • Device0、Device1两个复选框,二选其一;

  • 打开日志输出端口和修改波特率的界面:

    选择从设备管理器端口属性中“设备实例路径”的值为:
    "USB\VID_19D1&PID_0001&MI_04\xxxxxx&0&0004"的日志输出端口。

  • USB的虚拟日志端口不用修改波特率。

这时前面流程都走完了,但是发现没有日志出来。

首先可以确认下模块是否开机:

最直接的方式就是量vbat的电压是否在4.3v~3.3v之间,并且看VDD_EXT是否有1.8v或3.3v,电压正常就说明模块是处于开机状态了。

其他类似于看网络灯没亮、USB端口没显示这种条件不够准确,因为这些也会存在其他因素而导致状态不正常。

接下来继续排查,USB虚拟日志端口选择的是否正确:

如果虚拟端口没显示出来:
确认下LuatOS开发程序内,是否调用了"pm.power(pm.USB, false)"关闭usb功能的接口;

AT开发使用AT+ECPCFG?指令查看"usbCtrl"属性的值是否为2,如果是2代表关闭了usb功能,需要手动设置下AT+ECPCFG="usbCtrl",0 将usb功能打开。

然后重启模块,如果还是没有端口显示,就需要从硬件、USB数据线、电脑端口方面排查,先做交叉测试。

有时还遇到过从模块dm、dp飞出的连接线过长,
也会导致usb虚拟端口无法识别不能正常显示:

把dm、dp和usb的连接线整体缩短到30cm左右,端口才能正常显示;但理论上还是要看使用的USB线和杜邦线的传输质量是否优秀。

有时使用Win7/Win8的系统,
遇到怎么着都出不来USB的虚拟端口:

原因是Air780E模块的USB驱动使用的是微软系统自带的USB驱动,所以仅支持在Win10和Win11上驱动。

如果是Win10/Win11上面的方法都尝试过,端口也依然没有出来,也不妨用另一台电脑试一下看看是否是驱动问题,可能电脑上装的Win10系统是简装版,缺少了一些驱动。

3.3.4 选择使用DBG_UART串口

 使用DBG_UART串口流程  

  • 抓日志用的USB转TTL的串口工具需要支持6M波特率,电脑上并且装了对应串口工具用到的驱动(一般从网络上或者购买商家那里,可以了解到需要用什么驱动);

  • 打开设备端口配置界面;

  • 关闭或打开端口:

    如果端口被占用,工具也不会提示"端口已被占用",所以如果发现端口选择正确,并且日志还是没有出来的话,可以确认下日志端口是否有被占用,而导致EPAT没有打开日志端口。

  • Device0、Device1两个复选框,二选其一;

  • 打开日志输出端口和修改波特率的界面;

  • 选择日志输出端口;

  • DBG_UART端口波特率输出可手动写入修改为6000000(6M)波特率。

使用DBG_UART串口没输出出来日志,排除步骤和USB也有点相同之处。

首先确认下模块是否开机:

最直接的方式就是量vbat的电压是否在4.3v~3.3v之间,并且看VDD_EXT是否有1.8v或3.3v,电压正常就说明模块是处于开机状态了。

其他类似于看网络灯没亮、USB端口没显示这种条件不够准确,因为这些也会存在其他因素而导致状态不正常。

接下来继续排查,DBG_UART日志串口选择的是否正确:

确认下LuatOS开发程序内是否有通过云编译关闭了uart0的日志输出;

AT开发使用AT+ECPCFG?指令查看,要DBG_UART0输出日志,需要几条指令配置一下:

AT+ECPCFG="logPortSel",1                 

// 只从UART0输出日志

AT+ECPCFG=logBaudrate,6000000       

// 修改日志输出波特率为6M

AT+ECPCFG="logCtrl",2                       

// 输出log等级为ALL,全部任何日志都输出

指令配置完之后重启模块,正常来说日志应该就可以输出了。

如果还是没有日志,尝试用sscom这种串口调试工具打开相同的端口,看下是否有日志输出(正常会输出一堆的乱码);

没有输出的话,就需要排查下打开的端口:

串口接线,比如rx/tx反接一下,有没有短路。

并且如果是从预留的测试点用杜邦线飞出的DBG_UART_TX和DBG_UART_RX,那需要注意杜邦线的长度一定要短,不然也会影响输出的日志出现丢失

3.3.5 进阶玩法--两个端口都使用

没错,还可以同时使用USB的虚拟日志端口和DBG_UART日志串口来抓取日志。

这样做的好处是:
在进入休眠场景的时候,待USB断开,就会用DBG串口输出日志,等模块唤醒时就会重新虚拟出来USB端口,就会从USB的日志口抓取日志。

如果通过DBG_UART串口来抓取非休眠场景的日志:
由于底层业务逻辑过多,各种日志都会长时间大批量输出,只用6M的波特率,还是避免不了可能出现丢日志的情况。

而用串口抓取休眠中的日志时,由于一些底层业务会关闭,输出的日志相对并没有特别频繁,所以在休眠中丢日志概率会小一些。

但两个端口同时使用,
这样就把两个端口的优势都使用上了:

无论是休眠场景还是其他业务逻辑场景,基本上不会出现任何日志丢失的情况,但要求就是两个端口都要有预留出来。

两个端口同时使用流程要点

  • 打开设备端口配置界面;

  • 关闭或打开端口:

    如果端口被占用,工具也不会提示"端口已被占用",所以如果发现端口选择正确,并且日志还是没有出来的话,可以确认下日志端口是否有被占用,而导致EPAT没有打开日志端口。

  • 日志端口可以同时打开两个,一个用模块的DBG_UART端口打开,另一个使用USB的日志输出端口。

AT固件需要设置以下指令(重启生效)才能设置日志端口可以从USB和DBG_UART两个端口输出。

AT+ECPCFG=logPortSel,2               
// USB和DBG_UART都允许输出底层日志

下面两个指令如果不配置,那么插入usb不会进入休眠,配置下面指令之后,相当于就算接入usb也允许进入休眠。

AT+ECPCFG="usbSlpMask",1           
// USB不参与休眠投票

AT+ECUSBSYS="VBUSModeEn",1,"VBUSWkupPad",1     
// usb的vbus引脚不参与休眠投票

  • 打开日志输出端口和修改波特率的界面;

  • 选择日志输出端口;

  • USB的虚拟日志端口不用修改波特率:

  • DBG_UART端口波特率输出可手动写入修改为6000000(6M)波特率。

因为这个项目没有用休眠场景,就直接用USB来抓日志了。

按照上面的流程接上USB,打开日志的虚拟端口,成功看到了有日志出来。下面只需要挂着等问题出现就好了。

有抓过底层日志的朋友肯定想起来,
不是还有一步匹配解析日志的数据库MDB.txt文件吗?

其实如果只是导出pcap看网络包,不需要去匹配数据库文件。

图片

四、导出pcap文件,查看网络抓包 

首先在抓取到复现的日志之后,不要着急,先停止日志打印。

然后在当前是SigLogger视图的日志窗口时,才能看到并点击右上角的SigLog菜单栏。

打开SigLog菜单栏后,点击"Export As pcap file":

选择一个导出路径并起一个文件名称,切记:文件名称不能和当前文件夹内的.pcap名称重复!!!因为导出同名文件,根据提示点击覆盖,但实际上内容却并不会覆盖变化。

随后点击保存,即可导出pcap格式的抓包文件。

图片

五、通过Wireshark开始分析 

好的,网络包也抓到了,调转回来继续分析:

——“TCP长链接,定时上报GPS/基站/wifi的定位数据,没有休眠需求,但时不时在发送数据的时候,会出现AT+CIPSEND发数据发着发着返回+CME: ERROR 3”的问题。

先前文章开头已经分析出是TCP链接出现断开,而导致AT+CIPSEND命令返回+CME: ERROR 3。但还不清楚具体是模块主动断开的,还是服务器端断开的链接。

下面我们就通过导出的pcap文件,打开看一下。

根据日志的时间戳看到复现时间在18:56.24左右,那我们先定位到这个时间附近看一下。

图片

结果确实找到了[FIN,ACK]请求断开连接的网络包,在确认下发出的ip地址是112.74.41.204,目标地址是10.49.81.92

怎么判断哪个是模块,哪个是服务器端呢?
也很简单,还是从上面那张图片举例:

流程中现在有检测如果发现AT+CIPSEND发送失败,
就发送AT+CEREG?、AT+CIPSTATUS
等返回结果为+CEREG:0,1和STATE: TCP CLOSED时,
就重新建立连接。

从AT流程中看出:
在19:00:12时有发送AT+CIPSTART=xxxxxx,xxx,来建立新链接。

从图片中网络包的同一时间19:00:12,也确实出现了[SYN]建立连接的请求,发出的地址是10.49.81.92,那这个就是模块端的IP地址了。

以此推断出:
另一个112.74.41.204就是服务器端的IP地址(一般如果服务器是自己公司建立维护的,可以向自己公司的相关负责的同事询问一下,服务器IP是哪一个)。

既然找出了发出[FIN,ACK]请求断开连接的网络包是112.74.41.204这个服务器端的IP地址,这样就明白了是服务器端主动把链接关闭的。

不过正常来说,被动断开连接模块应该会出现"CLOSED"的URC上报,但为什么没。。。

哦~ 原来有上报啊,是我忘记加在收到CLOSED的URC上报后,尝试重连的逻辑了。

那这个就很简单了,出现断链之后:
先通过AT+CEREG?获取到模块已成功注网的状态,
然后再发送AT+CIPSTART=xxxxxx,xxx做重连。

最终,导致断开连接的这个“罪犯”找到了
——是服务器的问题。

不过我们用的服务器,是老板找的第三方。在拿出这个网络抓包(证据)之后,以为能知道是什么原因呢,结果一直在"踢皮球",说他们也是负责代理,他们也要去确认……

哎,沟通起来那是可真累啊~一整天都过去了,也不知道是啥原因。

由于项目赶时间,解决完这个问题后,又要看下一个问题了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1549010.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习------------------------RNN(循环神经网络)

目录 潜变量自回归模型循环神经网络困惑度梯度剪裁循环神经网络的从零开始实现初始化循环神经网络模型的模型参数初始化隐藏状态创建一个类来包装这些函数该部分总代码 定义预测函数该部分总代码 梯度裁剪定义一个函数在一个迭代周期内训练模型训练函数 循环神经网络的简洁实现…

Redis高级特性及应用

一、Redis慢查询 1.1 Redis命令流程 1.2 慢查询配置: 可以通过以下命令配置慢查询时间阈值(慢查询值得是上图中执行命令的时间,不包含其他时间) config set slowlog-log-slower-than 10000 //单位微秒 config rewrite //写入…

大模型与智能体的市场调研分析

2024年,很多人都在谈论智能体,我老婆这样的美术老师,也让我给她科普一下,于是我花了几天时间,系统学习和深入调研了一下,在此分享给大家。 时代背景 人工智能就像电力一样,如果你的竞争对手正…

木材检测系统源码分享

木材检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

物联网智能项目全面解析

目录 引言 一、物联网概述 1.1 什么是物联网 1.2 物联网的历史与发展 二、物联网智能项目分类 三、关键组件与技术 3.1 传感器和执行器 3.2 连接技术 3.3 数据处理与分析 3.4 用户界面 四、物联网智能项目案例分析 4.1 智能家居 4.2 智慧城市 4.3 工业物联网 4.4…

C# 字符串(String)的应用说明一

一.字符串(String)的应用说明: 在 C# 中,更常见的做法是使用 string 关键字来声明一个字符串变量,也可以使用字符数组来表示字符串。string 关键字是 System.String 类的别名。 二.创建 String 对象的方法说明&#x…

$attrs 和 $listeners

通常情况下,父子组件之间的数据是通过 props 由父向子传递的,当子组件想要修改数据时,则需要通过 $emit 以事件形式交由父组件完成,而这种交互方式只存在于父子组件之间,多层嵌套的时候,处于内层的组件想要…

SQL进阶技巧:如何获取状态一致的分组? | 最大、最小值法

目录 0 需求描述 1 数据准备 2 问题分析 方法1:最大、最小值法(技巧) 方法2:常规思路 3 小结 如果觉得本文对你有帮助,那么不妨也可以选择去看看我的博客专栏 ,部分内容如下: 数字化建设通…

(JAVA)队列 和 符号表 两种数据结构的实现

1. 队列 1.1 队列的概述 队列是一种基于先进先出(FIFO)的数据结构,是一种只能在一端进行插入,在另一端进行删除操作的特殊线性表。 它按照先进先出的原则存储数据,先进入的数据,在读取时先被读出来 1.2 …

【anki】显示 “连接超时,请更换网络后重试” 怎么办

文章目录 前言一、问题描述二、解决方案 前言 在 anki同步 时遇到的问题 一、问题描述 二、解决方案 从电信换为了移动热点,电脑手机都同步成功了

图像超分辨率(SR)

图像超分辨率(Image Super-Resolution, SR)是一种图像处理技术,旨在从低分辨率(LR)图像中恢复出高分辨率(HR)图像。这种技术通过增加图像中的细节和清晰度来提高图像的视觉质量,从而…

Stable Diffusion扩散模型【详解】新手也能看懂!!

前言 文章目录 1、Diffusion的整体过程2、加噪过程 2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程 3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导,需要参考这篇文章: Stable Diffusion扩散模型推导公式的基础知识 1、Diffu…

数据结构 ——— 顺序表oj题:编写函数,删除有序数组中的重复项

目录 题目要求 代码实现 题目要求 一个升序排列的数组 nums ,要求原地删除重复出现的元素,使每个元素只出现一次,并返回删除后数组的新长度,元素的相对顺序应该保持一致 代码实现 代码演示: int removeDuplicate…

你要的Air201录音和播放录音功能?直接拿去!

最近拼拼收到同学们的疑问:Air201是否支持录音、播放录音功能? 必须支持!Air201可是高集成化设计,并且Air201自带了ES8311音频解码芯片(Audio Codec)及MIC麦克,可支持本地的录音功能&#xff1…

SAP Message - self-explanatory 自身说明

SAP Message 解释、创建和应用可见如下文章:SAP Abap】SE91 - SAP MESSAGE 消息类创建与应用-CSDN博客 SE91 SAP消息类型 - tongxiaohu - 博客园 这里主要想聊一下常用的SE91 中不常用的功能 - 自身说明 选项的作用。 以 VF - 004 为例: 我们都知道自…

《凡人歌》中的IT职业启示录

《凡人歌》是由中央电视台、正午阳光、爱奇艺出品,简川訸执导,纪静蓉编剧,侯鸿亮任制片,殷桃、王骁领衔主演,章若楠、秦俊杰、张哲华、陈昊宇主演的都市话题剧 ,改编自纪静蓉的小说《我不是废柴》。该剧于2…

上位机通讯汇川Plc3U和5U

开发过程中需要调用到汇川官网的两个动态库(ModbusTcpAPI.dll;StandardModbusApi.dll) 解压完成后找到上面的动态库复制到自己项目的根目录下面然后就可以进行下一步操作了 UI界面: 通讯类集成了3U和5U的连接断开以及读写方法: public clas…

如何巧妙运用Shell变量:掌握脚本编程的核心技巧

目录 前言一、Shell变量——变量类型1、用户自定义变量2、环境变量用./ 启动脚本文件记得加权限哦 二、Shell变量——变量赋值和访问(一)变量定义(二)变量的使用(三)删除变量(四)添加环境变量(五)内部变量(六&#xff…

开源链动2+1模式AI智能名片小程序源码:放大特色,构建独特竞争力

摘要:本文探讨在当今社会背景下,开源链动21模式AI智能名片小程序源码如何通过坚持与众不同来构建独特竞争力。在信息传播便捷但个体易同质化的时代,拥有特色是脱颖而出的关键,而这种模式下的小程序源码具有独特的发展潜力。 一、引…

有效解决配置管理混乱,麒麟桌面操作系统V10 sp1 2403最新版本推出统一配置系统

了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn 当前桌面操作系统中可通过配置定义的应用有限&a…