展讯SPRD AT指令这块资料圈里流传的大多是零散截图或者某一平台的定制版文档真正能跨平台通用的、讲清楚为什么的资料其实很少。这篇把我这些年在不同展讯方案上实际验证过的命令和排障经验整理出来覆盖基础查询、私有扩展、脚本解析和实战坑点给后面接手展讯平台的工程师省点时间。1. 展讯平台的AT指令生态标准命令、私有命令和版本坑1.1 两条主线3GPP标准命令与展讯私有扩展展讯SPRD现在并入紫光展锐平台的AT指令体系本质上由两部分组成一部分是3GPP TS 27.007和V.25ter定义的通用命令比如ATCSQ信号强度、ATCREG网络注册、ATCPINSIM卡状态另一部分是展讯自己定义的私有扩展命令比如ATNVRAMNV存储读写、ATSPFMFM相关、ATEFUN工厂模式。这两部分的可靠程度和文档完整度差距非常大——标准命令几乎每个平台都一致但私有扩展命令在不同芯片平台、不同软件版本上经常改名或者改变参数含义。我自己的体会是标准命令是保底口粮私有扩展命令才是展讯平台真正值钱、也最需要小心的地方。原因在于展讯给功能机、智能机、IoT模组提供的是整体交钥匙方案很多工厂测试、产线校准、运营商定制功能都要靠私有AT通道完成所以这些命令数量巨大而且很多时候是方案商根据客户需求现加的。这意味着你拿到的文档只代表该版本固件支持的命令换一个项目、换一版固件命令集就可能变。建议拿到新平台的第一件事不是翻命令而是先跑一遍ATCLAC列出所有支持的命令把当前固件的真实命令集拉出来再去跟手头的文档比对差异。这一步能省掉后面大量的为什么文档和实际对不上的困惑。1.2 指令入口不只有UARTUSB、蓝牙和AT通道的区别展讯平台的AT指令入口远比很多人以为的要复杂。最常见的是UART串口这也是绝大多数开发板、模组的默认调试通道。但展讯的智能手机方案比如UMS系列和部分4G模组AT指令还可以通过USB虚拟串口、蓝牙SPP甚至通过内部共享内存接口来访问。重点在于这些不同入口不等价。以USB为例展讯平台在正常开机后一般会枚举出多个端口其中可能有/dev/ttyUSB0、/dev/ttyUSB1甚至更多分别对应不同的业务通道比如AT命令口、日志口、诊断口。如果脚本连错了口发送AT不会有任何回复非常耽误排查。此外展讯还有一个特殊的下载模式Download Mode在这个模式下USB枚举出的设备是下载口通常用FDL工具和烧录工具通信不能用来发AT指令。很多新人会把下载模式下的端口当成AT口结果怎么发都没反应。实操时的判断方法很简单正常开机后先用工具串口助手或者ls /dev观察所有枚举出的端口然后逐个发AT\r\n只有能返回OK的那个才是AT指令口。不要靠文档猜因为不同项目的USB配置可能完全不同。1.3 网上文档为什么经常对不上平台代号、软件版本与文档版本展讯平台的代号很杂老一点的SC65312G功能机、SC9820/SC9832低端智能机、再到后来的UMS9117/UMS9230等。不同平台之间的AT指令集差异比同平台不同版本固件的差异还要大。尤其是一些偏底层的私有命令比如NV读写命令ATNVRAM不同平台的NV项编号完全不同你在SC6531上验证过的ATNVRAMxxx参数拿到UMS系列上可能直接报ERROR。还有一个很隐蔽的问题展讯文档版本落后于固件版本。产线和新项目拿到的一般是预发布固件里面可能已经加了新命令但对外文档还是旧版反过来也一样文档里写了某条命令新固件因为安全策略或功能调整把它删了文档却还没更新。所以文档只能当参考最终解释权在当前固件实际行为上。我的做法是每接手一个新项目先固化一套基线验证命令集大概20条左右覆盖模块信息、SIM卡状态、网络注册、信号、电话本、短信、数据拨号全部跑一遍并记录返回结果作为后续所有工作的对照基准。2. 基础查询命令组拿到模组或板子之后必跑的检查清单2.1 最小验证集AT、ATE0、ATCGMI/ATCGMM/ATCGMR不管是用展讯模组还是整机板子上电后第一件事永远是发AT确认通信链路通不通。链路通了之后紧接着建议做两件事发ATE0关闭命令回显然后依次查询厂家、型号、版本信息。AT通信握手正常返回OK。ATE0关闭回显。这个操作很重要否则脚本解析时会把输入的ATCGMI和返回的\r\nATCGMI\r\n...混在一起增加解析难度。ATCGMI厂商信息展讯平台通常返回UNISOC或Spreadtrum老版本返回Spreadtrum。ATCGMM具体型号通常是模组型号或者芯片方案代号。ATCGMR软件版本号这个字段在后续固件问题排查里非常关键报bug给原厂或者方案商时第一件事就是提供ATCGMR的返回内容。查询版本还有一个容易被忽略的点直接发ATCGMR可能只返回主版本号有些展讯平台需要发ATCGMR?才能列出完整的版本信息包括编译时间、GIT提交号等。包含编译时间这个信息在对比新旧固件时特别有用排查为什么固件升级了但问题还在时可以靠它确认固件是否真的刷进去了。2.2 SIM卡、信号与网络状态检查基础查询里SIM卡和网络相关的命令是使用频次最高的我列一组实际跑过的组合命令用途典型返回ATCPIN?查询SIM卡状态CPIN: READY表示已识别ATICCID读取SIM卡ICCID非标准命令展讯支持ICCID: 8986001xxx...ATCIMI读取IMSICIMI: 46000...ATCSQ信号强度CSQ: 18,0第一项越大越好ATCREG?网络注册状态CREG: 0,1第二项为1表示已注册ATCOPS?当前运营商COPS: 0,0,CHINA MOBILE,7需要说明的是ATICCID不是3GPP标准命令但展讯平台基本都支持很方便用来做整机测试时确认SIM卡是否插好、有没有读卡异常。ATCSQ返回的第二个参数是误码率一般恒为0第一个参数才是信号强度范围0-31。实测中功能机平台通常在10-20之间属于正常弱信号地区20以上算良好低于10基本处于弱覆盖区域。ATCREG?的第二位参数是重点0表示未注册、1表示已注册到本地网络、5表示已注册但处于漫游状态。排障时如果发现一直返回0说明天线、SIM卡或者网络参数比如频段配置有问题而不是AT指令本身的问题。2.3 用ATCLAC摸清当前固件的命令边界ATCLAC是我每到一个新平台必跑的第一条私有扩展命令它也出现在标准V.25ter中。它会列出当前固件支持的全部命令名输出格式一般是CLAC: ATCGMI,ATCGMM,...。因为展讯平台的私有命令太多文档又不一定跟得上这条命令就是固件自身最权威的命令清单。实际使用中有三个经验输出可能很长串口工具要设置足够大的接收缓冲区否则容易丢数据。建议用支持日志保存的工具直接把返回内容存成文件。ATCLAC列出的只是命令名不是参数说明。所以它帮你确定了固件支持哪些命令但不能告诉你每条命令的具体参数格式。私有命令的参数还得靠文档、原厂FAE或者反推测试。个别展讯固件的ATCLAC可能不列私有扩展命令只列标准命令这时可以尝试ATCLAC?。如果都不行说明固件关闭了这个接口只能靠文档和抓modem日志来补全了。3. 展讯扩展命令里真正有价值的配置功能3.1 ATSP家族厂商信息与工厂自检展讯的私有命令里ATSP开头是一个庞大的命令族不同命令用ATSP...的完整命令名区分类似ATSPFM、ATSPCAM这种命名方式而不是统一加参数区分。这里说几个我在项目里真正用过的以及它们的位置ATSP?部分平台支持返回软件版本、硬件版本、芯片版本等综合信息。不同于ATCGMR它更偏向硬件和方案层信息。音频测试类命令不同项目名称不同常见的是ATSPAUDIO、ATSPSETVOICE用于设置音频通路、音量、回音消除参数常用于音频产线测试。工厂自检类命令一些定制方案会有ATSPLCD屏检测、ATSPTP触摸检测、ATSPCAM摄像头检测这类一次性自检命令产线通过它们快速判断硬件是否正常。这里的核心建议是不要试图背下所有ATSP*命令因为不同方案差异太大了。正确做法是先在ATCLAC返回结果里搜索ATSP开头的命令再结合你手头项目的产线测试规范去理解。这类命令的参数格式没有统一规律有些用十六进制传参数有些直接传ASCII务必以实测为准。3.2 ATEFUN、ATCFUN、ATNVRAM功能模式与NV存储展讯平台的ATCFUN和标准平台类似用来设置功能模式ATCFUN0进入飞行模式ATCFUN1恢复全功能。但展讯还有一个比较特殊的ATEFUN它和CFUN不是一回事——EFUN通常用于工厂模式切换在某种情况下会关闭RIL智能机平台上或关闭协议栈的部分功能导致电话短信不可用但AT指令本身还能回。这类命令在量产测试中用来隔离其他业务、保证测试环境纯净但普通调试时候千万别乱开。ATNVRAM是展讯平台一个非常底层、也非常危险的命令用于读写NVNon-Volatile非易失性存储项。NV项保存了RF校准参数、IMEI、MAC地址、运营商配置等信息。展讯平台的G2D2G和智能机方案上NV项编号是完全不同的体系同一个编号在不同平台可能代表完全不同的参数。针对ATNVRAM我的经验是千万别靠猜。写NV项之前必须确认你查到的NV编号确实来自当前平台文档最好先在另一台设备上备份所有NV值。写完后不要立刻断电或者重启等几秒钟再操作。NV写入实际是有中间过程的有些项写完后需要soft resetATCFUN0再ATCFUN1才能生效直接断电可能只写了一半。如果是为了改IMEIATNVRAM并不是唯一途径ATEGMR如果固件支持才是相对标准的命令而且改IMEI本身需要确认每个国家地区的法规合规性别在生产环境里乱测。3.3 音频、FM收音机与双卡相关的私有命令展讯在功能机时代深度做音频和FM方案所以相关命令特别多。音频层面ATCLVL是标准命令设置通话音量但展讯平台音频通路切换回音消除、麦克风增益等往往靠ATSPSETVOICE这类私有命令。如果做音频产测或者整机测试拿到设备的音频校准规范是最快的路径命令细节以规范为准不要自己造参数。FM收音机方面展讯平台老方案有ATSPFM相关命令用于开关FM、调频、搜台等。实测中FM命令的返回比较慢搜台操作可能需要好几秒调试脚本时不要把AT超时时间设得太短。双卡双待是展讯方案的一大特色。智能机平台一般不用AT命令管理双卡走RIL内部接口但功能机或IoT方案上你可能需要用ATCSIM通用SIM访问或者平台私有命令切换SIM卡槽、读取副卡状态。据我见过的情况双卡相关私有命令在展讯各平台之间也不统一而且和Modem配置双卡单待还是双卡双待强相关。如果是做整机或者模组方案建议先确认当前固件的SIM卡方案再去看对应的私有命令不然很容易出现主卡一切正常、副卡命令全部报错的情况。3.4 数据业务和TCP/IP协议栈从NETOPEN到CIP系列展讯平台在数据业务上的AT命令体系比较有特色。老一些的2G/3G模组方案里常见的是ATNETOPEN打开TCP/IP协议栈然后用ATCIPOPEN、ATCIPSEND、ATCIPCLOSE这组命令做TCP/UDP连接和数据收发新一些的4G智能机方案则基本不走AT数据通道而是用NDIS/RNDIS/ECM这种虚拟网卡方式拨号AT指令只负责查询状态。如果做IoT数据传输项目我建议先确认模组是AT指令直接承载TCP/IP还是AT虚拟网卡拨号模式。这两种模式的调试方法完全不同直接AT承载TCP/IP的模式需要重点测协议栈稳定性比如长时间ATCIPSEND大数据包传输是否丢数据、TCP重连逻辑是否正常。虚拟网卡模式AT指令只用来做拨号和状态查询类似ATCGACT1激活PDP实际的TCP/IP业务跑在操作系统协议栈里。这种情况下AT层的稳定性重点在拨号、断线重拨、APN配置业务层问题反而要从系统网络侧排查。实测中还遇到过一个坑展讯部分平台对ATCGDCONT设置APN/PDP上下文的参数有严格的字符集限制APN内容不能带大写字母和特殊符号否则会返回ERROR或者设置无效。排查数据业务不通时如果ATCGACT1一直失败先检查APN字符串是否跟运营商开通资料完全一致再检查大小写。4. 命令格式、回复解析和URC处理脚本能写稳的关键4.1 AT指令语法细节与缓冲区限制AT指令从语法上分几种无参数命令如AT、带参数命令如ATCPIN1234、查询命令如ATCPIN?、测试命令如ATCPIN?。这个分类在基础文档里都有但展讯平台实际处理时有几个细节值得注意命令行结尾是回\rCR而不是\n换行大多数串口工具会自动处理但写脚本时如果发的是\n展讯Modem可能不认。命令行的最大长度因固件而异一般不超过128字节或者256字节。长参数比如写长短信、设置长APN时要特别小心超过缓冲区长度会直接ERROR。展讯平台对命令输入大小写不敏感atcsq和ATCSQ一样但返回的中间信息如CSQ: 18,0通常是固定格式解析时按实际返回处理。我见过不少脚本问题都出在串口工具显示正常但脚本解析失败上。原因往往是脚本把\n或\r\n当成命令结束符发送而协议栈只认\r结尾。正确做法是命令行统一用\r\n结尾虽然展讯对多余的LF通常不报错但统一格式能避免特殊固件下的意外行为。4.2 三类回复OK/ERROR、CME ERROR和URC展讯平台对AT指令的回复可以分成三类第一类是简单结果码OK表示成功ERROR表示通用失败。这类最简单但信息量少出错时很难直接定位原因。第二类是带错误码的返回格式为CME ERROR: err或者CMS ERROR: err。要看到这类详细错误码通常需要先发ATCMEE2开启详细错误信息。展讯平台对ATCMEE2的支持比较稳定建议脚本初始化序列里固定加上。常见错误码比如CME ERROR: 13SIM卡故障、CME ERROR: 10SIM未插入等排障效率比只看到ERROR高很多。第三类是主动上报的URCUnsolicited Result Code它不需要你发命令就会自动过来比如CIEV: 5,1信号强度变化、CREG: 1网络注册状态变化、CMTI: SM,1新短信到达、RING来电等。URC是脚本里最容易被忽略的干扰源——你发一条ATCSQ回复还没到突然先来了一条CIEV的URC解析程序如果没有处理URC的逻辑就会把数据对错位。我的建议是任何解析引擎都要先按是否包含CME ERROR、是否包含已知URC前缀做一次分流再进入正常回复解析流程。不要假设发了命令之后收到的所有内容都只属于这条命令。4.3 从查询到解析的完整脚本逻辑示例下面是一段简单但可用的Python串口AT交互逻辑重点不是代码本身多复杂而是处理顺序能覆盖上面提到的三种回复类型import serial import time ser serial.Serial(/dev/ttyUSB0, 115200, timeout3) def send_at(cmd, wait_ms500): ser.reset_input_buffer() ser.write((cmd \r\n).encode()) time.sleep(wait_ms / 1000.0) return ser.read_all().decode(errorsignore) # 初始化 send_at(ATE0) send_at(ATCMEE2) # 查询信号强度并处理可能混入的URC resp send_at(ATCSQ) for line in resp.splitlines(): if line.startswith(CSQ:): csq line.split(:)[1].strip().split(,)[0] print(CSQ , csq) elif line.startswith(CME ERROR) or line ERROR: print(命令返回错误, line) else: # 到达这里的可能是URC或命令回显记录即可 print(其他内容, line)这段代码里用了reset_input_buffer()清空输入缓冲避免上一次命令的残留数据干扰这是一个实操中很有用的细节。timeout3也很关键展讯平台某些命令比如网络注册查询在弱信号下响应可能很慢超时设短了会把正常命令误判为失败。实际项目中我会建议把每条命令的超时做成可配置参数和命令本身绑定普通查询500ms-1s网络操作和搜网、FM搜台这类操作给3-5s。5. 实战踩坑记录展讯平台AT调试里最难发现的问题5.1 改波特率导致的永久失联展讯平台多数支持ATIPR动态修改UART波特率。听起来很方便但这个命令非常容易坑人。我之前在调试一块展讯4G模组时想从115200改成460800提速发了ATIPR460800返回OK后串口助手还没来得及切换波特率驱动就把波特率改了结果就是两边速率不一致终端上再也看不到任何回复只能断电重启。正确流程是先把后面要用的大批量操作的波特率策略定好在整机初始化配置阶段一次性设置并且设置完要立即在同一个环节把串口工具或脚本的波特率同步切换掉。如果只是临时调试大数据量日志建议不要改波特率而是用其他方式比如抓USB日志或者文件日志来规避。另外展讯平台改波特率后是否自动保存到NV不同固件行为也不一样有的重启后会恢复默认值有的会一直保持。千万不要在产线流程里依赖改完波特率就永久生效这个假设。5.2 NVRAM写入后立刻重启配置丢失前面提到ATNVRAM写入后不能立刻断电重启这里展开说一下原因和现象。我在一次产线调试中遇到一个间歇性bug写入RF校准参数后接着执行自动重启重启后参数时有时无。后来抓Modem日志发现NV写入实际是先写缓存再落盘重启指令如果在落盘动作完成前触发缓存数据会丢失。规避方法很简单ATNVRAM写入后先发一条ATCFUN4如果支持或者延时2-3秒确认没有异常再触发重启。也可以用上一章节提到的方式通过查询命令把刚写入的NV项读回来确认一遍读回来一致再继续下一步。这条写后必读、确认再重启的经验在整个展讯平台的NV和校准参数调试里几乎是通用法则。5.3 URC上报时机与命令时序冲突展讯Modem的URC上报没有严格的和命令回复强制隔离。最典型的场景是做自动化测试时脚本发ATD10086;拨号结果在等待拨号结果的过程中突然收到一条CIEV: 3,0的URC当前通话状态变化如果脚本这时还在等待完整的OK或CME ERROR就容易超时误判。处理思路不是去禁用URC很多URC关不掉而是把超时时间放宽并在解析逻辑中单独处理URC。如果自动化测试对时序非常敏感可以考虑在测试前通过ATCSVM?语音邮箱、ATCLIP?来电显示这类命令将非必要通知关掉但这只对部分URC有效。最重要的一点是不要在每次命令发送前直接sleep固定时间然后读串口而是应该读串口直到等到目标响应或超时。5.4 选错AT通道连上了却收不到任何回复我在文章开头提过展讯设备可能同时存在多个串口。这里再说一个更隐蔽的变体有些展讯智能机方案的AT命令口和AGPS数据口复用同一个USB端口需要特定的打开方式比如先发一个特殊转义序列才能进入AT模式。我遇到过一次设备枚举出一个ttyUSB2打开后能正常收到日志但发AT指令完全没有响应后来看了方案商文档才知道这个口当前是日志模式需要通过特定指令切换。这种情况靠ATCLAC是测不出来的只能靠查方案文档或者找原厂FAE确认。给一个新项目的排查建议上电开机后把枚举出的每个口都试一遍把哪个口对应AT记录下来不要想当然认为ttyUSB0就一定是AT口。6. 可复用的AT排障链路从异常日志倒推根因6.1 按顺序排查不要跳步展讯平台AT层出问题绝大多数根因是以下五类之一而且排查顺序特别重要跳步容易浪费时间通信链路问题串口接线、波特率、通道选择。先用最基础的AT握手确认链路链路不通什么都别谈。固件状态问题设备是否处于飞行模式、是否注册网络、SIM卡是否识别。按ATCPIN?、ATCFUN?、ATCREG?的顺序依次检查。参数配置问题APN、频段、运营商配置。这类问题在数据业务和网络注册异常时优先排查。业务逻辑问题电话、短信、数据连接时序。这类问题需要结合日志分析不是单纯AT交互能解决的。硬件/RF问题天线、射频校准、SIM卡接触。当ATCSQ持续为99无法读取信号或ATCPIN?一直NO SIM时优先怀疑硬件。这套顺序听起来像废话但实际项目里我见过太多人一上来就怀疑固件版本刷了好几个版本才发现是串口波特率设错了。建议把上面五个层次做成一个检查表每次排障都按表格走一遍避免被直觉带偏。6.2 把AT日志固化成标准检查单我个人习惯是每次项目进入系统联调前先固化一份AT标准检查单包含以下内容软件版本信息ATCGMR、ATCGMMSIM卡状态和ICCID网络注册状态和当前运营商信号强度关键业务路径拨号、短信收发、数据拨号各来一轮异常场景的AT日志保存比如断网重连、SIM卡热插拔这样做的好处是当现场报设备无法联网这类模糊问题时我可以直接让现场按检查单跑一遍把结果发回来。比起远程反复指导、让对方到处试这种方法几乎能手到病除。而且这些检查记录长期积累下来还能作为固件版本升级后的回归基线判断新固件到底有没有引入兼容性问题。另外建议在日志保存上统一格式每行带上时间戳命令前加--回复前加--。这个习惯能让你在翻日志时一眼看出命令时序和URC插入点排障效率会提升很多。简单地说不要只在出问题时才开始记录AT日志把它变成日常调试的标准动作。