跳转至

AT 指令开发与使用指南

本文档面向 HiDiTingV100 的应用、驱动和中间件开发者,说明 AT(Attention)命令框架的工作方式、当前可用命令的源码入口,以及如何新增、编译、运行和调试自定义 AT 命令。

AT 命令将 PC 串口工具或诊断通道与设备上的功能模块连接起来。开发者可以通过它完成特性验证、产测辅助和问题定位,也可以把自己的业务能力封装为可脚本化的命令接口。

适用范围: 本文以 HiDiTingV100/3322 的 diting-community 构建目标和当前 SDK 源码为准。命令是否实际可用还受目标配置、产品形态和权限控制影响。


AT 模块背景知识

AT 命令是什么

AT 命令是一种基于文本的串口控制协议。主机向设备发送以 AT+(或兼容的 AT^)开头、以 CRLF 结尾的命令;设备解析命令、调用对应业务回调,并返回信息行及最终结果码 OKERROR

AT 框架提供通用的通道管理、命令解析、参数校验、命令分发和响应输出。业务模块只需提供命令表和回调函数,无需重复实现串口收发和协议解析。

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 框架,最终由命令表中的回调函数处理。

AT 启动与命令处理流程

关键入口如下:

  1. /src/application/3322/3322_app_standard/service_init.c 调用 at_adapter_init()
  2. /src/middleware/chips/3322/at_adapter/at_adapter.c 注册基础 API、通道写函数和各模块命令表。
  3. at_channel_rx_callback() 将 UART 输入交给 uapi_at_channel_data_recv()
  4. at_parse.c 识别命令格式与参数,at_process.c 调用 at_cmd_entry_t 中对应的回调。
  5. 回调使用 uapi_at_report()uapi_at_print() 输出业务信息;框架依据返回值追加 OKERROR

命令类型与语法

类型 格式 用途
执行命令 AT+<CMD> 执行无参数操作。
设置命令 AT+<CMD>=<para>[,<para>...] 传入参数并执行设置或动作。
查询命令 AT+<CMD>? 查询当前状态或已保存值。
测试命令 AT+<CMD>=? 查询设置命令支持的参数范围。
扩展查询 AT+<CMD>?=<para> 仅在启用 CONFIG_AT_SUPPORT_QUERY 时可用。

输入命令不区分大小写,但新增命令名称必须使用大写字母和数字;命令以 \r\n 结束。参数使用逗号分隔,字符串参数中的逗号需要按模块协议处理。

响应约定

AT+DEMOVALUE=42
+DEMOVALUE: 42
OK

AT+DEMOVALUE=101
ERROR
  • 信息行以 + 开头,建议使用与命令同名的前缀。
  • OKERROR 由框架依据回调返回的 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,否则命令不会被完整识别。
  • 烧录与当前构建目标匹配的固件;具有权限限制的命令需满足产测/白名单条件。

SecureCRT 的 CR+LF 设置示例

最小验证

AT+HELP

该命令会输出当前已注册命令的名称;它是确认“固件已启动、串口链路正常、命令表已注册”的首选方法。

AT+RST

该命令重启设备,仅用于受控测试场景。

说明: 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                    # 示例组件配置

核心代码走读

  1. service_init() 调用 at_adapter_init(),初始化 UART、基础 API 和输出通道。
  2. at_adapter_init() 按产品配置调用各模块的命令注册函数;自定义示例在这里注册 DEMOINFODEMOVALUE
  3. at_channel_rx_callback() 将串口输入交给 uapi_at_channel_data_recv()
  4. 框架由 at_parse.c 识别命令类型和参数,再由 at_process.c 调用 at_cmd_entry_t 中的回调。
  5. 回调返回 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=? 查询参数范围。

新增 AT 命令开发流程

涉及接口

接口 功能说明
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 已增加以下接入点:

  1. native_samples/CMakeLists.txtCONFIG_ENABLE_AT_COMMAND_SAMPLE 控制地加入示例组件。
  2. /src/build/config/target_config/3322/config.pyditing-community 增加该宏与 at_command_sample 组件。
  3. 示例 CMake 通过 AT_DITING_EXAMPLE_CUSTOM_AT 发布编译宏。
  4. /src/middleware/chips/3322/at_adapter/at_adapter.c 在启动时调用 at_diting_custom_at_command_register()

新增正式业务命令时,请使用独立组件名和独立配置宏;不要直接复用本示例的宏和命令名。

详细编码步骤

定义命令协议

先确定命令名称、命令类型、参数和返回格式。名称必须在最终固件中唯一,且仅含大写字母和数字。例如:

AT+MYFEATURE=<mode>,<timeout>
+MYFEATURE: <result>
OK | ERROR

名称重复会导致启用命令表校验时注册失败。对于会改变网络、安全或持久化数据的操作,必须设计权限与二次确认机制。

定义参数结构体和语法表

设置命令的参数由 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 关联命令名称、参数语法和执行/设置/查询/测试回调。只有设置命令需要非空 syntaxstruct_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 与目标:

fbb build --sdk-dir $env:FBB_SDK_DIR pack_diting_community

构建完成后,使用一站式 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_SAMPLEat_command_sample 的配对关系;关闭该宏时,示例代码和命令不会进入固件。

运行步骤

  1. 使用 AT 串口连接设备,配置为 115200、8N1,回车发送 CR+LF
  2. 输入 AT+HELP,确认输出中包含 DEMOINFODEMOVALUE
  3. 依次输入以下命令:

    AT+DEMOINFO
    AT+DEMOVALUE=?
    AT+DEMOVALUE=42
    AT+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>=? 确认范围;检查 syntaxlastoffset 和属性。
设置命令无法解析 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 确认注册状态,再逐步验证测试、设置和查询命令。不要在业务回调中直接阻塞很长时间;耗时操作应设计为异步命令。

相关资料