
1. 项目概述1.1 EC20模块与quectel-CM是什么做过物联网、车联网、远程数据采集的朋友对EC20这个4G模块应该不陌生。它属于移远Quectel的LTE标准模组系列采用LGA封装板载尺寸紧凑却能提供LTE-TDD/LTE-FDD/UMTS/EVDO/TD-SCDMA等多种制式的网络接入能力。我在实际项目里最常用的是EC20-CE适用于中国大陆运营商和EC20-C适用欧洲频段两者在AT指令集、硬件管脚定义上基本一致只是在支持的频段和认证上有差异。EC20模块本身不带协议栈它本质上是一个“无线调制解调器”你通过串口或者USB发AT指令给它它帮你完成驻网、附着、拨号连接然后把IP数据转发给主机。正因为如此主机侧要完成网络配置、DNS下发、路由表维护等一系列工作而quectel-CM正是移远官方提供的一款连接管理工具。quectel-CM的全称是Quectel Connection Manager它的核心职责就是帮模块完成拨号、获取IP地址、设置DNS、维持链路状态并在掉线时自动重拨。很多工程师用EC20的时候会纠结EC20本身不是支持PPP拨号吗为什么还要用quectel-CM这是因为EC20在USB模式下常用的拨号方式是RNDIS、Gobinet或者QMI这与老式2G/3G模块的PPP拨号完全不同。PPP需要主机侧起pppd进程而EC20走的是高通平台上的QMIQualcomm MSM Interface通道qmi接口比PPP更高效也更稳定。quectel-CM就是封装了这套QMI流程让用户不用自己写内核驱动或反复调AT指令一条命令就能把网拨起来。1.2 这个项目能解决什么问题在实际工业现场中EC20最常见的用法就是接在嵌入式主板比如基于NXP i.MX6ULL、TI AM335x、瑞芯微RK3288等的USB口上通过quectel-CM让整板拥有4G上网能力。调试这个“最后一公里”的过程中我遇到的典型问题包括quectel-CM启动后一直卡在waiting for network、模块能AT通但network一直不可用、DNS解析失败但Ping公网IP却通、掉线后probe次数耗尽导致进程退出等。这篇文章会围绕quectel-CM的启动流程把它每一步做了什么、为什么要这么做、可能卡在哪一条条拆开讲清楚。无论你是第一次用EC20做4G联网还是已经在产品里被“疑似断网”问题折腾过几周这篇文章都能给你提供一套可以照着做的排查思路。2. 整体设计思路与启动流程拆解2.1 quectel-CM的工作模式与源码结构quectel-CM从源码上看是一个Linux用户态程序最早移远把它作为开源参考实现发布在GitHub和官方wiki上源码结构非常清晰主要包含以下几个目录src/主程序源码包括main.c、qmimux.c、qmi_thread.c、network_interface.c等。cm/连接管理核心逻辑处理PDP上下文激活、IP地址获取、DNS配置、路由添加等。at/AT指令通道处理主要用于非QMI方式下的初始化流程。usbnet/USB虚拟网卡的管理负责将模块侧的网络接口与系统路由打通。从使用角度讲quectel-CM有两种典型工作方式一种是直连方式即模块直接作为一个网络接口比如ethX或wwan0出现数据走RNDIS或者Gobinet另一种是QMI方式通过内核的qmi_wwan驱动创建一个网络接口quectel-CM在用户态通过QMI协议与之通信。绝大多数时候我们用的是QMI方式因为qmi_wwan驱动的稳定性和吞吐表现都优于RNDIS尤其是在Linux 4.x以上内核上qmi_wwan已经进入主线基本是即插即认。一个值得注意的细节是quectel-CM启动的第一步不是直接拨号而是先检查当前模块状态、确认SIM卡是否就位、是否已经注册上网络。这个过程看似简单实际却是很多问题的源头尤其是信号弱、SIM卡未插好、SIM卡欠费停机这类问题都会在初始状态检查时暴露出来。2.2 启动流程三段式拆解为了方便记忆和排查我把quectel-CM的启动流程归纳为三个阶段初始化阶段、拨号阶段、网络配置阶段。下面逐个展开。初始化阶段quectel-CM进程起来后第一件事就是打开指定的USB设备节点通常是/dev/ttyUSB2AT端口和/dev/cdc-wdm0QMI端口。它会向AT端口发送AT、ATE0等基础指令确认模块响应正常然后发送ATCPIN?检查SIM卡是否readyATCOPS?看当前是否已经注册到运营商网络ATCSQ读取信号强度。这些操作在源码中对应的是util_open_dev和qc_init函数每一步都有超时判断超时会返回错误并退出。有一个常见坑是很多板子为了省电USB口默认是挂起状态模块上电后没有被系统枚举出来。你直接跑quectel-CM它会报Cant open /dev/ttyUSB2。所以我习惯在启动脚本里先做一次USB设备扫描等ls /dev/ttyUSB*出现设备节点再启动quectel-CM必要时加一个sleep 2等待内核加载驱动。拨号阶段初始化通过后quectel-CM会通过QMI通道发送WDA_SET_DATA_FORMAT、WDS_SET_AUTH_SETTING、WDS_SET_IP_FAMILY等一系列请求协商数据通道格式和鉴权方式。这里最关键的是APN信息和鉴权方式quectel-CM读取配置的顺序是命令行参数优先然后读/etc/quectel-CM/quectel-CM.conf配置文件最后使用内置默认值。默认的APN通常是3gnet或者cmnet具体取决于模块型号。如果你的SIM卡用的APN不是这个需要显式指定。拨号的核心操作是通过WDS_START_NETWORK_INTERFACE请求创建PDP上下文。这个请求里带上APN、用户名密码如果有、IP类型IPv4还是IPv6模块返回一个QMI结果里面包含分配的IP地址、DNS地址等。quectel-CM拿到这些信息后进入下一阶段。网络配置阶段真正让EC20在Linux系统里“通网”的是这个阶段。quectel-CM会通过netlink或者ioctl为qmi_wwan创建的虚拟网卡配置IP地址添加默认路由并把模块下发的DNS写入/etc/resolv.conf。从日志上你能看到类似这样的输出[02-13_10:22:31:740] wwan0: IP address 10.74.28.211 [02-13_10:22:31:740] wwan0: DNS address 114.114.114.114 [02-13_10:22:31:740] wwan0: DNS address 8.8.8.8这里就涉及到很多人在网上搜的那个问题quectel-CM是否会将114.114.114.114写进DNS配置答案是要看模块下发什么DNS。quectel-CM本身不会主动往resolv.conf里塞114.114.114.114它只是把运营商通过QMI下发的DNS地址写入系统。如果你在江苏、浙江一带用电信卡运营商下发的DNS很可能就是114.114.114.114北方联通则可能下发202.106.0.20这类地址。所以如果你发现系统的resolv.conf里出现了114.114.114.114那不是quectel-CM“自带”的而是你所在地区的运营商默认DNS就是它。不过quectel-CM在写入DNS时有一个行为需要注意它默认会“合并”模块下发的DNS和系统原有的nameserver。具体来说源码里有一组dns数组如果模块下发了两个DNS它就把这两个写进resolv.conf如果模块一个DNS都没下发它会使用编译时内置的默认值这个默认值在部分编译版本里确实是114.114.114.114和8.8.8.8。所以你看到114.114.114.114的时候要区分是运营商下发还是quectel-CM兜底写入。区分方法很简单看日志里DNS address ...这一行到底打印了什么。如果是运营商下发的日志会明确打印出来如果日志里没有打印DNS但resolv.conf里却有那就是兜底逻辑生效了。提示有些版本编译时把默认DNS写死为114.114.114.114这是正常现象。如果你公司内部有自建DNS建议在quectel-CM启动脚本里额外覆盖resolv.conf避免模块兜底DNS覆盖你的内网解析配置。2.3 为什么选择quectel-CM而不是纯AT脚本拨号聊到这里有必要解释一下为什么官方推荐用quectel-CM而不是你自己写一个AT指令脚本发ATD*99#走PPP。首先EC20在QMI模式下的拨号流程是完全不同于PPP的QMI是控制面和数据面分离的架构类似智能手机上的Modem通信方式数据的封装解封装由模块内部完成USB网卡只是提供一个通道。PPP拨号方式在EC20上虽然也支持但需要内核配置ppp_deflate、bsd_comp等压缩协议驱动吞吐也受限于PPP帧开销和串口速度实测掉速明显。其次quectel-CM内置了链路监测和自动重拨机制。启动后它会起一个专门的QMI线程周期性发送WDS_GET_PACKET_STATISTICS查询数据流量同时用QMI_WDS_GET_CURRENT_CHANNEL_RATE等指令关注网络状态。一旦发现链路异常或者网络状态变化事件上报比如eNB切换失败、注册状态丢失它会重新执行拨号流程。这一点对于无人值守的工业设备来说非常关键纯AT脚本很难做得这么完整。3. 核心细节解析与实操要点3.1 编译quectel-CM前的准备拿到quectel-CM源码后第一步是检查宿主机或目标板根文件系统里是否已经安装了libqmi。quectel-CM依赖libqmi-glib库这是Freedesktop组织维护的QMI协议实现库。在Ubuntu上安装很简单sudo apt-get install libqmi-glib-dev libqmi-utils如果目标板是交叉编译环境需要把libqmi头文件复制到交叉编译器的sysroot目录确保pkg-config --cflags --libs qmi-glib能正常找到库。然后进入quectel-CM源码目录执行make编译完成后会生成可执行文件quectel-CM。这里有一个编译期细节源码里main.c定义了默认APN、默认DNS等宏如果你想要自定义默认DNS建议在编译前直接改源文件这比事后加命令行参数更省心。比如#define DEFAULT_DNS1 223.5.5.5 #define DEFAULT_DNS2 119.29.29.29改完之后重新make烧到板子上就行。3.2 启动quectel-CM的典型命令与参数生产环境下我推荐的启动方式是配合一个启动脚本或systemd service把quectel-CM做成开机自启。下面给一个完整的启动命令示例./quectel-CM -s cmnet -f /dev/ttyUSB2 -g /dev/cdc-wdm0 各参数含义-s cmnet指定APN为cmnet中国移动物联网卡常用的APN之一。-f /dev/ttyUSB2指定AT指令串口设备节点。-g /dev/cdc-wdm0指定QMI设备节点。-4仅使用IPv4。-6仅使用IPv6如果模块和运营商支持。如果你的模块是EC200或者EC20定制版AT口和QMI口对应的ttyUSB序号可能不同。建议在启动前先执行ls /dev/ttyUSB* ls /dev/cdc-wdm*正常情况下EC20在USB枚举后会生成/dev/ttyUSB0到/dev/ttyUSB3四个节点其中ttyUSB2对应AT口ttyUSB3对应PPP口/dev/cdc-wdm0对应QMI口。有些内核版本还会生成/dev/net/tun或者/dev/wwan0这些都是正常现象。3.3 启动日志逐行解读quectel-CM的日志非常有价值我通常用-v 2参数开启详细日志不同版本日志级别参数略有差异。下面是我从实际板子上抓的一段启动日志逐行注释[02-13_10:22:28:451] Get clientWDS success. -- 获取WDS服务客户端成功 [02-13_10:22:28:460] Get clientDMS success. -- 获取DMS服务客户端成功 [02-13_10:22:28:460] Get clientNAS success. -- 获取NAS服务客户端成功 [02-13_10:22:28:461] Get clientUIM success. -- 获取UIM服务客户端成功 [02-13_10:22:28:466] Get clientWDA success. -- 获取WDA服务客户端成功 [02-13_10:22:28:468] request base version... [02-13_10:22:28:470] request nas version... [02-13_10:22:28:472] request wds version...这些行表示quectel-CM在和模块通过QMI总线“握手”获取各服务模块的版本信息。如果卡在这一步通常意味着QMI通道没建立起来或者模块固件太老不支持QMI需要检查/dev/cdc-wdm0是否存在以及内核是否加载了cdc_mbim、qmi_wwan驱动。接下来是关键部分[02-13_10:22:29:012] wwan0: IPv4 address 10.74.28.211 [02-13_10:22:29:012] wwan0: IPv4 subnet 255.255.255.255 [02-13_10:22:29:012] wwan0: IPv4 gateway 10.74.28.211 [02-13_10:22:29:012] wwan0: DNS address 114.114.114.114 [02-13_10:22:29:012] wwan0: DNS address 8.8.8.8这里注意IPv4 gateway和IPv4 address是一样的这是运营商网络在QMI拨号方式下的常见表现网关就是模块自己所有流量通过模块转发。看到这一段日志说明PDP上下文已经激活成功参数也拿到了网络配置马上生效。最后是路由配置输出[02-13_10:22:29:014] Set default route interface is wwan0 [02-13_10:22:29:014] Set netmask is 255.255.255.255此时如果执行ip addr show wwan0应该能看到IP地址已经配置上去了执行ip route应该能看到一条默认路由指向wwan0。从这条日志往下quectel-CM就进入了周期巡检状态。3.4 一个隐藏的启动参数-n与-pquectel-CM在较新版本里增加了几个不太好找的启动参数其中-n表示禁止修改路由表-p表示禁止修改resolv.conf。如果你的板子上有多个网络接口不希望quectel-CM把默认路由抢过去就用-n参数。我曾经在一个同时有以太网和4G的网关设备上调试eth0是本地局域网口如果quectel-CM把默认路由改成wwan0局域网里的机器就上不了外网了因为回程路由不对加上-n参数后只做拨号不碰路由问题立刻解决。同理-p参数适用于你的系统里跑着dnsmasq、systemd-resolved这类DNS管理程序的情况。quectel-CM直接改resolv.conf会和systemd-resolved的”符号链接“机制冲突导致DNS配置不生效或者被覆盖。加-p跳过resolv.conf修改改为在启动脚本里用resolvectl或者手动写resolv.conf。4. 实操过程与核心环节实现4.1 快速复现从零开始让EC20连上网络为了方便大家对照我把整个流程整理成一份可直接执行的步骤清单。步骤1硬件连接与驱动确认把EC20模块通过USB接上主板上电后执行dmesg | grep -i qmi dmesg | grep -i usb正常情况下能看到类似qmi_wwan 1-1:1.4: cdc-wdm0: USB QMI wwan device的输出。如果只看到USB枚举信息而没有qmi_wwan说明内核没有编译qmi_wwan驱动需要重新配置内核Device Drivers - Network device support - USB Network Adapters - QMI WWAN driver supportEC20也可以走RNDIS方式但qmi_wwan是性能最稳的路线我建议优先保证这个驱动。步骤2检查AT口和SIM卡状态echo -e ATI\r /dev/ttyUSB2 cat /dev/ttyUSB2或者用minicom/picocom连接ttyUSB2波特率默认115200发送ATI能看到模块型号。然后发送ATCPIN?返回READY表示SIM卡正常发送ATCSQ返回值第一个数字大于10说明信号可用数值范围0-31越大越好发送ATCOPS?看是否返回运营商名称和注册状态。步骤3编译并启动quectel-CM这一步在前面已经详细说过直接给一个最小化流程cd quectel-CM make ./quectel-CM -s cmnet -f /dev/ttyUSB2 -g /dev/cdc-wdm0 -4看到日志里出现wwan0: IPv4 address ...时开另一个终端执行ping -I wwan0 223.5.5.5如果能通说明网络链路已经打通。然后测试DNSping www.baidu.com如果域名能解析说明DNS配置正常工作。4.2 写一个systemd service实现开机自启裸跑quectel-CM只适合调试量产设备肯定要把它做成服务。下面是我实际在用的一套systemd service配置已经过多个项目验证。[Unit] DescriptionQuectel CM 4G Connection Manager Afternetwork.target Wantsnetwork.target [Service] Typeforking ExecStartPre/bin/sh -c while [ ! -e /dev/ttyUSB2 ]; do sleep 1; done ExecStartPre/bin/sh -c while [ ! -e /dev/cdc-wdm0 ]; do sleep 1; done ExecStart/usr/bin/quectel-CM -s cmnet -f /dev/ttyUSB2 -g /dev/cdc-wdm0 -4 Restarton-failure RestartSec10 KillModecontrol-group TimeoutStartSec120 [Install] WantedBymulti-user.target这里几个要点ExecStartPre里加了设备节点等待循环因为模块枚举需要几秒钟不等待的话quectel-CM会直接报“设备打开失败”退出。Typeforking是因为quectel-CM启动后会fork出子进程父进程退出。Restarton-failure是为了在模块异常挂掉时自动拉起新进程配合quectel-CM自身的重拨机制双保险。TimeoutStartSec120是因为在弱信号环境下模块从上电到完成网络注册可能超过30秒如果这个值太短systemd会误杀启动过程。注意在嵌入式设备上如果文件系统是只读的quectel-CM写resolv.conf会失败。建议把/etc/resolv.conf做成tmpfs挂载点或者使用resolvconf工具动态管理避免只读文件系统导致的启动失败。4.3 多APN场景下的配置策略有些物联网卡会要求使用专用APN比如cmiot中国移动物联网专用APN、ctnet天翼物联等。这种情况下不要硬编码APN在启动命令里建议通过配置文件统一管理。quectel-CM支持读取环境变量和配置文件你可以用如下方式实现#!/bin/sh # /etc/init.d/quectel-cm-start.sh APN$(cat /etc/quectel-cm-apn.conf) /usr/bin/quectel-CM -s $APN -f /dev/ttyUSB2 -g /dev/cdc-wdm0 -4 同时把/etc/quectel-cm-apn.conf做成一个可修改的分区文件。这样一来运营商参数变更时远程运维只需更新这个配置文件不用重新烧系统。另外部分APN要求设置PDP类型为IPv4/IPv6或者使用特殊的鉴权方式。quectel-CM支持通过命令行指定具体可以用-4或-6选择IP协议族如果有用户名密码需求在源码里配置或者参考源码里的quectel-cm.conf模板增加User和Password字段。4.4 调试串口上的常见问题排查用EC20做项目时调试串口的波特率设置也是容易被忽略的点。有些模块出厂默认波特率是9600有些是115200如果你用115200连不上就先试9600然后再用ATIPR115200改成115200。quectel-CM通过ttyUSB2发AT指令时它会按照默认波特率打开串口如果这个默认值和模块当前波特率不匹配初始化阶段就会卡住。解决方法是先串口登录模块手动把波特率固定然后用quectel-CM自带的-b参数指定波特率不同版本参数可能不一样老版本是-b 115200新版本直接用stty设置。5. 常见问题与排查技巧实录5.1 DNS被写成114.114.114.114的问题前面已经提到过这里再单独拎出来讲一遍排查方法。当你发现系统的/etc/resolv.conf里出现了114.114.114.114但你不想用它可以分三步排查看quectel-CM的日志确认DNS address ...这行打印的是什么。如果打印的是114.114.114.114说明运营商就下发这个DNS如果日志里根本没有DNS行说明是quectel-CM编译时内置的默认DNS兜底生效了。查看你所在地区的运营商默认DNS是不是114.114.114.114最简单的办法是换一张不同运营商的SIM卡测试。电信在很多地区确实下发的就是114.114.114.114。如果确认是兜底生效修改源码里的默认DNS宏定义并重新编译或者用-p参数禁止quectel-CM修改resolv.conf然后在脚本里用自己的DNS配置覆盖。在商业项目里我最推荐的方式是不管quectel-CM怎么写resolv.conf启动脚本最后固定覆盖一次DNS。比如echo nameserver 223.5.5.5 /etc/resolv.conf echo nameserver 119.29.29.29 /etc/resolv.conf这样无论运营商下发什么DNS最终都以你的配置为准。适合对DNS有明确要求的场景比如内网域名解析。5.2 能Ping通IP但无法解析域名这个问题在4G上网场景里非常典型。现象是ping 223.5.5.5 # 通 ping www.baidu.com # 报unknown host排查思路很明确既然IP能通链路没问题问题出在DNS解析环节。常见原因有三个resolv.conf为空quectel-CM的-p参数或者systemd-resolved把配置覆盖了。DNS地址不可达运营商下发的DNS服务器在某些网络环境比如专网卡、内网卡下无法访问需要手动改成公网DNS测试。DNS权限问题系统里跑着dnsmasq但dnsmasq的监听地址配置错误。实际操作中我一般先手动指定DNS测试echo nameserver 223.5.5.5 /etc/resolv.conf nslookup www.baidu.com如果通了就是模块下发的DNS有问题按5.1的方式处理如果还通不了查一下/etc/nsswitch.conf里的hosts配置确保files dns顺序正确。5.3 启动后一直卡在waiting for networkquectel-CM日志如果停在某个阶段不动最常见的原因是模块没有注册上网络。排查步骤# 查看信号强度 ATCSQ # 查看注册状态期望返回 0,1已注册本地网 ATCREG? # 查看PS域注册状态 ATCEREG?如果CREG返回0,3或0,4说明被网络拒绝可能是SIM卡没有开通数据业务或者APN错误。CEREG返回0,2表示正在搜索网络等几秒再看。一个容易被忽略的点是天线问题。EC20模块的天线匹配非常敏感如果天线没接好或者天线阻抗不匹配信号强度会极低甚至检测不到网络。调试时用手碰一下天线接口看ATCSQ返回值是否明显变大如果变大说明天线装配有接触不良问题。5.4 自动重拨失效quectel-CM本身有断线重拨机制但实际项目里我发现它默认的链路探测频率偏低且探测手段有限。在弱网环境下可能出现“网络已经断了但quectel-CM自己还不知道”的情况。解决方法是配合一个外层看门狗脚本周期性检查网络连通性发现异常就杀掉quectel-CM重启#!/bin/sh # /usr/bin/4g-watchdog.sh while true; do if ! ping -I wwan0 -c 3 -W 5 223.5.5.5 /dev/null 21; then killall quectel-CM sleep 2 /usr/bin/quectel-CM -s cmnet -f /dev/ttyUSB2 -g /dev/cdc-wdm0 -4 fi sleep 30 done这个脚本配合systemd的Restart机制基本能保证98%以上的链路恢复成功率。需要注意的是这里的ping -c 3会持续10秒左右脚本启动时CPU占用可以忽略但别在多个网络接口同时跑的网关上用避免误判路由走向导致频繁重启4G链路。5.5 常见问题速查表现象可能原因排查手段解决方案无法打开/dev/ttyUSB2内核驱动未加载/模块未枚举dmesg检查USB枚举手动modprobe qmi_wwan等待设备节点生成初始化阶段卡死波特率不匹配/模块固件异常串口ATI验证修改波特率参数重新刷模块固件一直waiting for network天线问题/SIM卡欠费/未注册ATCSQ、ATCREG?检查天线换SIM测试能Ping通IP但域名不通DNS配置被覆盖/DNS不可达nslookup测试手动覆盖resolv.conf默认路由被抢占多网口设备ip route查看使用-n参数频繁断线重拨不恢复链路检测频率低看日志中链路状态增加外层看门狗脚本qmi_wwan驱动加载失败内核配置缺失检查.config重新编译内核启用qmi_wwanresolv.conf被systemd-resolved覆盖systemd接管DNS管理检查symlink使用-p参数用resolvectl配置5.6 一个踩过的大坑USB供电不足导致模块挂死最后分享一个我在量产调试中遇到的典型案例。现场反馈某批次设备的4G模块“用几天就掉线且掉线后无法自动恢复”。远程日志显示quectel-CM反复重拨但始终报QMI request failed。最后排查发现这批设备的USB host口供电设计只有300mAEC20在高速传输时峰值电流超过800mA电压跌落导致模块瞬间复位QMI通道随之挂掉。解决办法是把USB供电从主板5V直接经过一颗低阻抗MOS管切换确保模块供电在2A以上同时quectel-CM那边也用systemd的RestartSec10兜底。这个问题让我养成了一个习惯任何新板子拿到手第一步先测USB口在满载状态下的电压跌落别等上了产线才发现供电缺陷。6. 进阶建议把quectel-CM用得更稳关于quectel-CM和EC20的配合还有几个可以优化的方向值得多说两句。一是日志轮转和远程监控。quectel-CM默认把日志打向控制台和log文件量产设备上建议把输出重定向到syslog或者logrotate管理的日志目录避免出现日志文件撑爆Flash的问题。我一般会在启动脚本里加上./quectel-CM -s cmnet -f /dev/ttyUSB2 -g /dev/cdc-wdm0 -4 /var/log/quectel-cm.log 21 然后配置/etc/logrotate.d/quectel-cm做按天切割。二是拨号前检查SIM卡热插拔状态。工业设备经常面临“对端现场插拔SIM卡”的情况。quectel-CM对SIM卡热插拔的响应并不完美它在初始化阶段检查到SIM不存在时会直接退出。我建议在启动脚本里先执行一遍AT指令检测ATQSIMSTAT?看返回的SIM卡状态位然后再启动quectel-CM。三是区分模块固件版本。EC20的固件版本不同QMI协议行为可能有细微差异。老的EC20固件比如EC20CEFAGR06A08M1G和较新的固件在IPv6PD、双栈支持上表现不一样。如果遇到“同样的quectel-CM编译版本这个模块能拨号另一个不能”先对比两块的固件版本大概率是固件差异。四是弱网环境下的时延抖动优化。quectel-CM默认的链路保持参数偏保守如果项目对实时性要求高比如视频回传、远程控制可以调整WDS_SET_LINK_MTU和TCP握手机制。EC20在QMI模式下默认MTU通常是1500但运营商网络实际MTU往往是1428或者更小遇到Ping大包失败、HTTP请求超时类问题可以尝试手动设置MTU为1420ip link set dev wwan0 mtu 1420这个优化在移动/联通网络下效果明显电信网络一般默认1500也问题不大。最后再分享一个小技巧在编译quectel-CM时可以把版本号和使用帮助都统一改成自己公司的名称方便现场同事根据日志快速识别是否为定制版本。源码里的const char *app_ver变量改动位置在src/version.c十分简单。EC20和quectel-CM这套组合本身就是为嵌入式联网场景设计的熟练掌握启动流程和排查思路就相当于拿到了4G模块调优的钥匙。还是那句话——遇到问题先看日志日志里每一行都有意义。