# 自定义AT开发指南
***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.***
---
# 功能概述
AT命令(Attention Command)是一种用于控制调制解调器或通信模块的标准化指令集。每条命令以“AT”开头,用于通知设备即将发送命令,随后设备执行具体操作,如查询信号质量、发送短信、拨打电话或配置模块参数。设备执行命令后会返回响应,如 **OK**、**ERROR** 或状态信息,响应末尾通常带有回车换行(CR/LF)作为格式化标记。
AT命令广泛应用于GSM、3G/4G/5G模块、蓝牙和GPS设备,支持文本与数字两种响应模式,便于开发者进行设备控制、状态查询和调试。由于其简洁性、标准化和跨厂商兼容性,AT命令成为嵌入式通信和模块开发中最常用的控制接口。本文主要描述如何通过相关API实现自定义AT命令的注册与处理。
## AT命令类型
标准AT命令一般有 **四种基本操作类型:测试命令、查询命令、设置命令** 和 **执行命令**。
|
类型
|
示例
|
说明
|
| --- | --- | --- |
| **测试命令** | **AT+``=?** | 测试是否存在相应的命令,并返回有关其参数的类型、值或范围的信息 |
| **查询命令** | **AT+``?** | 查询相应命令的当前参数值 |
| **设置命令** | **AT+``=``[,``[,``[...]]]** | 设置用户可定义的参数值 |
| **执行命令** | **AT+``** | 返回特定的参数信息或执行特定的操作 |
### 测试命令
- **格式**
```bash
AT+=?
```
- **作用**
测试是否存在相应的命令,并返回有关其参数的类型、值或范围的信息。
- **示例**
```objective-c
AT+CFUN=?
+CFUN: (0,1,4)
OK
```
上述示例表示该命令支持0、1和4这三种模式。
- **特点**
- 以=?结尾;
- 查询可支持的参数范围;
- 常用于调试或开发阶段。
### 查询命令
- **格式**
```bash
AT+?
```
- **作用**
查询相应命令的当前参数值。
- **示例**
```objective-c
AT+CFUN?
+CFUN: 1
OK
```
上述示例表示查询当前的CFUN模式,当前模式设置为1。
- **特点**
- 以?结尾;
- 不修改配置;
- 查询当前状态。
### 设置命令
- **格式**
```bash
AT+=[,[,[...]]]
```
- **作用**
设置用户可定义的参数值。
- **示例**
```bash
AT+CFUN=1
```
上述示例表明设置CFUN模式为1。
- **特点**
- 带=号;
- 且包含配置参数;
- 用于修改配置。
### 执行命令
- **格式**
```bash
AT+
```
- **作用**
返回特定的参数信息或执行特定的操作。
- **示例**
```bash
AT+CIMI
```
上述示例表明执行AT+CIMI(用于查询IMSI号)。
- **特点**
不带参数;
直接执行操作。
## 添加自定义AT命令
需要使用到的接口文件:
*qos_components\system\at\qosa_at_cmd.h*
增加自定义AT命令的基本流程如下:
1. 注册自定义AT命令:
系统在开机后的初始化阶段,通过 ***qosa_at_parser_add_cust_at()*** 添加自定义AT命令。该函数可以接收一个包含多个AT命令及其处理函数的表格。
2. 实现处理函数:
在AT处理函数中, 实现AT命令的功能。
以下通过一个最简单的AT处理函数,介绍如何实现自定义的AT处理函数。 该AT命令的名称为 **AT+QEXAMPLEHELLO**, 发送 **READ命令(AT+QEXAMPLEHELLO?)** 会返回"**+QEXAMPLEHELLO: Hello World!**"。
步骤一:注册自定义AT命令。
首先在开机初始化阶段调用 ***qosa_at_parser_add_cust_at()*** 注册AT命令 **+QEXAMPLEHELLO** 以及对应的处理函数。此处AT命令的字符串请勿加上AT字符。示例代码如下:
```c
qosa_at_desc_t unir_examples_at_desc[] = {
{"+QEXAMPLEHELLO", unir_exec_example_qexamplehello_cmd, 0},
{QOSA_NULL, QOSA_NULL, 0}};
qosa_at_parser_add_cust_at((const qosa_at_desc_t *)unir_examples_at_desc, QOSA_ARRAY_SIZE(unir_examples_at_desc));
```
步骤二:实现处理函数。
AT命令的处理并非简单的字符串匹配,而是一套高度抽象的命令分发机制。AT命令解析器框架已完成从物理链路层到应用逻辑层的解耦,因此开发者只需关注 *unir_exec_example_qexamplehello_cmd()* 这一回调函数,在该函数中完成自定义AT命令的业务逻辑。示例代码如下:
```cpp
void unir_exec_example_qexamplehello_cmd(qosa_at_cmd_t *cmd)
{
char resp[128] = {0}; // Response string buffer
switch (cmd->type)
{
case QOSA_AT_CMD_READ: {
// Read command processing branch, e.g. input AT+QEXAMPLEHELLO?
qosa_snprintf(resp, sizeof(resp), "%s", "+QEXAMPLEHELLO: Hello World!");
qosa_at_resp_cmd(cmd->dev_port, QOSA_ATCI_RESULT_CODE_OK, QOSA_CMD_RC_OK, resp, 1);
}
break;
case QOSA_AT_CMD_SET: {
// Set command processing branch, e.g. input AT+QEXAMPLEHELLO="cfg",10
// Get first string parameter
test_str = (char *)qosa_at_param_string(cmd->params[0], ¶mok);
if (!paramok)
{
// Return error when parameter is invalid
qosa_at_resp_cme_error(cmd->dev_port, QOSA_ERR_AT_CME_PARAM_INVALID);
return;
}
// Construct and return set command response
qosa_snprintf(resp, sizeof(resp), "+QEXAMPLEHELLO: \"%s\"", test_str);
qosa_at_resp_cmd(cmd->dev_port, QOSA_ATCI_RESULT_CODE_OK, QOSA_CMD_RC_OK, resp, 1);
}
break;
default:
// Unsupported command type, return operation not supported error
QOSA_RETURN_CME_ERR(cmd->dev_port, QOSA_ERR_AT_CME_OPERATION_NOT_SUPPORTED);
break;
}
}
```
处理函数的参数功能说明如下:
- cmd->type:用于确定命令的类型
- cmd->params:命令的参数集
- cmd->dev_port:命令传输通道, 后续回复AT命令需要向此通道传输
**命令分发**
当一条AT命令到达处理器时,SDK首先将其解析并封装进 *qosa_at_cmd_t* 结构体中。其中cmd->type是处理流程的核心字段,它定义了当前交互的语义:
| **类型 (cmd->type)** | **对应AT指令示例** | **说明** |
| --- | --- | --- |
| *QOSA_AT_CMD_READ* | **AT+QEXAMPLEHELLO?** | **查询命令** |
| *QOSA_AT_CMD_SET* | **AT+QEXAMPLEHELLO="cfg",1** | **设置命令** |
| *QOSA_AT_CMD_TEST* | **AT+QEXAMPLEHELLO=?** | **测试命令** |
| *QOSA_AT_CMD_EXE* | **AT+QEXAMPLEHELLO** | **执行命令** |
**命令参数的解析与校验**
SDK提供专用的API来解析cmd->params[]数组中的参数,并对解析结果进行校验。这些API具备自动类型转换和合法性检查功能。
- 解析API:
字符串解析API:*qosa_at_param_string(cmd->params[index], &ok)*
整型解析API:*qosa_at_param_int(cmd->params[index], &ok)*
- 安全性校验:SDK引入了paramok机制,该变量可在解析过程中传递状态。解析API采用“逻辑短路”设计:一旦序列中某个参数解析失败,paramok立即被锁定为false状态,后续有效解析自动中止。开发者需在所有参数解析完成后,对paramok进行一次最终校验。
**响应回复机制**
发送命令执行结果时,必须关联cmd->dev_port,以确保响应能准确返回给发起请求的通道(如UART或USB)。
- 成功响应:使用 *qosa_at_resp_cmd()* 发送具体内容及OK状态。
- 错误响应:使用 *qosa_at_resp_cmd()*/*qosa_at_resp_cme_error()*/*QOSA_RETURN_CME_ERR* 返回标准错误码,便于上位机识别异常原因。
## 自定义AT API
## 头文件
*qosa_at_cmd.h*
## 函数概览
| **函数** | **描述** |
| --- | --- |
| *qosa_at_parser_add_cust_at()* | 动态添加自定义AT命令 |
| *qosa_at_resp_cmd()* | 返回结果并结束AT命令 |
| *qosa_at_resp_cmd_info_text()* | 输出文本但不结束命令 |
| *qosa_at_resp_finish()* | 结束AT命令并清理资源 |
## 函数详解
### qosa_at_parser_add_cust_at
- **功能描述**
动态添加自定义AT命令。用于应用层向系统注册自定义AT命令,用户可将命令描述符列表添加到AT解析器中,从而扩展模块的标准AT命令集。
- **函数原型**
```c
void qosa_at_parser_add_cust_at(const qosa_at_desc_t *desc, qosa_uint32_t list_len)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *desc* | 输入 | const qosa_at_desc_t * | 指向自定义AT命令描述结构体列表的指针。有关自定义AT命令描述结构体详情,详见 [*qosa_at_desc_t*](#qosaatdesc_t) |
| *list_len* | 输入 | qosa_uint32_t | 待添加的AT命令列表中的命令总数(总数需大于等于1) |
- **返回值说明**
无
```{note}
1. 该函数通常在应用初始化阶段调用。
2. 注册的命令名称不能与系统内置的标准AT命令重名。
```
### qosa_at_resp_cmd
- **功能描述**
返回结果并结束AT命令。向指定的AT通道返回命令执行的最终结果,并正式结束当前AT命令的生命周期。支持返回 **OK**、**ERROR**、**CME ERROR** 及 **CMS ERROR** 等标准响应格式。
- **函数原型**
```c
void qosa_at_resp_cmd(qosa_at_dev_type_e dev_port, qosa_atci_result_code_e resultCode, qosa_uint32_t report_code, char *rsp_buffer, qosa_uint8_t padding)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *dev_port* | 输入 | *qosa_at_dev_type_e* | AT命令的目标通道。详情请参考 [*qosa_at_dev_type_e*](#qosaatdevtypee) |
| *resultCode* | 输入 | *qosa_atci_result_code_e* | 返回结果类型(如 *QOSA_ATCI_RESULT_CODE_OK*)。详情请参考 [*qosa_atci_result_code_e*](#qosaatciresultcodee) |
| *report_code* | 输入 | qosa_uint32_t | 错误码。当结果为 **CME ERROR** 或 **CMS ERROR** 时,携带具体的错误编号。*report_code* 的取值取决于 *resultCode* 的类型。详情可参考 ***resultCode*****的使用说明** |
| *rsp_buffer* | 输入 | char * | 响应内容缓冲区。仅在结果为 **OK** 且需要返回额外数据时有效。若无需返回数据,可设置为 *QOSA_NULL* |
| *padding* | 输入 | qosa_uint8_t | 换行符(\r\n)填充模式配置,控制 *rsp_buffer* 内容前后是否自动添加换行。范围:0~4- *0*: 不添加
- *1*: 自动在 *rsp_buffer* 前后增加换行符,如果 *rsp_buffer* 原始数据前后已有换行符, 则避免重复
- *2*: 强制在 *rsp_buffe* r前后增加换行符
- *3*: 强制在 *rsp_buffer* 前增加换行符
- *4*: 强制在 *rsp_buffer* 后增加换行符
推荐使用 **1** |
***resultCode*的使用说明如下**:
- 不推荐使用 *QOSA_ATCI_RESULT_CODE_NULL*。如需返回常规错误码, 请使用 *QOSA_ATCI_RESULT_CODE_ERROR*,并将 *report_code* 设定为 *QOSA_CMD_RC_ERROR*。示例代码如下:
```c
qosa_at_resp_cmd(cmd->dev_port, QOSA_ATCI_RESULT_CODE_ERROR, QOSA_CMD_RC_ERROR, QOSA_NULL, 1)
```
- *QOSA_ATCI_RESULT_CODE_CMS_ERROR* 为短信相关的错误码, 不推荐使用。
- 当 *resultCode* 为 *QOSA_ATCI_RESULT_CODE_OK* 时, *report_cod* e应设为 *QOSA_CMD_RC_OK*。如果有字符串需要输出, *rsp_buffer* 应填入字符串地址;否则设为 *QOSA_NULL*。示例代码如下:
```c
//无字符串输出
qosa_at_resp_cmd(cmd->dev_port, QOSA_ATCI_RESULT_CODE_OK, QOSA_CMD_RC_OK, QOSA_NULL, 1);
//有字符串输出
qosa_at_resp_cmd(cmd->dev_port, QOSA_ATCI_RESULT_CODE_OK, QOSA_CMD_RC_OK, rsp_buffer, 1);
```
- 当 *resultCode* 为 *QOSA_ATCI_RESULT_CODE_CME_ERROR* 时, *report_code* 可填入 *QOSA_ERR_AT_CME_* 开头的CME相关错误码或者自定义错误码, *rsp_buffer* 需要保持为 *QOSA_NULL*。示例代码如下:
```c
qosa_at_resp_cmd(cmd->dev_port, QOSA_ATCI_RESULT_CODE_CME_ERROR, QOSA_ERR_AT_CME_OPERATION_NOT_ALLOWED, QOSA_NULL, 1);
```
- **返回值说明**
无
```{note}
1. 调用该函数后,当前AT命令处理流程即结束,通道重新进入待命状态。
2. 若仅需输出中间过程信息而不结束命令,请调用 ***qosa_at_resp_cmd_info_text()***。
```
### qosa_at_resp_cmd_info_text
- **功能描述**
输出文本但不结束命令。在AT命令执行过程中输出文本信息,仅负责向指定通道发送数据,不会改变当前的AT解析状态,也不会结束正在执行的命令。
- **函数原型**
```c
int qosa_at_resp_cmd_info_text(qosa_at_dev_type_e dev_port, const char *text, qosa_size_t length, unsigned char padding)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *dev_port* | 输入 | *qosa_at_dev_type_e* | AT命令的目标通道。详情请参考 [*qosa_at_dev_type_e*](#qosaatdevtypee) |
| *text* | 输入 | const char * | 响应内容缓冲区。不可为空 |
| *length* | 输入 | qosa_size_t | *text* 的长度。单位:字节。该长度需大于等于1 |
| *padding* | 输入 | unsigned char | 换行符(\r\n)填充模式配置,控制 *text* 内容前后是否自动添加换行。范围:0~4- *0*: 不添加
- *1*: 自动在 *text* 前后增加换行符, 如果 *text* 原始数据前后已有换行符, 则避免重复
- *2*: 强制在 *text* 前后增加换行符
- *3*: 强制在 *text* 前增加换行符
- *4*: 强制在 *text* 后增加换行符
推荐使用 **1** |
- **返回值说明**
*0*:函数执行成功
*非0*:函数执行失败
```{note}
1. 该函数常用于查询命令或需要分多行输出数据的场景。
2. 在使用 *qosa_at_resp_cmd_info_text()* 输出自定义响应内容后,必须调用 *qosa_at_resp_cmd()* 返回最终执行结果(如 **OK** 或 **ERROR**),以结束当前AT命令流程。
```
### qosa_at_resp_finish
- **功能描述**
结束AT命令并清理资源。结束当前AT命令解析流程,清除当前状态,并向AT线程发送事件以继续读取新的输入数据。
- **函数原型**
```c
int qosa_at_resp_finish(qosa_at_dev_type_e dev_port)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *dev_port* | 输入 | *qosa_at_dev_type_e* | AT命令的目标通道。详情请参考 [*qosa_at_dev_type_e*](#qosaatdevtypee) |
- **返回值说明**
*0*:函数执行成功
*非0*:函数执行失败
```{note}
该函数用于AT命令处理的收尾操作,清除当前解析状态。调用后,AT线程将继续读取新的输入数据。
```
## 结构体定义
### qosa_at_desc_t
自定义AT命令描述结构体定义如下:
```cpp
typedef struct _qosa_at_desc
{
char *name;
void (*handler)(struct _qosa_at_cmd *);
qosa_uint32_t constrains;
} qosa_at_desc_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *name* | char * | 命令名称字符串。例如 *"***+IPR***"*、*"***+QEXAMPLEHELLO***"*。注册时只填写命令体,不包含前缀AT |
| *handler* | void (*)(struct _qosa_at_cmd *) | 命令的处理回调。命令匹配成功后,AT解析器会调用此函数,并通过 [*qosa_at_cmd_t*](#qosaatcmd_t) 向回调传入通道、命令类型、参数列表等上下文信息 |
| *constrains* | qosa_uint32_t | 保留参数(暂不使用,请保持为0) |
**示例:**
```bash
qosa_at_desc_t unir_examples_at_desc[] = {
{"+qexampleedit", unir_exec_example_qexampleedit_cmd, 0},
{"+qexamplehello", unir_exec_example_qexamplehello_cmd, 0},
{"+qexampleraw", unir_exec_example_qexampleraw_cmd, 0},
{QOSA_NULL, QOSA_NULL, 0}};
```
### qosa_at_cmd_t
*qosa_at_cmd_t* 是AT命令解析上下文结构体。命令匹配成功后,AT解析器构造该结构体,并通过 *qosa_at_desc_t* 中的 *handler* 传递给命令处理函数。处理函数通过该结构体判断命令类型、读取参数,并通过响应接口输出执行结果。
AT命令解析上下文结构体定义如下:
```cpp
typedef struct _qosa_at_cmd
{
qosa_at_dev_type_e dev_port;
qosa_uint8_t param_count;
qosa_at_cmd_type_e type;
qosa_at_desc_t *desc;
qosa_bool_t resp_flag;
qosa_bool_t err_flag;
qosa_at_param_t *params[QOSA_AT_MAX_PARAM_CNT];
} qosa_at_cmd_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *dev_port* | *qosa_at_dev_type_e* | AT命令的目标通道。详情请参考 [*qosa_at_dev_type_e*](#qosaatdevtypee) |
| *param_count* | qosa_uint8_t | 当前命令解析得到的参数个数。业务处理时可结合 *params* 数组判断可访问的参数范围 |
| *type* | qosa_at_cmd_type_e | 当前AT命令的执行模式,包括设置命令、测试命令、查询命令和执行命令。*handler* 可根据该字段区分处理逻辑 |
| *desc* | qosa_at_desc_t * | 匹配到的AT命令注册描述信息,包含命令名称、处理回调和约束参数 |
| *resp_flag* | qosa_bool_t | 响应输出控制标志,用于标记当前AT命令是否为首次输出,AT框架据此处理响应前的换行格式 |
| *err_flag* | qosa_bool_t | 错误状态标志,用于记录当前AT命令执行过程中是否已经发生错误 |
| *params* | qosa_at_param_t *[QOSA_AT_MAX_PARAM_CNT] | 参数数组,保存解析后的AT参数。业务处理函数通常配合 *qosa_at_param_\** 系列接口读取和校验参数 |
## 枚举定义
### qosa_at_dev_type_e
AT命令的目标通道枚举定义如下:
```c
typedef enum
{
QOSA_DEV_NONE = -1,
QOSA_DEV_SIOLIB_UART1_PORT,
QOSA_DEV_SIOLIB_UART2_PORT,
QOSA_DEV_SIOLIB_UART3_PORT,
QOSA_DEV_SIOLIB_USB_AT_PORT,
QOSA_DEV_SIOLIB_USB_MODEM,
QOSA_DEV_SIOLIB_USB_AT2_PORT,
QOSA_DEV_SIOLIB_USB_NMEA,
QOSA_DEV_SIOLIB_DATA_MUX_0_PORT,
QOSA_DEV_SIOLIB_DATA_MUX_1_PORT,
QOSA_DEV_SIOLIB_DATA_MUX_2_PORT,
QOSA_DEV_SIOLIB_DATA_MUX_3_PORT,
QOSA_DEV_SIOLIB_DATA_MUX_4_PORT,
QOSA_DEV_VIRT_AT_PORT,
QOSA_DEV_PORT_MAX,
} qosa_at_dev_type_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_DEV_NONE* | 无效端口或未指定端口,通常作为默认值或特殊场景占位值使用 |
| *QOSA_DEV_SIOLIB_UART1_PORT* | UART1 AT通道,对应本地端口名 *uart1* |
| *QOSA_DEV_SIOLIB_UART2_PORT* | UART2 AT通道,对应本地端口名 *uart2* |
| *QOSA_DEV_SIOLIB_UART3_PORT* | UART3 AT通道,对应本地端口名 *uart3* |
| *QOSA_DEV_SIOLIB_USB_AT_PORT* | 主USB AT通道,对应本地端口名 *usbat* |
| *QOSA_DEV_SIOLIB_USB_MODEM* | USB Modem通道,对应调制解调器数据相关USB端口 |
| *QOSA_DEV_SIOLIB_USB_AT2_PORT* | 第二路USB AT通道,用于多路USB AT访问场景 |
| *QOSA_DEV_SIOLIB_USB_NMEA* | USB NMEA通道,对应本地端口名 *usbnmea* |
| *QOSA_DEV_SIOLIB_DATA_MUX_0_PORT* | CMUX逻辑通道基准值,常用于与后续CMUX端口做偏移换算 |
| *QOSA_DEV_SIOLIB_DATA_MUX_1_PORT* | 第1路CMUX AT/URC通道,对应本地端口名 *cmux1* |
| *QOSA_DEV_SIOLIB_DATA_MUX_2_PORT* | 第2路CMUX AT/URC通道,对应本地端口名 *cmux2* |
| *QOSA_DEV_SIOLIB_DATA_MUX_3_PORT* | 第3路CMUX AT/URC通道,对应本地端口名 *cmux3* |
| *QOSA_DEV_SIOLIB_DATA_MUX_4_PORT* | 第4路CMUX AT/URC通道,对应本地端口名 *cmux4* |
| *QOSA_DEV_VIRT_AT_PORT* | 虚拟AT通道,对应本地端口名 *virtat*,用于虚拟或内部转发场景 |
| *QOSA_DEV_PORT_MAX* | 枚举边界值,表示端口类型上限,不作为实际AT端口使用 |
### qosa_atci_result_code_e
返回结果类型枚举定义如下:
```c
typedef enum QOSA_ATCI_RESULT_CODE
{
QOSA_ATCI_RESULT_CODE_NULL,
QOSA_ATCI_RESULT_CODE_OK,
QOSA_ATCI_RESULT_CODE_ERROR,
QOSA_ATCI_RESULT_CODE_CME_ERROR,
QOSA_ATCI_RESULT_CODE_CMS_ERROR,
QOSA_ATCI_RESULT_CODE_MAX
} qosa_atci_result_code_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_ATCI_RESULT_CODE_NULL* | 空结果类型。一般不推荐使用,实际开发中应优先使用更明确的 **OK**、**ERROR**、**CME ERROR** 或 **CMS ERROR** |
| *QOSA_ATCI_RESULT_CODE_OK* | 命令执行成功。若同时传入 *rsp_buffer*,会先输出内容,再输出最终 **OK** |
| *QOSA_ATCI_RESULT_CODE_ERROR* | 返回标准 **ERROR** 结果,适用于通用失败场景 |
| *QOSA_ATCI_RESULT_CODE_CME_ERROR* | 返回 **+CME ERROR: ** 类型错误,适用于设备、参数、网络等ME相关错误 |
| *QOSA_ATCI_RESULT_CODE_CMS_ERROR* | 返回 **+CMS ERROR: ** 类型错误,适用于短信业务相关失败场景 |
| *QOSA_ATCI_RESULT_CODE_MAX* | 枚举边界值,用于范围控制,不作为实际返回结果使用 |
# 应用逻辑流程图
该流程在系统启动的初始化阶段执行,目的是注册自定义AT命令:当接收到该命令字符串时,系统将调用对应的处理函数。
```{figure} images/board_HEdJwxKlYhfxwRbMG0UclyCpncc.jpg
:align: center
:alt: image
```
用户通过串口发送命令(如 **AT+QEXAMPLEHELLO?**)后,AT命令解析器框架将解析该命令并触发相应的回调函数。
```{figure} images/board_C7hgw4jRfhhkbvb6Ny8cZcCtnQe.jpg
:align: center
:alt: image
```
# 示例代码
完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/system/at/at_demo.c 。