深度解析 3GPP TS 27.007:4 AT command syntax (AT命令语法)

本文技术原理深度参考了3GPP TS 27.007 V19.4.0 (2025-09) Release 19 规范中,关于“4 AT command syntax”的核心章节,旨在为读者深入拆解AT命令的底层文法结构。掌握本章,如同掌握一门语言的语法,是编写可靠、健壮的蜂窝通信应用代码的基石。

写在前面:小李的“编程第一课”

在对整个TS 27.007规范有了宏观的认识后,物联网工程师小李坐在了他的开发工作台前。面前是“天眼”追踪器的原型板,5G模组的串口TX/RX指示灯正在安静地闪烁,仿佛在等待着第一条指令的到来。

小李的目标很明确:他需要编写一个驱动程序,让主控MCU能够稳定地向模组发送命令,并准确地解析返回的信息。这就像学习一门外语,在开口说出复杂的句子之前,必须先彻底搞懂这门语言的语法规则:什么是主谓宾,什么是疑问句,什么是感叹句。

AT命令,这门连接应用与通信世界的“语言”,其语法规则就全部定义在规范的第四章——“AT command syntax”之中。这一章是理论通往实践的第一座桥梁。小李深吸一口气,他知道,这一章的每一个细节,都将直接影响他代码的健壮性和可维护性。让我们跟随小李,一起进入AT命令的语法世界,学习如何精确地“遣词造句”。


1. 通用原则与安全警示 (4.0 General)

在深入具体语法之前,规范首先提出了一些通用性的指导原则,其中蕴含着重要的编程思想。

1.1 向前兼容:永恒的设计哲学

TE software implementors must take into account that future versions of this specification may include additional parameters beyond what is expected in any (final or intermediate) response to an AT set command, read command or test command, and beyond what is expected in any unsolicited result code. Implementations must therefore analyse all parameters provided from the TA and discard (ignore) any parameters received following the parameters expected by the TE software.

这段话堪称AT命令驱动开发的“黄金法则”。它强调了向前兼容性。3GPP规范在不断演进,新版本的规范可能会在现有命令的响应中增加新的参数。

小李的思考与实践:

他立刻意识到了一个潜在的陷阱。假设他现在开发的模组固件遵循R19规范,AT+FOO?命令返回两个参数:+FOO: <p1>,<p2>。如果他的代码写死了只解析这两个参数,那么当未来“天眼”项目升级到一款遵循R20规范的模组,而R20规范将响应扩展为+FOO: <p1>,<p2>,<p3>时,他那段僵化的解析代码很可能会出错甚至崩溃。

正确的做法是:“按需索取,忽略其他”。小李在他的解析函数设计中立刻加上了备注:

  • 解析响应时, 只读取我当前版本关心的前N个参数。

  • 对于后续可能出现的、不认识的额外参数, 程序应当能够优雅地忽略它们,而不是抛出错误。

这个原则保证了他的驱动程序具有更好的鲁棒性和生命周期,不会因为模组固件的微小升级而需要重写。

1.2 安全红线:明文传输的警示

Certain AT commands transfer information in the clear that can be regarded as sensitive with regards to security or privacy. Care must be exercised in AT commands that:

  • transfer passwords (e.g. +CLCK, +CPWD or +CPBS);
  • transfer identities (e.g. IMSI) or details of a call (e.g. +COLP);
  • reveal the IMEI (e.g. +CGSN);

规范在这里敲响了安全的警钟。AT命令本质上是明文传输的。如果TE和TA之间的物理链路(如UART)被恶意监听,那么所有敏感信息都可能被窃取。

小李的场景与对策:

“天眼”追踪器可能会被部署在复杂的环境中,如果有人物理接触到设备并接入了MCU与模组之间的调试串口,他就可以轻易地:

  • 通过AT+CIMI窃取SIM卡的IMSI。

  • 通过AT+CPIN尝试破解PIN码。

  • 通过AT+CGSN获取设备的IMEI。

这些信息一旦泄露,可能导致SIM卡被复制、设备被非法追踪等严重后果。因此,小李在产品设计规范中郑重地写下:

  1. 物理安全是第一道防线:最终产品的外壳必须坚固,内部PCB上的调试串口(UART)在量产版本中必须被禁用或移除。

  2. 访问控制:任何能够接触到AT命令接口的系统(如远程调试后台),都必须有严格的权限控制。

这一节的提醒让小李明白,AT命令虽然方便,但其安全性高度依赖于物理环境的隔离。


2. 命令的结构:如何对模组“说话” (4.1 Command line)

现在,进入核心语法部分。规范通过一张图清晰地展示了命令行(Command Line)的结构。

See figure 2 for general structure of a command line. Standardized basic commands are found only in ITU-T Recommendation V.250. The commands in this specification use syntax rules of extended commands.

小李仔细研究了规范中的“Figure 2: Basic structure of a command line”,并结合自己的理解,将一条复杂的AT命令AT+CMD1=12;+CMD2?彻底解剖。

2.2.1 基本命令 vs. 扩展命令

  • 基本命令 (Basic commands): 没有+号开头,通常只有一个字母。例如D (Dial), H (Hangup), A (Answer)。这些都是从V.250继承来的元老级命令。

  • 扩展命令 (Extended commands):+号开头,后跟一串字母。例如+CSQ, +CREG, +CGDCONT。这是3GPP规范的主体,用于实现蜂窝网络特有的复杂功能。

2.2.2 命令的四种形态

这是本章的精髓,它定义了TE与TA交互的四种基本模式:测试、读取、设置和执行。

1. 测试命令 (Test Command =?)

Every extended command has a test command (trailing =?) to test the existence of the command and to give information about the type of its subparameters.

用途: 询问模组“对于…这个功能,你支持哪些选项?”

格式: AT+<CMD>=?

小李的实践: 他想知道他的5G模组支持哪些UE使用场景设置。

  • 他发送: AT+CEUS=?

  • 模组返回: +CEUS: (0,1),然后是OK

  • 解读: 这告诉小李,+CEUS这条命令的参数只支持0(voice centric)和1(data centric)这两个值。这对于编写具有良好兼容性的代码至关重要,他可以在程序中检查模组的能力,而不是硬编码一个特定的值。

2. 读取命令 (Read Command ?)

Parameter type commands also have a read command (trailing ?) to check the current values of subparameters.

用途: 询问模组“对于…这个功能,你现在的状态是什么?”

格式: AT+<CMD>?

小李的实践: 他想知道当前模组的信号质量。

  • 他发送: AT+CSQ?

  • 模组返回: +CSQ: 25,99,然后是OK

  • 解读: 模组告诉他,当前的信号强度rssi是25(对应-63dBm,信号很好),误码率ber是99(不适用)。

3. 设置命令 (Set Command =)

(Implicitly defined as a command with parameters)

用途: 命令模组“把…功能的状态设置为…”

格式: AT+<CMD>=<value1>,<value2>,...

小李的实践: 为了省电,他希望在不需要网络时,将模组的射频功能关闭(即进入最小功能模式)。

  • 他发送: AT+CFUN=0

  • 模组返回: OK

  • 解读: 模组成功执行了指令,关闭了射频电路。

4. 执行命令 (Execution Command)

Action type commands do not store the values of any of their possible subparameters, and therefore do not have a read command.

用途: 命令模组“执行…这个动作!”

格式: AT+<CMD> (通常没有参数)

小李的实践: 在进行了一系列电话本操作后,他想获取SIM卡中存储的所有电话号码。

  • 他发送: AT+CPBR=1,100 (这是一个带参数的执行命令,意为读取1到100号位置的电话本)

  • 模组返回: 一系列+CPBR: ...的信息,最后是OK

通过这“四式”,小李掌握了向模组提问、查询、下令和执行动作的全套方法。


3. 模组的回应:如何理解TA的“反馈” (4.2 Information responses and result codes)

学会了如何“说”,还要学会如何“听”。4.2节详细描述了模组(TA)是如何回应TE的命令的。

The TA response for the example command line of figure 2 could be as shown in figure 3. Here, verbose response format is enabled with command V1.

小李研究了“Figure 3: Response to a command line”,对响应的结构有了清晰的认识。一个完整的响应通常由两部分组成:

3.3.1 信息响应 (Information Response)

这是响应的主体内容,包含了TE请求的数据。

  • 格式: 通常以+<CMD>: 开头。

  • 示例:AT+CSQ?的响应是+CSQ: 25,99

  • 特殊情况: 对于测试命令=?,响应会列出支持的范围或列表。例如,对AT+CMD2=?的响应可能是+CMD2: (0-3),(0,1),(0-12,15),("GSM","IRA"),用括号清晰地表示了每个参数的有效取值范围。

3.3.2 最终结果码 (Final Result Code)

这是响应的结束标志,告知TE命令的最终执行结果。

If verbose responses are enabled with command V1 and all commands in a command line has been performed successfully, result code OK is sent from the TA to the TE. … If verbose responses are enabled with command V1 and subparameter values of a command are not accepted by the TA … result code ERROR is sent to the TE.

  • OK: 命令成功执行。

  • ERROR: 命令执行失败。

  • +CME ERROR: <err>: 当通过AT+CMEE开启扩展错误报告时,会返回更详细的错误码或错误信息,这对于调试至关重要。

小李的编程笔记:

他的驱动程序主循环逻辑变得清晰起来:

  1. 发送一条AT命令。

  2. 进入接收状态,开始逐行读取串口数据。

  3. 循环接收,直到读到OKERROR(或+CME ERROR)为止。

  4. 在这期间接收到的所有其他行,都作为信息响应进行解析。

  5. 设置一个超时定时器,如果在规定时间内没有收到最终结果码,就判定为通信超时。

3.3.3 中间结果码与主动上报码

So called intermediate result codes inform about progress of TA operation (e.g. connection establishment CONNECT), and so called unsolicited result codes indicate occurrence of an event not directly associated with issuance of a command from TE (e.g. ring indication RING).

  • 中间结果码 (Intermediate result codes): 在一个耗时较长的命令执行过程中,模组可能会返回一些中间状态。最经典的例子就是CONNECT。当TE发送ATD*99***1#后,模组在最终建立数据链路前,会先返回CONNECT,告知TE“数据通道即将打开,请准备切换到数据模式”。

  • 主动上报码 (Unsolicited Result Codes, URCs): 这是模组主动推送给TE的信息,与TE当前发送的命令无关。

    • 小李的场景: 他的“天眼”追踪器正在静默待机。突然,网络侧发起了一次网络更新,导致模组的网络注册状态从“已注册”变为“正在搜索”。此时,即便MCU没有发送任何命令,模组也会主动发送一行+CREG: 2到串口。

    • 编程启示: 小李的MCU串口接收程序必须是事件驱动的。它不能只在发送命令后才去监听串口,而是要时刻准备接收可能随时到来的URC,并进行相应的处理。这是保证设备状态实时性的关键。


4. 底层配置:用V.250命令微调“对话”方式 (4.3 ITU-T Recommendation V.250)

规范的4.3节和与之关联的Table 1,列出了一系列继承自V.250的底层控制命令。这些命令不控制蜂窝网络功能,而是控制TE与TA之间“对话”本身的属性。

Table 1 summarizes ITU-T Recommendation V.250 commands relating to command line and response formatting, and TA-TE interface operation.

小李重新绘制了这张表格,并对其中最常用的命令做了标记。

Table 1: V.250 commands relating to TE-TA interface

| Command | Clause | Impl. | Used in the present document |

| :--- | :--- |:---|:---|

| S3=[<value>] | 6.2.1 | mand. | command line termination character (mandatory default setting IRA 13) |

| S4=[<value>] | 6.2.2 | mand. | response formatting character (recommended default IRA 10) |

| S5=[<value>] | 6.2.3 | mand. | command line editing character (recommended default IRA 8) |

| E[<value>] | 6.2.4 | mand. | command echo (recommended default 1 i.e. TA echoes commands back) |

| Q[<value>] | 6.2.5 | mand. | result code suppression (recommended default 0 i.e. TA transmits result codes) |

| V[<value>] | 6.2.6 | mand. | TA response format (recommended default 1 i.e. verbose format) |

| … | … |…|…|

小李的调试日记:

  • 问题: “为什么我通过串口助手每打一个字,都会显示两个字?”

  • 分析: 这是因为串口助手本身会回显你输入的字符,同时模组也开启了命令回显(Echo)功能。

  • 解决: 发送ATE0命令,关闭模组的回显功能。E1是开启回显。

  • 问题: “模组只返回一个数字04,而不是OKERROR,为什么?”

  • 分析: 这是因为模组当前处于数字响应格式。

  • 解决: 发送ATV1命令,将响应格式切换为详细的文本模式(Verbose)。V0则是切换回数字模式。

这些底层命令就像是调试工具箱,帮助小李将模组的交互行为调整到最适合他开发和调试的状态。


总结

第四章“AT command syntax”的学习,让小李从一个AT命令的“门外汉”变成了能够准确理解其“文法”的“入门者”。他不仅学会了如何构建一条结构正确的AT命令,还深刻理解了四种基本命令形态(测试、读取、设置、执行)的用途,并掌握了解析模组返回信息的正确方法。

更重要的是,他建立了几个关键的软件设计思想:

  • 向前兼容:解析代码要留有余地,优雅地处理未知的多余参数。

  • 事件驱动:串口接收程序必须能随时处理模组主动上报的URC,以保证状态的实时同步。

  • 安全意识:AT命令接口的物理安全至关重要,量产产品必须做好防护。

装备了这些“语法知识”后,小李已经迫不及待地要开始学习具体的“词汇”了。他的“天眼”项目,离第一次成功连接到5G网络,又近了一大步。


FAQ:快速问答

Q1:AT+CMD?AT+CMD=? 到底有什么区别,我总是记混?

A1:这是初学者最常见的问题。可以这样记:

  • ? (问号):像是在问“What is it now?”(现在是什么?)。它用来读取参数的当前值。例如 AT+CSQ? “现在的信号质量是多少?”

  • =? (等于问号):像是在问“What can it be?”(它能是什么?)。它用来测试参数支持的取值范围选项列表。例如 AT+COPS=? “你可以连接哪些运营商?”

Q2:什么是URC (Unsolicited Result Code),为什么它对物联网应用很重要?

A2:URC是模组在没有收到TE命令的情况下,主动上报的信息。例如,网络断开、有短信进来、信号强度发生剧变等。对于需要实时感知状态变化的物联网应用,URC至关重要。如果只靠TE轮询查询,会消耗大量电力且有延迟。通过处理URC,设备可以在事件发生时被“唤醒”并立即做出反应,实现真正的低功耗和事件驱动。

Q3:我看到有的AT命令如ATD没有+号,有的如+CSQ+号,这是为什么?

A3:没有+号的命令通常是“基本命令”,它们继承自非常古老的ITU-T V.250标准,历史悠久。而带有+号的命令是“扩展命令”,是3GPP为了支持蜂窝网络特有的功能(如网络注册、QoS、短信等)而新增的。在现代蜂窝模组开发中,我们打交道的绝大部分都是扩展命令。

Q4:AT命令的响应中,OKERROR+CME ERROR 有什么区别?

A4:它们都是最终结果码,表示命令执行结束。

  • OK: 命令成功。

  • ERROR: 命令失败,但原因未知或很通用(如语法错误)。

  • +CME ERROR: <err>: 命令失败,并提供了详细的错误原因。<err>可以是一个数字码或一段描述文本。要启用+CME ERROR,你需要先发送AT+CMEE=1(数字错误码)或AT+CMEE=2(文本错误码)。在开发调试阶段,强烈建议开启+CMEE

Q5:我可以一次发送多条AT命令吗?

A5:可以。现代模组普遍支持用分号(;)作为分隔符,将多条命令写在同一行一次性发送。例如,AT+CFUN=0;+CFUN=1 可以用来快速重启模组的射频。但请注意,模组会按顺序执行。如果其中一条命令出错,后续的命令可能不会被执行。同时,一行命令的总长度也有限制,通常为几百个字节。