AT 指令开发与使用指南
本文档面向 HiDiTingV100 的应用、驱动和中间件开发者,说明 AT(Attention)命令框架的工作方式、当前可用命令的源码入口,以及如何新增、编译、运行和调试自定义 AT 命令。
AT 命令将 PC 串口工具或诊断通道与设备上的功能模块连接起来。开发者可以通过它完成特性验证、产测辅助和问题定位,也可以把自己的业务能力封装为可脚本化的命令接口。
适用范围: 本文以 HiDiTingV100/3322 的
diting-community构建目标和当前 SDK 源码为准。命令是否实际可用还受目标配置、产品形态和权限控制影响。
AT 模块背景知识
AT 命令是什么
AT 命令是一种基于文本的串口控制协议。主机向设备发送以 AT+(或兼容的 AT^)开头、以 CRLF 结尾的命令;设备解析命令、调用对应业务回调,并返回信息行及最终结果码 OK 或 ERROR。
AT 框架提供通用的通道管理、命令解析、参数校验、命令分发和响应输出。业务模块只需提供命令表和回调函数,无需重复实现串口收发和协议解析。
模块职责
| 层级 | 主要职责 | 核心代码 |
|---|---|---|
| 产品适配层 | 初始化 UART、注册基础运行时能力和通道输出函数。 | /src/middleware/chips/3322/at_adapter/at_adapter.c |
| 通道层 | 接收输入、缓存命令并投递至 AT 消息队列。 | /src/middleware/utils/at/at/src/at_channel.c |
| 解析与执行层 | 识别前缀、命令名和类型,校验参数并调用命令表回调。 | /src/middleware/utils/at/at/src/at_parse.c、/src/middleware/utils/at/at/src/at_process.c |
| 命令表层 | 管理各模块注册的 at_cmd_entry_t 命令表。 |
/src/middleware/utils/at/at/src/at_cmd.c |
| 业务层 | 实现蓝牙、媒体、GNSS、CAT1、外设示例等具体能力。 | AT 命令清单 |
启动与注册流程
service_init() 在系统服务初始化阶段调用 at_adapter_init()。适配器先建立 UART 通道和 AT 基础 API,再按编译宏注册基础命令、协议栈命令、业务模块命令及示例命令。UART 收到数据后进入 AT 框架,最终由命令表中的回调函数处理。
关键入口如下:
- /src/application/3322/3322_app_standard/service_init.c 调用
at_adapter_init()。 - /src/middleware/chips/3322/at_adapter/at_adapter.c 注册基础 API、通道写函数和各模块命令表。
at_channel_rx_callback()将 UART 输入交给uapi_at_channel_data_recv()。at_parse.c识别命令格式与参数,at_process.c调用at_cmd_entry_t中对应的回调。- 回调使用
uapi_at_report()或uapi_at_print()输出业务信息;框架依据返回值追加OK或ERROR。
命令类型与语法
| 类型 | 格式 | 用途 |
|---|---|---|
| 执行命令 | AT+<CMD> |
执行无参数操作。 |
| 设置命令 | AT+<CMD>=<para>[,<para>...] |
传入参数并执行设置或动作。 |
| 查询命令 | AT+<CMD>? |
查询当前状态或已保存值。 |
| 测试命令 | AT+<CMD>=? |
查询设置命令支持的参数范围。 |
| 扩展查询 | AT+<CMD>?=<para> |
仅在启用 CONFIG_AT_SUPPORT_QUERY 时可用。 |
输入命令不区分大小写,但新增命令名称必须使用大写字母和数字;命令以 \r\n 结束。参数使用逗号分隔,字符串参数中的逗号需要按模块协议处理。
响应约定
- 信息行以
+开头,建议使用与命令同名的前缀。 OK与ERROR由框架依据回调返回的at_ret_t统一输出。- 异步操作使用
uapi_at_send_async_result()在业务完成时返回最终结果;主动上报使用 URC 接口。
API 接口列表
本文档涉及的 AT 框架接口如下。AT 产品适配接口尚未生成独立 API 页面,链接到对应头文件;其余接口可直达 API 参考锚点。
| 接口函数 | 说明 |
|---|---|
| uapi_at_base_api_register | 注册消息队列、内存、调度等 AT 框架基础能力。 |
| uapi_at_channel_write_register | 注册指定 AT 通道的输出函数。 |
| uapi_at_channel_data_recv | 将 UART/诊断输入交给 AT 框架处理。 |
| uapi_at_cmd_table_register | 注册 at_cmd_entry_t 命令表。 |
| uapi_at_report | 向当前命令通道输出固定响应信息。 |
| uapi_at_print | 向当前命令通道格式化输出信息。 |
| uapi_at_send_async_result | 为异步阻塞式命令返回最终执行结果。 |
| uapi_at_urc_to_channel | 向指定通道发送 URC 主动上报。 |
完整 API 列表
更多 AT 接口、前置条件和 Kconfig 配置请参考:AT API 参考。
快速跑通 AT Demo
准备工作
- 使用设备 AT 串口。默认配置为 115200 bit/s、8 数据位、1 停止位、无校验。
- 串口工具的回车键必须发送
CR+LF,否则命令不会被完整识别。 - 烧录与当前构建目标匹配的固件;具有权限限制的命令需满足产测/白名单条件。

最小验证
该命令会输出当前已注册命令的名称;它是确认“固件已启动、串口链路正常、命令表已注册”的首选方法。
该命令重启设备,仅用于受控测试场景。
说明:
AT+HELP展示的是当前固件实际注册的集合;它会随编译宏和产品配置变化,是命令可用性的最终运行时依据。
当前 AT 命令清单
完整命令索引、功能说明和源码入口请见 AT命令清单.md。清单按模块分组,表格只保留三列:AT 命令、功能说明、代码路径链接。
命令是否纳入最终固件由 /src/middleware/chips/3322/at_adapter/at_adapter.c 中的注册逻辑决定。对于 AT+MEDIA=<subcmd>、AT+OHOS=<subcmd> 等命令族,具体子命令由同一处理模块进一步解析;对外使用时请同时查看清单中的子命令说明和源码实现。
文件结构与代码走读
文件结构
src/middleware/utils/at/at/
├── include/at_product.h # 产品适配接口、通道与基础 API
└── src/
├── at_channel.c # 串口/诊断通道接收与缓存
├── at_parse.c # 命令格式和参数解析
├── at_process.c # 参数校验、回调调度和结果输出
├── at_cmd.c # 已注册命令表管理
└── at_report.c # 信息行和结果输出
src/middleware/chips/3322/at_adapter/
└── at_adapter.c # UART、基础命令和模块命令启动注册
samples/native_samples/at_command/
├── at_custom_command_demo.c # 自定义命令回调和注册
├── at_custom_command_demo.h # 参数语法和 at_cmd_entry_t 命令表
└── CMakeLists.txt # 示例组件配置
核心代码走读
service_init()调用at_adapter_init(),初始化 UART、基础 API 和输出通道。at_adapter_init()按产品配置调用各模块的命令注册函数;自定义示例在这里注册DEMOINFO与DEMOVALUE。at_channel_rx_callback()将串口输入交给uapi_at_channel_data_recv()。- 框架由
at_parse.c识别命令类型和参数,再由at_process.c调用at_cmd_entry_t中的回调。 - 回调返回
AT_RET_OK时框架输出OK;其他返回值输出ERROR。
完整启动流程和架构图见AT 模块背景知识。
基于 AT Demo 扩展自己的 AT 命令
仓库已提供 AT 自定义命令 Demo,源码位于 samples/native_samples/at_command/。本节结合该真实工程说明两个不依赖硬件的命令:
| 命令 | 功能 |
|---|---|
AT+DEMOINFO |
输出示例说明。 |
AT+DEMOVALUE=<0-100> |
保存一个示例整数。 |
AT+DEMOVALUE? |
查询当前示例整数。 |
AT+DEMOVALUE=? |
查询参数范围。 |
涉及接口
| 接口 | 功能说明 |
|---|---|
| uapi_at_cmd_table_register | 将命令表注册到 AT 框架。 |
| uapi_at_report | 输出固定字符串到当前命令通道。 |
| uapi_at_print | 格式化输出业务信息。 |
| uapi_at_send_async_result | 异步命令结束时返回结果。 |
| uapi_at_cmd_abort_register | 为可中断异步命令注册取消回调。 |
| uapi_at_urc_to_channel | 向指定通道发送 URC 主动上报。 |
后 3 个接口需要相应 Kconfig 特性开启;本示例只使用前三个同步接口。
准备工作与关键配置
示例代码位于:
samples/native_samples/at_command/
├── at_custom_command_demo.c # 回调、注册函数和状态
├── at_custom_command_demo.h # 参数语法与命令表
├── CMakeLists.txt # 组件配置、公共宏
└── README.md # 命令速览
为使示例进入当前产品镜像,SDK 已增加以下接入点:
native_samples/CMakeLists.txt受CONFIG_ENABLE_AT_COMMAND_SAMPLE控制地加入示例组件。- /src/build/config/target_config/3322/config.py 为
diting-community增加该宏与at_command_sample组件。 - 示例 CMake 通过
AT_DITING_EXAMPLE_CUSTOM_AT发布编译宏。 - /src/middleware/chips/3322/at_adapter/at_adapter.c 在启动时调用
at_diting_custom_at_command_register()。
新增正式业务命令时,请使用独立组件名和独立配置宏;不要直接复用本示例的宏和命令名。
详细编码步骤
定义命令协议
先确定命令名称、命令类型、参数和返回格式。名称必须在最终固件中唯一,且仅含大写字母和数字。例如:
名称重复会导致启用命令表校验时注册失败。对于会改变网络、安全或持久化数据的操作,必须设计权限与二次确认机制。
定义参数结构体和语法表
设置命令的参数由 at_para_parse_syntax_t 描述。框架根据参数类型、范围、可选属性和结构体偏移完成校验与赋值。
typedef struct {
uint32_t para_map;
int32_t value;
} at_custom_value_args_t;
static const at_para_parse_syntax_t g_at_custom_value_syntax[] = {
{
.type = AT_SYNTAX_TYPE_INT,
.last = true,
.attribute = AT_SYNTAX_ATTR_AT_MIN_VALUE | AT_SYNTAX_ATTR_AT_MAX_VALUE,
.entry.int_range.min_val = 0,
.entry.int_range.max_val = 100,
.offset = offsetof(at_custom_value_args_t, value),
},
};
实现回调函数
回调返回 AT_RET_OK 时框架输出 OK;返回其他值时输出 ERROR。参数已经经过语法表校验,但回调仍应检查指针及业务条件。
static at_ret_t at_custom_demo_value_set(const at_custom_value_args_t *args)
{
if (args == NULL) {
return AT_RET_CMD_PARA_ERROR;
}
g_demo_value = args->value;
uapi_at_print("+DEMOVALUE: %d\r\n", g_demo_value);
return AT_RET_OK;
}
定义命令表
at_cmd_entry_t 关联命令名称、参数语法和执行/设置/查询/测试回调。只有设置命令需要非空 syntax;struct_max_size 必须不小于所有设置参数结构体的最大值。
{
.name = "DEMOVALUE",
.cmd_id = 0x22F1,
.attribute = AT_FLAG_NONE,
.syntax = g_at_custom_value_syntax,
.cmd = NULL,
.set = at_custom_demo_value_set,
.read = at_custom_demo_value_read,
.test = at_custom_demo_value_test,
},
注册命令表
在组件初始化函数中调用注册 API,并确保该函数由产品 AT 适配器在启动期调用。
void at_diting_custom_at_command_register(void)
{
(void)uapi_at_cmd_table_register(g_at_custom_command_table,
AT_CUSTOM_COMMAND_TABLE_SIZE, AT_CUSTOM_COMMAND_MAX_PARAM_SIZE);
}
上述代码来自 /samples/native_samples/at_command/at_custom_command_demo.c 和 /samples/native_samples/at_command/at_custom_command_demo.h。复制 Demo 开发自定义组件时,应同步修改组件名、配置宏、命令 ID 和注册函数,避免与现有命令冲突。
编译
说明: 本文示例命令以一站式 CLI 为主。实际开发可从以下三种环境中选择,推荐使用一站式 CLI。
| 开发环境 | 适用场景 | 使用指南 |
|---|---|---|
| 一站式 CLI(推荐) | 快速完成目标选择、构建、烧录和串口监视 | 一站式 CLI 开发环境使用指南 |
| HiSpark Studio for VS Code | 图形化编辑、编译、烧录和调试 | HiSpark Studio for VS Code 开发环境使用指南 |
| WSL 与 Docker | 在 Windows 上使用一致的 Linux 容器构建环境 | WSL 与 Docker 环境使用指南 |
按照一站式 CLI 开发环境使用指南完成 fbb setup 后,在工程目录中执行:
# 指向当前 SDK 的 src 目录;路径请按本机实际位置修改。
$env:FBB_SDK_DIR = "<SDK根目录>\src"
# 首次设置构建目标,目标会保存到工程目录下的 .fbb-target。
fbb set-target pack_diting_community
# 编译已设置的目标。
fbb build
也可以不保存默认目标,直接指定 SDK 与目标:
构建完成后,使用一站式 CLI 烧写完整固件并打开 UART2 日志串口;将 COM3 替换为实际端口:
fbb flash -f "$env:FBB_SDK_DIR\output\3322\fwpkg\diting-community.fwpkg" --chip 3322 -d --timeout 180
fbb monitor --port COM3 --baud 750000
不要再在 src 目录直接执行 python build.py。
如需仅在自定义目标启用示例,请保留 CONFIG_ENABLE_AT_COMMAND_SAMPLE 与 at_command_sample 的配对关系;关闭该宏时,示例代码和命令不会进入固件。
运行步骤
- 使用 AT 串口连接设备,配置为 115200、8N1,回车发送
CR+LF。 - 输入
AT+HELP,确认输出中包含DEMOINFO和DEMOVALUE。 -
依次输入以下命令:
预期结果
AT+DEMOINFO
+DEMOINFO: custom-at-ready
OK
AT+DEMOVALUE=?
+DEMOVALUE: (0-100)
OK
AT+DEMOVALUE=42
+DEMOVALUE: 42
OK
AT+DEMOVALUE?
+DEMOVALUE: 42
OK
当输入 AT+DEMOVALUE=101 时,参数范围校验失败,预期返回 ERROR。
注意事项
- 格式化、复位、权限切换、产测、射频和调试类命令可能影响设备安全、数据完整性或网络行为。商用版本应通过编译宏、命令属性和产品权限进行收敛。
- 新增命令必须同步更新 AT命令清单.md,提供功能说明和代码路径链接。
- 命令名、命令 ID、参数格式和响应前缀应保持向后兼容;如需变更,新增版本化命令,不要静默改变既有语义。
- 合入前至少验证成功路径、参数边界、重复命令、串口断连和权限受限路径。
常见编译错误
| 现象 | 优先检查项 | 处理方法 |
|---|---|---|
AT+HELP 中没有新命令 |
组件是否进入构建、注册函数是否被调用、命令表是否注册成功。 | 检查配置宏、CMake 组件、at_adapter.c 注册点及注册 API 返回值。 |
返回 ERROR 且没有业务日志 |
命令名称、命令类型、参数数目、参数范围。 | 使用 AT+<CMD>=? 确认范围;检查 syntax 的 last、offset 和属性。 |
| 设置命令无法解析 | struct_max_size、参数结构体和语法表不匹配。 |
传入所有设置参数结构体中的最大 sizeof,并使用 offsetof。 |
| 只有回显,没有响应 | 串口行结束符不正确或接收通道错误。 | 设置串口工具回车为 CR+LF,确认 AT UART 与日志 UART 的连接。 |
AT+HELP 有命令但调用失败 |
命令属于受权限或特性宏约束的模块。 | 检查产品配置、DUT 权限和模块初始化前置条件。 |
| 异步命令一直 BUSY | 异步结果或取消路径未结束当前命令。 | 调用 uapi_at_send_async_result();为可取消场景注册 abort 回调。 |
| URC 未输出 | 未开启通知特性,或当前异步命令阻塞 URC。 | 启用 CONFIG_AT_SUPPORT_NOTIFY_REPORT,检查 AT_FLAG_NOT_BLOCK_URC 使用场景。 |
调试时优先使用 AT+HELP 确认注册状态,再逐步验证测试、设置和查询命令。不要在业务回调中直接阻塞很长时间;耗时操作应设计为异步命令。