杰理 SDK 文档中心
首页
首页
  • SDK 概述与入门

    • SDK 总览
    • 支持芯片与蓝牙认证
    • 工程结构导航
  • 开发环境与构建

    • 环境搭建与工具链安装
    • 编译指南与工程选择
    • 烧录与生产工具
  • BLE 透传/数传应用

    • 透传应用框架与处理模块
    • 透传与数传示例
    • 多连接与自定义服务示例
    • FindMy 与查找网络示例
  • HID 人机交互应用

    • 键盘与按键设备示例
    • 鼠标设备示例
    • 遥控器示例
    • HID 蓝牙应用模块
  • 公共 BSP 模块

    • 按键、编码器与红外输入
    • 传感器驱动
    • LED 与显示控制
    • 串口与 USB 通信
    • 存储、参数与时钟
    • 电源与温度管理
    • 消息、内存与系统配置
    • OTA 升级框架
  • 蓝牙协议栈与库

    • BLE 控制器与协议栈适配
    • 经典蓝牙 BR/EDR 支持
    • 第三方蓝牙协议
    • 设备管理框架
    • DUT 测试与射频认证
  • 构建系统与开发工具

    • Makefile 构建系统
    • 固件后处理与配置工具
    • 辅助脚本与库合并
  • 文档与硬件资料

    • AT 命令参考
    • 硬件参考资料
    • SDK 文档与在线资源

AT 命令参考

本文档是 AW33N BLE SDK 中 AT 命令体系(at_char_com 示例应用)的完整参考,涵盖命令解析框架、命令分类、参数格式、响应协议、底层通道与扩展方式。

Purpose and Scope

本页面向需要基于 AT 命令调试、测试或二次开发 AW33N BLE 产品的开发者,完整说明:

  • AT 命令的框架设计:命令头(AT+ / AT>)、操作符(= 设置、? 查询)、参数解析与响应(OK / ERR)协议;
  • 命令字符串表与字符串 ID 枚举的映射关系;
  • 全部内置命令的分类说明(系统查询、广播、扫描连接、传输、电源管理);
  • 核心数据结构(at_param_t、str_info_t、target_uuid_info_t)与解析缓冲区的内存布局;
  • 与 UART 通道、BLE 服务端/客户端之间的数据流;
  • 配置项、错误码、边界情况与扩展新命令的方法。

本页不包含:BLE 广播参数细节、GATT Profile 具体实现、UART 驱动寄存器级配置——这些属于 ble_at_char 与 at_char_uart 相关主题,建议参见同目录下源码。本页聚焦命令层(at_char_cmds.*)与命令触发入口(app_at_char_com.c、ble_at_char_client.c)。

概述

at_char_com 是 SDK 中一个"AT 命令透传"参考应用:设备通过 UART 接收符合 AT 语法的人机指令,解析后驱动 BLE 协议栈完成广播、扫描、连接、数据传输、OTA 升级、开关机等操作,并将结果以文本形式返回。它同时承担两类角色:

  • 从机(Server):广播自身、接受主机连接;
  • 主机(Client):主动扫描并连接外设,读写对端 GATT 特征。

AT 指令通道在所有 BLE 连接通道中拥有独立的通道号,代码注释明确划分了通道资源:

0-7:主机通道(主动连出通道);8:从机通道;9:AT 指令通道

(来源:at_char_cmds.c)

命令层与通道层解耦:at_char_cmds.c 只负责"字符串 → 命令 ID → 处理函数"的解析分发,实际行为通过 at_cmd_send()、at_send_rx_cid_data() 等接口下发到 BLE 栈或 UART,因此同样的命令框架可复用于不同的底层传输。

架构

flowchart TD
    subgraph sg_Input["输入层"]
        UART["at_char_uart.c<br/>UART 接收/发送"]
        BLE_C["ble_at_char_client.c<br/>BLE 客户端回调"]
    end

    subgraph sg_Cmd["命令层 (at_char_cmds.c)"]
        PARSE["parse_buffer[256]<br/>输入缓冲 + 参数解析"]
        TABLE["at_cmd_str_table<br/>命令字符串表"]
        DISPATCH["命令分发<br/>STR_ID → handler"]
        RESP["响应生成<br/>OK / ERR / 数据上报"]
    end

    subgraph sg_Action["动作层"]
        ADV["广播控制<br/>ADV / ADVPARAM / ADVDATA"]
        SCANCONN["扫描连接<br/>SCAN / CONN / DISC / OTA"]
        SYS["系统管理<br/>GVER / NAME / BAUD / POWEROFF"]
    end

    subgraph sg_Out["输出层"]
        BLE_S["ble_at_char_server.c<br/>BLE 服务端特征"]
        UART_OUT["UART TX"]
    end

    UART -->|"AT 字符串"| PARSE
    BLE_C -->|"事件上报"| RESP
    PARSE -->|"逐段匹配"| TABLE
    TABLE --> DISPATCH
    DISPATCH --> ADV
    DISPATCH --> SCANCONN
    DISPATCH --> SYS
    ADV --> BLE_S
    SCANCONN --> BLE_S
    SYS --> RESP
    RESP --> UART_OUT
    RESP --> BLE_S

各层职责

  • 输入层:UART 中断/轮询将字符写入解析缓冲区;BLE 客户端在扫描到设备、连接状态变化时调用 at_cmd_send() 或 at_send_connected() / at_send_disconnect() 将事件文本注入 AT 输出流(例如 ble_at_char_client.c 中扫描结果经 at_cmd_send() 上报)。
  • 命令层:先匹配命令头(AT+ / AT>),再按分隔符切分命令名与参数,用 at_cmd_str_table 把字符串映射为 STR_ID_* 枚举,最后调用对应处理分支。
  • 动作层:每个命令 ID 对应一段处理逻辑,直接调用 BLE 协议栈 API 或系统电源管理 API。
  • 输出层:所有响应统一以 \r\n 结尾;既可通过 UART TX 输出,也可封装后写入 BLE 从机特征,实现"远端设备经 BLE 链路收发 AT 指令"。

命令协议格式

命令层定义了两类命令头与一组特殊字符,作为解析的分隔依据:

static const char at_head_at_cmd[]     = "AT+";
static const char at_head_at_chl[]     = "AT>";
static const char at_str_enter[]       = "\r\n";
static const char at_str_ok[]          = "OK";
static const char at_str_err[]         = "ERR";

static const char specialchar[]        = {'+', '>', '=', '?', '\r', ','};

(来源:at_char_cmds.c)

协议约定:

  • AT+<CMD>[=<参数1>,<参数2>...]:标准命令头,命令名与参数以 = 分隔,参数之间以 , 分隔;
  • AT><CMD>:AT 指令通道专用头(与 AT+ 走同一解析流程,但用于区分来源通道语义);
  • ? 作为查询操作符,对应 AT_CMD_OPT_GET;
  • 无 ? 的赋值形式对应 AT_CMD_OPT_SET;
  • 每条命令以 \r\n 结束;执行结果以 OK / ERR 响应,错误时携带 err_id。

命令分类与详解

命令字符串表把命令名映射到 STR_ID_* 枚举,枚举在 at_char_cmds.h 中按功能分区编号:

enum {
    STR_ID_NULL = 0,
    STR_ID_HEAD_AT_CMD,
    STR_ID_HEAD_AT_CHL,

    STR_ID_OK = 0x10,
    STR_ID_ERROR,

    STR_ID_GVER = 0x20,
    STR_ID_GCFGVER,
    STR_ID_NAME,
    STR_ID_LBDADDR,
    STR_ID_BAUD,

    STR_ID_ADV,
    STR_ID_ADVPARAM,
    STR_ID_ADVDATA,
    STR_ID_SRDATA,
    STR_ID_CONNPARAM,

    STR_ID_SCAN,
    STR_ID_TARGETUUID,
    STR_ID_CONN,
    STR_ID_DISC,
    STR_ID_OTA,
    STR_ID_CONN_CANNEL,
    STR_ID_POWER_OFF,
    STR_ID_LOW_POWER,
};

(来源:at_char_cmds.h)

命令字符串表通过宏 INPUT_STR_INFO 批量注册(str_len 用 sizeof(string)-1 自动计算,避免手工数长度):

#define INPUT_STR_INFO(id,string)  {.str_id = id, .str = string, .str_len = sizeof(string)-1,}

static const str_info_t at_cmd_str_table[] = {
    INPUT_STR_INFO(STR_ID_GVER, at_str_gver),
    INPUT_STR_INFO(STR_ID_GCFGVER, at_str_gcfgver),
    INPUT_STR_INFO(STR_ID_NAME, at_str_name),
    INPUT_STR_INFO(STR_ID_LBDADDR, at_str_lbdaddr),
    INPUT_STR_INFO(STR_ID_BAUD, at_str_baud),

    INPUT_STR_INFO(STR_ID_ADV, at_str_adv),
    INPUT_STR_INFO(STR_ID_ADVPARAM, at_str_advparam),
    INPUT_STR_INFO(STR_ID_ADVDATA, at_str_advdata),
    INPUT_STR_INFO(STR_ID_SRDATA, at_str_srdata),
    INPUT_STR_INFO(STR_ID_CONNPARAM, at_str_connparam),

    INPUT_STR_INFO(STR_ID_SCAN, at_str_scan),
    INPUT_STR_INFO(STR_ID_TARGETUUID, at_str_targetuuid),
    INPUT_STR_INFO(STR_ID_CONN, at_str_conn),
    INPUT_STR_INFO(STR_ID_DISC, at_str_disc),
    INPUT_STR_INFO(STR_ID_OTA, at_str_ota),
    INPUT_STR_INFO(STR_ID_CONN_CANNEL, at_str_conn_cannel),
    INPUT_STR_INFO(STR_ID_POWER_OFF, at_str_power_off),
    INPUT_STR_INFO(STR_ID_LOWPOWER, at_str_lowpower),
};

(来源:at_char_cmds.c)

命令总览表

命令功能分组说明
AT+GVER系统查询查询固件版本(G_VERSION)
AT+GCFGVER系统查询查询配置版本(CONFIG_VERSION)
AT+NAME系统查询/设置查询或设置设备名
AT+LBDADDR系统查询查询本地蓝牙地址
AT+BAUD系统设置查询或修改 AT UART 波特率(默认 TCFG_AT_UART_BAUDRATE)
AT+ADV广播控制启动/停止广播
AT+ADVPARAM广播控制设置广播参数(间隔等,默认 ADV_INTERVAL_DEFAULT = 2048)
AT+ADVDATA广播控制设置广播数据
AT+SRDATA广播控制设置扫描响应数据
AT+CONNPARAM连接控制设置连接参数
AT+SCAN扫描连接启动/停止扫描;扫描结果经 at_cmd_send() 上报
AT+TARGETUUID扫描连接设置目标服务/特征 UUID(target_uuid_info_t)
AT+CONN扫描连接发起连接
AT+DISC扫描连接断开连接
AT+OTA升级触发 OTA 升级流程
AT+CONN_CANNEL连接控制取消连接(拼写保留源码原样)
AT+POWEROFF电源管理关机
AT+LOWPOWER电源管理低功耗模式开关(at_set_low_power_mode)

操作类型(OPT)

解析器用操作类型区分"查询"与"设置":

enum {
    AT_CMD_OPT_NULL = 0,
    AT_CMD_OPT_SET, //设置
    AT_CMD_OPT_GET, //查询
};

(来源:at_char_cmds.h)

核心解析流程

sequenceDiagram
    participant U as UART / BLE 输入
    participant P as 解析器 (parse_buffer)
    participant T as at_cmd_str_table
    participant H as 命令处理分支
    participant R as 响应输出 (at_cmd_send)

    U->>P: "AT+ADV=1\r\n"
    P->>P: 匹配命令头 "AT+" (STR_ID_HEAD_AT_CMD)
    P->>T: 按 specialchar 切分, 匹配 "ADV"
    T-->>P: STR_ID_ADV
    P->>H: 参数 "1" → AT_CMD_OPT_SET, 执行广播开
    H->>R: 成功 → "OK\r\n" / 失败 → "ERR,err_id\r\n"
    R-->>U: 文本响应

解析器先做头部匹配(AT+ / AT>),再做命令名匹配,最后按 , 切分参数链表。每个参数是一个 at_param_t 节点,next_offset 指向下一参数在 parse_buffer 中的偏移,形成单向链表:

typedef struct {
    volatile uint8_t len;//长度不包含结束符
    uint8_t next_offset;
    uint8_t data[0];     //带结束符0
} at_param_t;

(来源:at_char_cmds.h)

宏 AT_PARAM_NEXT_P(a) 用于遍历参数链表:

#define AT_PARAM_NEXT_P(a) (at_param_t*)&parse_buffer[a->next_offset]

(来源:at_char_cmds.c)

len 标记为 volatile,说明解析缓冲区会被中断/UART 接收路径异步写入,主处理路径读取时需要关注数据一致性——这是嵌入式单缓冲区解析的典型做法:牺牲并发写保护换取零拷贝与低内存占用。

使用示例

示例 1:应用初始化时启动 AT 命令层

app_at_char_com.c 在应用启动流程中调用 at_cmd_init(),完成解析缓冲区与通道状态初始化:

        at_cmd_init();

(来源:app_at_char_com.c)

示例 2:文本发送与十六进制转换

命令层对外提供统一的文本发送宏,以及 BLE 数据展示常用的 hex/字符串互转接口:

#define AT_STRING_SEND(a) at_cmd_send((uint8_t *)a,strlen(a))

(来源:at_char_cmds.c)

uint32_t hex_2_str(uint8_t *hex, uint32_t hex_len, uint8_t *str);
uint32_t str_2_hex(uint8_t *str, uint32_t str_len, uint8_t *hex);

(来源:at_char_cmds.h)

示例 3:BLE 扫描结果经 AT 通道上报

主机扫描到外设后,客户端模块把广播数据格式化到发送缓冲区,再调用 at_cmd_send() 推送给 AT 输出流(UART 或 BLE 特征):

    at_cmd_send(at_send_adv_buf, ret);

(来源:ble_at_char_client.c)

上报前会先把原始广播数据用 hex_2_str() 转为可读的十六进制文本:

            ret = hex_2_str(adv_data_pt, lenght - 1, &at_send_adv_buf[5]);
            at_cmd_send(at_send_adv_buf, ret + 5);

(来源:ble_at_char_client.c)

配置选项

配置项类型默认值说明
CONFIG_APP_AT_CHAR_COM宏开关由应用配置决定编译开关;整个命令层代码以 #if CONFIG_APP_AT_CHAR_COM 包裹
G_VERSION字符串"JL_test"AT+GVER 返回的固件版本号
CONFIG_VERSION字符串"2021_02_04"AT+GCFGVER 返回的配置版本号
ADV_INTERVAL_DEFAULT数值2048默认广播间隔(单位:0.625ms 的倍数)
PARSE_BUFFER_SIZE数值256解析缓冲区大小,限制单条 AT 命令总长
BT_UART_FIFIO_BUFFER_SIZE数值0x100UART FIFO 缓冲区大小
TCFG_AT_UART_BAUDRATE数值由板级配置决定AT UART 默认波特率,AT+BAUD 可查询/修改
cur_atcom_cid通道号9AT 指令通道 ID(0-7 主机、8 从机、9 AT 指令)

(配置默认值来源:at_char_cmds.h 与 at_char_cmds.c)

API 参考

以下接口声明均来自 at_char_cmds.h。

void at_cmd_init(void)

初始化 AT 命令层:清空解析缓冲区、复位通道状态。必须在应用启动早期调用一次(见 app_at_char_com.c 的调用点)。

void at_cmd_send(uint8_t *packet, int size)

向 AT 输出通道发送一段原始数据(通常为文本)。

参数:

  • packet (uint8_t*):待发送数据指针
  • size (int):数据长度

说明: 这是所有响应与事件上报的统一出口,UART 与 BLE 特征两条输出路径都经过它。

void at_send_string(char *str)

以 C 字符串形式发送响应文本(内部按 strlen 计算长度)。

void at_send_connected(uint8_t cid) / void at_send_disconnect(uint8_t cid)

连接建立/断开事件上报;cid 为连接通道号,用于区分事件来自哪条 BLE 连接。

void at_send_rx_cid_data(uint8_t cid, uint8_t *packet, uint16_t size)

上报指定通道 cid 收到的数据,用于 BLE 数据透传场景。

void at_respond_send_err(int err_id)

发送错误响应(ERR,<err_id>)。错误码枚举:

enum {
    ERR_AT_CMD = 1,
    //add here
};

(来源:at_char_cmds.h)

uint32_t hex_2_str(uint8_t *hex, uint32_t hex_len, uint8_t *str) / uint32_t str_2_hex(uint8_t *str, uint32_t str_len, uint8_t *hex)

二进制与十六进制文本互转,返回转换后的字节数;用于广播数据、特征值的可读展示与反向解析。

uint8_t at_get_low_power_mode(void) / void at_set_low_power_mode(uint8_t enable)

低功耗模式查询/设置,供 AT+LOWPOWER 命令调用(声明见 at_char_cmds.c)。

失败模式、边界情况与并发

命令解析失败

  • 未知命令名:命令名匹配 at_cmd_str_table 失败时,进入错误分支并通过 at_respond_send_err(ERR_AT_CMD) 返回 ERR,1;ERR_AT_CMD = 1 是当前唯一的错误码,新增错误码应在枚举中"add here"处追加。
  • 超长命令:parse_buffer 固定为 PARSE_BUFFER_SIZE = 256 字节,超过该长度的单条命令会被截断或解析失败。设计上通过限制缓冲区大小换取确定性的内存占用(该缓冲以 NOT_KEEP_RAM + 4 字节对齐声明,见 at_char_cmds.c),适合资源受限的嵌入式环境;如需更长的命令,需同步增大缓冲区并评估 RAM 余量。
  • 参数数量/格式错误:参数以 , 分隔并以 at_param_t 链表组织;处理分支需自行校验参数个数与取值范围(如 AT+ADV=1 的开关值)。错误参数通常落入 ERR 响应。

并发与数据一致性

  • at_param_t.len 声明为 volatile uint8_t,表明接收路径(UART 中断/轮询)与解析路径运行在不同上下文;解析期间应避免被新的接收数据覆盖 parse_buffer,否则会产生半条命令解析。这是单缓冲区设计的固有权衡。
  • AT 指令通道号 cur_atcom_cid = 9 与 BLE 数据通道(0-7 主机、8 从机)严格隔离,避免 AT 文本流与业务数据流互相污染;at_send_rx_cid_data() 通过 cid 参数区分数据归属。

电源与连接边界

  • AT+POWEROFF 直接触发关机流程,属于不可逆操作,应在固件中确认参数后才执行(源码中由处理分支调用电源管理接口)。
  • AT+OTA 会中断当前连接进入升级流程,升级期间 AT 命令层仍应保持响应能力,具体行为取决于 ota 处理分支与升级模块(testbox_uart_update.c / testbox_update.c)的配合。

性能与运维提示

  • 输出热点:at_cmd_send() 是扫描结果、连接事件、数据透传的公共出口,高频事件(如持续扫描)会产生大量文本输出,建议结合 UART FIFO(BT_UART_FIFIO_BUFFER_SIZE = 0x100)与流控策略,避免丢字符。
  • 十六进制转换开销:hex_2_str / str_2_hex 在每条广播/特征数据上报时都会执行,属 O(n) 线性转换;对大批量数据建议在采集端先压缩或仅上报摘要。
  • 调试通道:AT_CHAR_CMD 日志标签已按 verbose/info/debug/warn/error 分级开放(见 log_config.c),排查命令未响应问题时优先打开该标签的 d/e 级日志。

扩展点

新增一条 AT 命令只需四步,全部集中在命令层:

  1. 在 at_char_cmds.h 的 STR_ID_* 枚举中追加新 ID(建议延续 0x20 起的功能分区编号);
  2. 在 at_char_cmds.c 中定义命令字符串常量,如 static const char at_str_xxx[] = "XXX";;
  3. 在 at_cmd_str_table[] 中以 INPUT_STR_INFO(STR_ID_XXX, at_str_xxx) 注册;
  4. 在命令分发处新增 case STR_ID_XXX: 处理分支,按 AT_CMD_OPT_GET/SET 区分查询与设置,成功返回 OK,失败调用 at_respond_send_err()。

由于输入(UART/BLE)与输出(at_cmd_send)均与命令表解耦,新增命令不触碰底层传输代码;若需要新增命令头(如第三个 AT# 前缀),则需同步扩展 at_head_str_table 与 specialchar[]。

相关链接

  • at_char_cmds.c — 命令解析与处理实现
  • at_char_cmds.h — 命令 ID 枚举、结构体与 API 声明
  • app_at_char_com.c — 应用入口与 at_cmd_init 调用
  • at_char_uart.c / at_char_uart.h — AT UART 收发通道
  • ble_at_char_server.c — BLE 从机侧特征与广播实现
  • ble_at_char_client.c — BLE 主机侧扫描/连接与事件上报
  • ble_at_char_profile.h — GATT Profile 定义
Next
硬件参考资料