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

    • SDK 概览与产品定位
    • 支持芯片平台与蓝牙认证
    • SDK 架构与目录分层
  • 快速开始

    • 环境搭建与编译工具链
    • 编译构建系统
    • 板级工程与配置
    • 烧录与固件升级工具
  • 应用工程

    • 应用选择与工程总览
    • SPP + BLE 数传应用框架
    • 透传与 AT 指令示例
    • BLE 广播/中心与定位示例
    • 2.4G 私有协议与 Dongle 示例
    • 云平台接入示例
    • HID 人机交互应用框架
    • HID 示例工程(键盘/鼠标/遥控器/手柄)
    • Bluetooth Mesh 应用框架
    • Mesh 模型与 Mesh DFU 固件升级
    • Mesh 音频编解码演示
  • 芯片平台与硬件抽象

    • 芯片平台总览与差异
    • 音频编解码与时钟管理
    • 外设驱动接口(ADC/IIC/SPI/PWM/LED/充电)
    • 芯片配置工具与下载支持
  • 蓝牙协议栈

    • 蓝牙控制器层(btctrler)
    • 蓝牙协议栈与 Profile(btstack)
    • 蓝牙模块选择与配置
  • 媒体与音频框架

    • 音频流框架
    • 音频编解码与 A2DP 媒体
    • 音频效果处理(EQ/频谱/变调/环绕/超低音)
    • 本地 TWS 与音频同步
  • 系统服务与运行时

    • 实时操作系统与任务调度
    • 消息事件机制
    • 电源管理与低功耗
    • 存储与配置系统
    • 设备驱动框架(USB/RTC)
  • 应用公共组件

    • 音频应用组件
    • 设备外设抽象(按键/触摸/传感器/存储)
    • 蓝牙公共模块与消息联动
    • 调试与配置组件
    • 杰理关键词唤醒(jl_kws)
  • 第三方协议与云平台接入

    • 杰理 RCSP 私有协议
    • 低功耗蓝牙 Mesh 方案(llsync_mesh)
    • Sig Mesh 方案
    • 涂鸦协议接入
    • 腾讯连连接入
    • 华为 HiLink 接入
  • 固件升级与维护

    • OTA 升级机制
    • 升级补丁与版本维护
    • 升级工具链(BLE OTA / USB Dongle OTA)
  • 文档与开发资源

    • 数据手册与架构文档
    • 协议与云平台开发文档
    • 常见问题与技术支持

蓝牙公共模块与消息联动

蓝牙公共模块(bt_common)是 AC63 系列蓝牙 SoC 上承载 BR/EDR 与 BLE 公共能力(初始化、广播、连接、SPP、GATT、MAC 地址、字节序转换等)的薄封装层;消息联动则依赖系统事件总线(event 模块)以 struct bt_event 为载体,将蓝牙协议栈状态(连接状态、HCI 状态、BLE 状态)与键值、TWS、AT 指令等来源的事件统一投递到应用层。

Purpose and Scope

本文档讲解两大主题:

  1. 蓝牙公共模块(bt_common):apps/common/include/bt_common.h 中声明的公共宏、状态位、LE Controller 扩展命令结构体、公共 API(bt_ble_init/bt_ble_exit/bt_ble_adv_enable/user_spp_data_handler 等)以及 apps/common/bt_common/bt_test_api.c 中的 BLE 射频 DUT 测试 API。
  2. 消息联动机制:include_lib/system/event.h 中定义的蓝牙事件类型(SYS_BT_EVENT)、事件来源(SYS_BT_EVENT_FROM_TWS/SYS_BT_EVENT_TYPE_CON_STATUS 等)与 struct bt_event 载荷格式,以及 bt_common.h 中 COMMON_EVENT_* 与应用逻辑联动的约定。

不属于本文范围、请参阅其他目录页的主题:蓝牙协议栈具体状态机(见 btstack 相关文档)、TWS 对箱联动(见 TWS 模块)、AT 指令解析(见 AT 模块)、OTA 升级流程(见 update 模块)。本文只覆盖公共底座与事件投递约定。

Overview

AC63 SDK 的应用代码(apps/ 目录)通过两层机制与蓝牙协议栈交互:

  • 直接调用层(bt_common 公共 API):应用无需关心底层 btstack 细节,通过 bt_common.h 提供的函数完成 BLE 初始化、广播开关、断开连接、MAC 地址读取、SPP 数据收发、GATT 数据收发、发射功率设置等操作。这些 API 是应用与协议栈之间的"稳定接口面"。
  • 事件通知层(消息联动):协议栈内部的异步状态变化(连接/断开、HCI 事件、BLE 配对状态、远端类型变化等)通过系统事件总线以 struct bt_event 广播给应用。应用注册 SYS_BT_EVENT 事件处理器即可响应这些变化,从而实现"协议栈 → 公共模块 → 应用"的解耦联动。

事件来源通过 32 位魔数(('C' << 24) | ('O' << 16) | ('N' << 8) | '\0' 这类写法)编码为可读字符串形式的 from/type 字段,事件载荷为 struct bt_event { u8 event; u8 args[7]; u32 value; }——固定 1 字节事件号 + 7 字节参数 + 4 字节值,结构紧凑、适合嵌入式环境下零拷贝投递。

Architecture

下图展示蓝牙公共模块与消息联动在 AC63 系统中的位置与数据流向:

flowchart TD
    subgraph sg_Stack["蓝牙协议栈(btstack / 控制器)"]
        BREDR["BR/EDR 控制器"]
        LE["BLE 控制器"]
    end

    subgraph sg_Common["蓝牙公共模块 bt_common"]
        API["公共 API<br/>bt_ble_init / bt_ble_adv_enable<br/>user_spp_data_handler / le_att_server_send_data"]
        MAC["MAC 地址与字节序工具<br/>bt_get_mac_addr / little_endian_read_16"]
        DUT["BLE DUT 测试 API<br/>ble_dut_mode_init / ble_fix_fre_api"]
        PWR["功率与射频配置<br/>bt_max_pwr_set / bredr_power_get"]
    end

    subgraph sg_Event["消息联动(事件总线)"]
        BT_EVENT["SYS_BT_EVENT (0x0010)"]
        BT_MSG["struct bt_event<br/>event + args[7] + value"]
        SOURCES["事件来源<br/>TWS / CON_STATUS / HCI_STATUS<br/>BLE_STATUS / KEY / AT / SELF"]
    end

    subgraph sg_App["应用层"]
        APP_HANDLER["应用事件处理器<br/>COMMON_EVENT_* 联动逻辑"]
    end

    BREDR -->|"异步状态"| BT_EVENT
    LE -->|"异步状态"| BT_EVENT
    BT_EVENT --> BT_MSG
    SOURCES --> BT_MSG
    BT_MSG --> APP_HANDLER
    APP_HANDLER -->|"回调公共 API"| API
    API --> BREDR
    API --> LE
    DUT --> LE
    PWR --> BREDR
    MAC --> API

架构说明:底层协议栈(BR/EDR 与 BLE 控制器)产生两类输出——同步可调用的服务能力(由公共 API 封装)和异步状态事件(经事件总线投递)。公共模块夹在中间,既为应用提供稳定的函数接口,又把事件按 SYS_BT_EVENT 分类后以统一载荷格式上抛。应用处理器在收到事件后可以再回调公共 API 执行动作(例如收到断开事件后重新开启广播),形成闭环联动。DUT 测试 API 直接操作 LE 控制器(ll_hci_destory 后接管 HCI),属于调试/产测通道,与正常业务路径隔离。

消息联动机制:事件源、载荷与分发约定

事件总线的注册位

系统事件总线(include_lib/system/event.h)为每个子系统分配一个独立的位掩码,蓝牙占用 0x0010:

#define SYS_ALL_EVENT           0xffff
#define SYS_KEY_EVENT           0x0001
#define SYS_TOUCH_EVENT         0x0002
#define SYS_DEVICE_EVENT        0x0004
#define SYS_NET_EVENT           0x0008
#define SYS_BT_EVENT            0x0010

Source: event.h

设计意图:应用可以一次性订阅 SYS_ALL_EVENT(0xffff)接收全部子系统事件,也可以只订阅 SYS_BT_EVENT 精确过滤蓝牙事件。位掩码设计使事件分发的过滤判断退化为一次位与运算,在中断/低功耗场景下开销极低。

事件来源(from)与类型(type)魔数

事件通过 32 位可读魔数标识"来源"或"类型",例如 ('C' << 24) | ('O' << 16) | ('N' << 8) | '\0' 即字符串 "CON" 的 ASCII 编码:

#define SYS_BT_EVENT_FROM_TWS          (('T' << 24) | ('W' << 16) | ('S' << 8) | '\0')
#define SYS_BT_EVENT_TYPE_CON_STATUS   (('C' << 24) | ('O' << 16) | ('N' << 8) | '\0')
#define SYS_BT_EVENT_TYPE_HCI_STATUS   (('H' << 24) | ('C' << 16) | ('I' << 8) | '\0')
#define SYS_BT_EVENT_BLE_STATUS        (('B' << 24) | ('L' << 16) | ('E' << 8) | '\0')
#define SYS_BT_EVENT_FORM_COMMON       (('C' << 24) | ('M' << 16) | ('M' << 8) | '\0')
#define SYS_BT_EVENT_FROM_KEY          (('K' << 24) | ('E' << 16) | ('Y' << 8) | '\0')
#define SYS_BT_EVENT_FORM_SELF         (('S' << 24) | ('E' << 16) | ('F' << 8) | '\0')
#define SYS_BT_EVENT_FORM_AT           (('I' << 24) | ('A' << 16) | ('T' << 8) | '\0')

Source: event.h

这些宏揭示了消息联动的完整来源矩阵:TWS(对箱)、CON_STATUS(连接状态)、HCI_STATUS(HCI 层状态)、BLE_STATUS(BLE 专属状态)、COMMON(公共模块自产事件)、KEY(按键转蓝牙事件)、SELF(模块自省)、AT(AT 指令触发)。应用处理器据此判断事件语义,避免为不同来源的事件设计同一套处理分支时发生语义混淆。

事件载荷:struct bt_event

所有蓝牙事件统一使用紧凑载荷结构:

struct bt_event {
    u8 event;
    u8 args[7];
    u32 value;
};

Source: event.h

  • event:1 字节事件编号,区分同一来源下的不同子事件;
  • args[7]:7 字节扩展参数,用于携带地址、句柄等小数据;
  • value:4 字节值,用于携带计数值、状态码或大参数。

固定 12 字节的结构便于通过环形队列或邮箱零拷贝投递;应用处理器按 from 宏 + event 编号 + args/value 的组合解析完整语义。

公共联动事件(COMMON_EVENT_*)

bt_common.h 定义了公共模块向应用联动广播的子事件号:

enum {
    COMMON_EVENT_EDR_REMOTE_TYPE = 1,
    COMMON_EVENT_BLE_REMOTE_TYPE,
    COMMON_EVENT_SHUTDOWN_ENABLE,
    COMMON_EVENT_SHUTDOWN_DISABLE,
    COMMON_EVENT_MODE_DETECT,
};

Source: bt_common.h

每个枚举项代表一类联动场景:EDR/BLE 远端类型变化(应用据此切换 UI 或协议栈行为)、关机使能/禁止(配合 sys_auto_shut_down_disable 类逻辑)、模式检测(进入/退出某工作模式)。这些事件通常由公共模块内部产生,通过 SYS_BT_EVENT_FORM_COMMON 来源上抛,应用只需订阅 SYS_BT_EVENT 即可全部接收。

联动时序

下图描述一次典型的"BLE 连接断开 → 应用联动恢复广播"的消息流:

sequenceDiagram
    participant LE as BLE 控制器
    participant Stack as btstack / 公共模块
    participant Bus as 事件总线 SYS_BT_EVENT
    participant App as 应用事件处理器
    participant API as bt_common API

    LE->>Stack: 连接断开(HCI 事件)
    Stack->>Bus: 构造 struct bt_event<br/>(from=BLE_STATUS, event=disconnect)
    Bus->>App: 投递 bt_event
    App->>App: 解析 from/event,执行联动逻辑<br/>(如更新状态图标、清除配对态)
    App->>API: 调用 bt_ble_adv_enable(1) 重新广播
    API->>LE: 下发 HCI LE Set Advertising Enable
    LE-->>API: 广播恢复

设计要点:联动逻辑全部收敛在应用处理器中,协议栈与公共模块不感知应用状态;事件总线只负责搬运,不执行业务,保证各层可独立替换与测试。

蓝牙公共 API(bt_common.h)

常用宏与状态位

公共模块提供一组面向协议栈数据布局的辅助宏,用于把时间、长度、槽位等概念转换为协议字节:

#define SYNC_TIMEOUT_MS(x)              {(x / 10) & 0xff, (x / 10) >> 8}
#define ALIGN_2BYTE(size)               (((size)+1)&0xfffffffe)
#define BYTE_LEN(x...)                  sizeof((u8 []) {x})
#define MS_TO_SLOT(x)                   (x * 8 / 5)
#define UINT24_TO_BYTE(x) \
{ \
    x,      \
    x >> 8, \
    x >> 16 \
}

Source: bt_common.h

  • SYNC_TIMEOUT_MS:把毫秒超时转换为 LE 同步超时双字节(10ms 为 1 单位);
  • MS_TO_SLOT:把毫秒转换为 BR/EDR 时隙(1 时隙 = 0.625ms,即 x * 8 / 5);
  • UINT24_TO_BYTE:把 24 位数值展开为小端 3 字节,用于 LE 广播间隔等 3 字节字段;
  • BYTE_LEN:由初始化列表推导字节长度,用于构造 GATT 数据载荷。

状态位枚举用于标识当前各协议通道的使能状态,供应用查询与联动:

enum {
    ST_BIT_INQUIRY = 0,
    ST_BIT_PAGE_SCAN,
    ST_BIT_BLE_ADV,
    ST_BIT_SPP_CONN,
    ST_BIT_BLE_CONN,
    ST_BIT_WEIXIN_CONN,
};

Source: bt_common.h

BLE 私有消息枚举定义配对链路的应用层消息号(0xF0 起,避开标准 ATT 消息空间):

enum {
    BLE_PRIV_MSG_PAIR_CONFIRM = 0xF0,
    BLE_PRIV_PAIR_ENCRYPTION_CHANGE,
};

Source: bt_common.h

公共 API 总览

API作用备注
bt_ble_init() / bt_ble_exit()BLE 协议栈初始化 / 退出生命周期入口
bt_ble_adv_enable(u8 enable)开关 BLE 广播联动恢复广播的常用调用
ble_app_disconnect()断开 BLE 连接主动断开
ble_module_enable(u8 en)使能/禁止 BLE 模块省电场景
bt_get_mac_addr()读取本机 MAC(返回 const u8 *)用于广播/配对
lib_make_ble_address(u8 *ble, u8 *edr)由 EDR 地址派生 BLE 地址保证双模同源地址
bt_get_vm_mac_addr(u8 *addr)从 VM 区读取 MAC掉电保持
user_spp_data_handler(packet_type, ch, packet, size)SPP 数据接收回调用户覆写实现
transport_spp_init() / transport_spp_disconnect()SPP 传输初始化 / 断开
le_att_server_send_data(cid, packet, size)GATT Server 发送数据返回 int
le_att_client_send_data(cid, packet, size)GATT Client 发送数据返回 int
le_at_client_creat_connection(addr, addr_type)主动建立 LE 连接Client 角色
att_set_conn_handle(handle, type)设置 ATT 连接句柄
bt_max_pwr_set(pwr, pg_pwr, iq_pwr, ble_pwr)设置发射功率最大值解析见 btcontroller_modules.h
bredr_power_get() / bredr_power_put()BR/EDR 射频电源管理低功耗联动
wdt_clear()喂狗长流程防复位
reset_PK_cb_register(cb) / _ext(cb, u16)注册复位配对键回调双模配对复位

Source: bt_common.h

字节序工具

LE 协议大量使用小端序,公共模块提供显式读写函数,避免应用直接解引用可能未对齐的 buffer:

extern uint16_t little_endian_read_16(const uint8_t *buffer, int pos);
extern uint32_t little_endian_read_24(const uint8_t *buffer, int pos);
extern uint32_t little_endian_read_32(const uint8_t *buffer, int pos);
extern void swapX(const uint8_t *src, uint8_t *dst, int len);
extern void little_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value);
extern void little_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value);
extern void big_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value);
extern void big_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value);

Source: bt_common.h

LE 扩展广播命令结构体

为支持蓝牙 5 扩展广播/扫描,公共头文件按 HCI LE Controller 命令字节布局定义了紧凑结构体(全部 _GNU_PACKED_),包括 __ext_adv_report_event、__periodic_adv_report_event、__periodic_creat_sync、__ext_scan_param、__ext_scan_enable、ext_advertising_param、ext_advertising_data、ext_advertising_enable、periodic_advertising_param 等。以广播参数为例:

struct ext_advertising_param {
    u8 Advertising_Handle;
    u16 Advertising_Event_Properties;
    u8 Primary_Advertising_Interval_Min[3];
    u8 Primary_Advertising_Interval_Max[3];
    u8 Primary_Advertising_Channel_Map;
    u8 Own_Address_Type;
    u8 Peer_Address_Type;
    u8 Peer_Address[6];
    u8 Advertising_Filter_Policy;
    u8 Advertising_Tx_Power;
    u8 Primary_Advertising_PHY;
    u8 Secondary_Advertising_Max_Skip;
    u8 Secondary_Advertising_PHY;
    u8 Advertising_SID;
    u8 Scan_Request_Notification_Enable;
} _GNU_PACKED_;

Source: bt_common.h

这些结构体直接映射 HCI LE Set Extended Advertising Parameters 命令参数,字段顺序与蓝牙规范一致,便于公共模块直接 memcpy 到命令缓冲区下发控制器。

配置项

公共模块依赖以下编译期/链接期配置(在 bt_profile_cfg.h / lib_profile_cfg.h 中定义,头文件通过 APP_PRIVATE_PROFILE_CFG 宏选择):

配置项类型默认值(取决于配置)说明
config_le_hci_connection_numconst int配置决定支持同时连接的 LE 连接个数
config_le_sm_support_enableconst int配置决定是否支持 BLE 加密配对(SM)
config_le_gatt_server_numconst int配置决定支持的 GATT Server 角色个数
config_le_gatt_client_numconst int配置决定支持的 GATT Client 角色个数
TCFG_USER_BLE_ENABLE宏配置决定BLE 功能总开关(app_config.h)
CONFIG_BT_MODE宏BT_NORMAL蓝牙工作模式(影响 DUT 行为)

Source: bt_common.h

这些 extern const int 由库侧(btstack/profile 配置)提供,公共 API 与 DUT 代码通过 TCFG_USER_BLE_ENABLE、CONFIG_BT_MODE == BT_NORMAL 等条件编译裁剪行为,保证同一套应用代码可适配不同产品配置。

BLE 射频 DUT 测试 API(bt_test_api.c)

apps/common/bt_common/bt_test_api.c 是公共模块中面向产测/认证的 BLE Direct Test Mode(DUT)实现,独立于正常业务路径编译。

测试参数定义

enum  BLE_DUT_PAYLOAD_TYPE {
    PAYLOAD_TYPE_PRBS9 = 0,
    PAYLOAD_TYPE_11110000,
    PAYLOAD_TYPE_10101010,
    PAYLOAD_TYPE_PRBS15,
    PAYLOAD_TYPE_11111111,
    PAYLOAD_TYPE_00000000,
    PAYLOAD_TYPE_00001111,
    PAYLOAD_TYPE_01010101,
    PAYLOAD_TYPE_SINGLE_CARRIER = 0xf0,
};

enum BLE_DUT_PHY_TYPE {
    BLE_1M_UNCODED_PHY = 1,
    BLE_2M_UNCODED_PHY,
    BLE_1M_CODED_PHY_S8,
    BLE_1M_CODED_PHY_S2,
};

struct ble_dut_param_set {
    u8 ch_index;        //tx ch index;(0~39 -> 2402~2480)
    u8 payload_type;    //tx payload type
    u8 payload_len;     //payload_len(0~0xff) when continuous_tx = 0;
    u8 continuous_tx;   //enable or disable continuous transmission mode(0/1)
};

Source: bt_test_api.c

BLE_DUT_PAYLOAD_TYPE 覆盖蓝牙认证要求的 PRBS9/PRBS15 伪随机序列与多种固定图案(0xAA、0x0F、0xF0、全 0/全 1)以及单载波模式;ch_index 直接映射信道频率 2402~2480MHz。

定频发射与 DUT 模式切换

void ble_fix_fre_api()
{
#if TCFG_USER_BLE_ENABLE
#if (CONFIG_BT_MODE == BT_NORMAL)
    bt_ble_adv_enable(0);
#endif
    os_time_dly(10);

    struct ble_dut_param_set dut_param = {
        .ch_index = 0,
        .payload_type = PAYLOAD_TYPE_10101010,
        .payload_len = 0x20,
        .continuous_tx = 1,
    };
    ble_enter_dut_tx_mode(&dut_param);
#endif
}

Source: bt_test_api.c

ble_fix_fre_api 展示了 DUT 的进入策略:先关闭正常广播(bt_ble_adv_enable(0))以避免射频竞争,延时 10 个系统 tick 让控制器收敛,再以信道 0、0xAA 图案、连续发射模式进入 DUT。条件编译保证 TCFG_USER_BLE_ENABLE 关闭或非 BT_NORMAL 模式下该函数为空操作。

static void *ble_dut_hdl = NULL;
extern void ll_hci_destory(void);
void ble_dut_mode_init(void)
{
    if (!ble_dut_hdl) {
        ll_hci_destory();
        ble_dut_hdl = __ble_dut_ops->init();
    }
}

void ble_dut_mode_exit(void)
{
    if (ble_dut_hdl) {
        // ...释放 DUT 句柄并恢复 HCI
    }
}

Source: bt_test_api.c

ble_dut_mode_init 先调用 ll_hci_destory() 销毁正常 HCI 通道,再通过 __ble_dut_ops->init() 取得 DUT 操作句柄——这解释了为什么注释强调"调用此 API 前必须退出睡眠模式":接管 HCI 后正常协议栈调度已不可用。句柄判空(if (!ble_dut_hdl))保证重复调用只初始化一次,ble_dut_mode_exit 则负责释放并回到正常模式。

公共模块 → DUT 联动

flowchart LR
    A["产测指令/测试盒"] -->|"触发"| B["bt_fix_fre_api()"]
    B --> C{"TCFG_USER_BLE_ENABLE<br/>且 BT_NORMAL?"}
    C -->|"否"| D["空操作"]
    C -->|"是"| E["bt_ble_adv_enable(0)<br/>关闭正常广播"]
    E --> F["os_time_dly(10)<br/>等待收敛"]
    F --> G["构造 ble_dut_param_set"]
    G --> H["ble_enter_dut_tx_mode<br/>进入定频发射"]
    H --> I["ble_dut_mode_init<br/>ll_hci_destory + ops->init"]

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

  • 睡眠模式冲突:源码注释明确警告 DUT API 必须在退出睡眠模式后调用。ll_hci_destory() 接管 HCI 后,若系统进入睡眠,射频时钟可能停止导致测试失效,产测流程必须先调用 sys_auto_shut_down_disable() 之类的接口(见 bt_dut_api 中的 TCFG_AUTO_SHUT_DOWN_TIME 分支)。
  • 重复初始化保护:ble_dut_hdl 静态句柄 + 判空初始化是公共模块典型的"一次性资源"保护模式;若 init() 失败返回 NULL,下次调用会重试,但不会重复销毁已存在的句柄。
  • 双模竞争:ble_fix_fre_api 中先关广播再延时,就是为了避免 EDR/BLE 同频竞争导致的测试功率测量偏差;同理 BR/EDR 测试(bt_fix_fre_api,被 #if 0 屏蔽)需要先 bit_clr_ie(IRQ_BREDR_IDX) 关闭中断。
  • 事件竞争:struct bt_event 的 value 与 args 由发送方一次性填好再投递,总线按队列顺序分发;应用处理器不应在中断上下文执行长逻辑,应只做状态标记后延后处理。
  • 事件号冲突风险:COMMON_EVENT_EDR_REMOTE_TYPE = 1 起始、BLE_PRIV_MSG_PAIR_CONFIRM = 0xF0 起始,两者处于不同事件域(前者是公共事件号,后者是 BLE 私有消息号),扩展时需保持各自域内编号唯一。

扩展点与操作注意事项

  • 新增公共事件:在 bt_common.h 的 COMMON_EVENT_* 枚举尾部追加编号,保持既有编号不变(嵌入式固件无动态重编号机制,编号变化会破坏已发布固件的联动协议)。
  • 新增公共 API:在 bt_common.h 声明 extern 并在 apps/common/bt_common/ 下实现,注意 _GNU_PACKED_ 结构体必须保持字段顺序与蓝牙规范一致,不得按编译器默认对齐。
  • 新增 DUT 图案:向 BLE_DUT_PAYLOAD_TYPE 枚举追加值,并在 __ble_dut_ops 驱动的实现中补充对应图案生成逻辑;PHY 类型同理扩展 BLE_DUT_PHY_TYPE。
  • 产测联调:产测脚本通过测试盒/串口触发 DUT 模式,完成后必须调用 ble_dut_mode_exit 恢复 HCI,否则设备无法再连接手机。
  • 日志开关:bt_test_api.c 顶部通过 LOG_TAG "[BT_DUT]" 与 LOG_*_ENABLE 宏控制调试输出(默认开启 ERROR/DEBUG/INFO 与 CLI 日志),量产版本建议按需裁剪。

测试覆盖

源码中 DUT 路径通过 #if 0 屏蔽了 BR/EDR 定频 API(bt_dut_api/bt_fix_fre_api),说明 BR/EDR 产测默认走库侧 bredr_fcc_init 通道;BLE DUT 路径(ble_fix_fre_api/ble_dut_mode_init/ble_dut_mode_exit)处于可用状态,配合 __ble_dut_ops 驱动完成认证所需的 PRBS/固定图案/单载波发射。公共 API 与事件联动本身无独立单元测试,其正确性依赖集成测试(产测 + 真机连接 + TWS 对箱场景)验证。

典型用法示例

业务路径:开关广播(联动恢复)

从 bt_test_api.c 可以看到公共 API 在业务代码中的标准调用姿势——条件编译保护 + 直接调用:

#if TCFG_USER_BLE_ENABLE
#if (CONFIG_BT_MODE == BT_NORMAL)
    bt_ble_adv_enable(0);   // 关闭广播:进入 DUT 前避免射频竞争
#endif
    os_time_dly(10);
#endif

Source: bt_test_api.c

应用在收到 SYS_BT_EVENT 断开事件后,用同样的方式调用 bt_ble_adv_enable(1) 即可实现"断开即重连广播"的联动逻辑——事件处理器只负责判断(from/event),动作一律落到公共 API。

协议数据路径:解析小端字段

解析广播/扫描报告时,优先使用公共模块的字节序工具而非直接指针转换:

// 假设 buf 指向 __ext_adv_report_event,RSSI 位于 Data 之后偏移处
uint16_t event_type = little_endian_read_16(buf, offsetof(struct __ext_adv_report_event, Event_Type));
uint32_t adv_interval = little_endian_read_24(adv_data, 1); // 3 字节广播间隔

Source: bt_common.h(工具函数声明)与 bt_common.h(事件结构布局)

这种做法的价值在于:LE 载荷多为字节流且可能未对齐,直接 *(u16*)ptr 在部分内核/架构上会触发异常或读到错位数据,而显式小端读取函数是零风险且可移植的。

事件消费路径:订阅与解析

应用侧订阅 SYS_BT_EVENT 后,处理器按三要素解析事件:

// 伪代码示意:应用事件处理器(基于 event.h 定义的宏与结构)
static int app_bt_event_handler(struct bt_event *bt)
{
    switch (bt->event) {
    case COMMON_EVENT_EDR_REMOTE_TYPE:      // bt_common.h 公共联动事件
        // 更新 EDR 远端设备类型 UI
        break;
    case COMMON_EVENT_BLE_REMOTE_TYPE:      // 更新 BLE 远端类型
        break;
    case COMMON_EVENT_SHUTDOWN_DISABLE:     // 联动:禁止自动关机
        break;
    }
    return 0;
}

Source(事件宏与结构定义): bt_common.h、event.h

说明:上述处理器示例为基于头文件定义的标准消费模式示意;实际应用代码位于各产品 app 目录(如 apps/ 下的自定义事件表),本文档仅以公共头文件契约演示联动写法。

相关链接

  • bt_common.h(公共 API 与宏定义)
  • event.h(事件系统与 bt_event 载荷)
  • bt_test_api.c(BLE DUT 测试 API)
  • 蓝牙协议栈状态机与连接管理:见 btstack 相关目录文档
  • TWS 对箱消息(SYS_BT_EVENT_FROM_TWS):见 TWS 模块文档
  • AT 指令触发事件(SYS_BT_EVENT_FORM_AT):见 AT 模块文档
Prev
设备外设抽象(按键/触摸/传感器/存储)
Next
调试与配置组件