1. 背景
- system/btif/src/stack_manager.cc
在之前的 关键线程 章节中对 bt_stack_manager_thread 介绍时,在 event_init_stack 和 event_start_up_stack 中有如下的调用。
module_init(get_local_module(BTIF_CONFIG_MODULE));
今天我将带领大家一起梳理这部分内容。
2. 数据结构介绍
// system/btif/src/stack_manager.cc
struct module_lookup {const char* name;const module_t* module;
};// system/btcore/include/module.htypedef future_t* (*module_lifecycle_fn)(void);typedef struct {const char* name{nullptr};module_lifecycle_fn init{nullptr};module_lifecycle_fn start_up{nullptr};module_lifecycle_fn shut_down{nullptr};module_lifecycle_fn clean_up{nullptr};const char* dependencies[BTCORE_MAX_MODULE_DEPENDENCIES]{nullptr};
} module_t;
- 上面定义了 module_t 和 module_lookup
- module_lookup 为了方便管理 module_t
- 而 module_t 中定义了很多 函数指针
- typedef future_t* (*)(void);
- init : 模块初始化阶段
- start_up: 模块开始阶段
- shut_down: 模块结束阶段
- clean_up: 模块清理阶段
- typedef future_t* (*)(void);
3. 都有那些模块
- system/btif/src/stack_manager.cc
const struct module_lookup module_table[] = {{BTE_LOGMSG_MODULE, &bte_logmsg_module},{BTIF_CONFIG_MODULE, &btif_config_module},{BT_UTILS_MODULE, &bt_utils_module},{GD_CONTROLLER_MODULE, &gd_controller_module},{GD_IDLE_MODULE, &gd_idle_module},{GD_SHIM_MODULE, &gd_shim_module},{INTEROP_MODULE, &interop_module},{OSI_MODULE, &osi_module},{STACK_CONFIG_MODULE, &stack_config_module},{NULL, NULL},
};
- 从上面的描述可以看到, 我们的 bt_stack_manager_thread 会去启动 这些模块。
3.1 BTE_LOGMSG_MODULE (bte_logmsg_module
)
-
作用:
负责蓝牙协议栈的日志记录(Logging)和调试信息管理。-
提供分级日志输出(如 ERROR/WARN/INFO/DEBUG)。
-
支持动态日志级别控制,便于问题追踪。
-
-
设计原因:
模块化日志系统可以灵活适配不同调试需求,避免日志代码散落在各模块中。
// system/internal_include/bt_trace.h
static const char BTE_LOGMSG_MODULE[] = "bte_logmsg_module";// system/main/bte_logmsg.cc
EXPORT_SYMBOL extern const module_t bte_logmsg_module = {.name = BTE_LOGMSG_MODULE,.init = init,.start_up = NULL,.shut_down = NULL,.clean_up = NULL,.dependencies = {STACK_CONFIG_MODULE, NULL}};
- bte_logmsg_module 模块是依赖 stack_config_module 模块的
3.2 BTIF_CONFIG_MODULE (btif_config_module
)
-
作用:
管理蓝牙的持久化配置(如配对设备信息、蓝牙适配器设置等)。-
通过键值对(Key-Value)存储到文件(如
/data/misc/bluedroid/bt_config.conf
)。 -
提供配置的增删改查接口。
-
-
设计原因:
解耦配置存储逻辑,确保蓝牙服务重启后能恢复状态(如已配对设备)。
// system/btif/include/btif_config.h
static const char BTIF_CONFIG_MODULE[] = "btif_config_module";// system/btif/src/btif_config.cc
EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE,.init = init,.start_up = NULL,.shut_down = shut_down,.clean_up = clean_up};
3.3 BT_UTILS_MODULE (bt_utils_module
)
-
作用:
提供蓝牙通用的工具函数和辅助功能。- 包括地址转换(如 MAC 地址字符串与二进制互转)、线程管理、定时器等。
-
设计原因:
集中复用工具代码,避免重复实现,提高可维护性。
// system/utils/include/bt_utils.h
static const char BT_UTILS_MODULE[] = "bt_utils_module";// system/utils/src/bt_utils.cc
EXPORT_SYMBOL extern const module_t bt_utils_module = {.name = BT_UTILS_MODULE,.init = init,.start_up = NULL,.shut_down = NULL,.clean_up = clean_up,.dependencies = {NULL}};
3.4 GD_CONTROLLER_MODULE (gd_controller_module
)
-
作用:
属于 Google’s Floss (GD) 架构的一部分,负责蓝牙控制器的抽象层(HCI 层)。-
封装与蓝牙硬件控制器(如 Broadcom/Qualcomm 芯片)的交互。
-
实现 HCI 命令/事件的统一处理。
-
-
设计原因:
通过硬件抽象层(HAL)兼容不同厂商的蓝牙芯片,便于移植到新硬件平台。
// system/main/shim/controller.h
static const char GD_CONTROLLER_MODULE[] = "gd_controller_module";// system/main/shim/controller.cc
EXPORT_SYMBOL extern const module_t gd_controller_module = {.name = GD_CONTROLLER_MODULE,.init = nullptr,.start_up = start_up,.shut_down = shut_down,.clean_up = nullptr,.dependencies = {GD_SHIM_MODULE, nullptr}};
3.5 GD_IDLE_MODULE (gd_idle_module
)
-
作用:
管理蓝牙协议栈的低功耗(Idle)状态。- 处理蓝牙空闲时的电源管理(如进入/退出低功耗模式)。
-
设计原因:
优化功耗,延长设备续航,尤其对 IoT 设备至关重要。
// system/main/shim/shim.h
static const char GD_IDLE_MODULE[] = "gd_idle_module";// system/main/shim/shim.cc
EXPORT_SYMBOL extern const module_t gd_idle_module = {.name = GD_IDLE_MODULE,.init = kUnusedModuleApi,.start_up = IdleModuleStartUp,.shut_down = GeneralShutDown,.clean_up = kUnusedModuleApi,.dependencies = {kUnusedModuleDependencies}};
3.6 GD_SHIM_MODULE (gd_shim_module
)
-
作用:
作为 新旧蓝牙协议栈的兼容层(Shim Layer)。- 将传统的 Bluedroid 接口适配到新的 GD(Google Direct)架构。
-
设计原因:
渐进式重构蓝牙协议栈时,确保旧代码(如 Android 传统蓝牙服务)能无缝调用新模块。
// system/main/shim/shim.h
static const char GD_SHIM_MODULE[] = "gd_shim_module";// system/main/shim/shim.cc
EXPORT_SYMBOL extern const module_t gd_shim_module = {.name = GD_SHIM_MODULE,.init = kUnusedModuleApi,.start_up = ShimModuleStartUp,.shut_down = GeneralShutDown,.clean_up = kUnusedModuleApi,.dependencies = {kUnusedModuleDependencies}};
3.7 INTEROP_MODULE (interop_module
)
-
作用:
处理蓝牙设备的互操作性(Interoperability)问题。-
维护厂商特定设备的兼容性规则(如规避某些设备的错误行为)。
-
例如:解决特定耳机连接失败或音频断连的问题。
-
-
设计原因:
集中管理碎片化兼容性问题,避免硬编码在协议栈各处。
// system/device/include/interop.h
static const char INTEROP_MODULE[] = "interop_module";// system/device/src/interop.cc
EXPORT_SYMBOL module_t interop_module = {.name = INTEROP_MODULE,.init = NULL,.start_up = NULL,.shut_down = NULL,.clean_up = interop_clean_up,.dependencies = {NULL},
};
3.8 OSI_MODULE (osi_module
)
-
作用:
提供操作系统抽象层(OS Abstraction)。-
封装线程、锁、内存分配、Socket 等系统调用。
-
例如:
osi_malloc()
替代malloc()
,便于内存调试。
-
-
设计原因:
增强跨平台可移植性(如 Linux/RTOS),方便单元测试(Mock 系统调用)。
// system/btcore/include/osi_module.h
static const char OSI_MODULE[] = "osi_module";// system/btcore/src/osi_module.cc
EXPORT_SYMBOL extern const module_t osi_module = {.name = OSI_MODULE,.init = osi_init,.start_up = NULL,.shut_down = NULL,.clean_up = osi_clean_up,.dependencies = {NULL}};
3.9 STACK_CONFIG_MODULE (stack_config_module
)
-
作用:
管理蓝牙协议栈的运行时配置(非持久化)。- 例如:调整 ACL 包大小、重传超时时间等参数。
-
设计原因:
动态配置可适应不同设备需求(如手机 vs 车载蓝牙)。
// system/internal_include/stack_config.h
static const char STACK_CONFIG_MODULE[] = "stack_config_module";// system/main/stack_config.cc
EXPORT_SYMBOL extern const module_t stack_config_module = {.name = STACK_CONFIG_MODULE,.init = init,.start_up = NULL,.shut_down = NULL,.clean_up = clean_up,.dependencies = {NULL}};
3.10 模块化设计的核心原因
-
解耦与复用:
-
各模块职责单一,通过接口交互,避免代码臃肿。
-
例如:
osi_module
可被所有模块调用,无需重复实现线程管理。
-
-
可维护性:
- 独立模块便于单独修复/升级(如
interop_module
更新兼容性列表不影响其他模块)。
- 独立模块便于单独修复/升级(如
-
兼容性:
- 通过
gd_shim_module
平滑过渡到新架构,降低迁移成本。
- 通过
-
可测试性:
- 模块化便于单元测试(如 Mock
btif_config_module
测试配置逻辑)。
- 模块化便于单元测试(如 Mock
-
功耗与性能优化:
- 独立模块(如
gd_idle_module
)可深度优化电源管理。
- 独立模块(如
3.11 小结
Android 蓝牙协议栈的模块化设计反映了现代嵌入式系统的典型架构:分层抽象、职责分离、灵活扩展。这种设计能够快速适配不同硬件厂商、蓝牙版本(如 4.2/5.0)和产品形态(手机/IoT/汽车),同时保持代码的可维护性和可调试性。
4. 模块的生命周期函数
在看模块生命周期时,我们先来看一个函数 get_local_module
inline const module_t* get_local_module(const char* name) {size_t len = strlen(name);for (const struct module_lookup* l = module_table; l->module; l++) {if (strncmp(l->name, name, len) == 0) {return l->module;}}LOG_ALWAYS_FATAL("Cannot find module %s, aborting", name);return nullptr;
}
- 从上面代码可以直观的看到, 我们通过 name 从 module_table 表中, 找到我们对应的 module_t
4.1 初始化阶段
- system/btcore/src/module.cc
bool module_init(const module_t* module) {call_lifecycle_function(module->init);set_module_state(module, MODULE_STATE_INITIALIZED);return true;
}
4.2 启动阶段
bool module_start_up(const module_t* module) {call_lifecycle_function(module->start_up);LOG_INFO("%s Started module \"%s\"", __func__, module->name);set_module_state(module, MODULE_STATE_STARTED);return true;
}
4.3 停止阶段
void module_shut_down(const module_t* module) {call_lifecycle_function(module->shut_down);LOG_INFO("%s Shutdown of module \"%s\" completed", __func__, module->name);set_module_state(module, MODULE_STATE_INITIALIZED);
}
4.4 清理阶段
void module_clean_up(const module_t* module) {call_lifecycle_function(module->clean_up);LOG_INFO("%s Cleanup of module \"%s\" completed", __func__, module->name);set_module_state(module, MODULE_STATE_NONE);
}
5. 结合 bt_stack_manager_thread 看模块生命周期
5.1 event_init_stack
static void event_init_stack(void* context) {module_init(get_local_module(OSI_MODULE));module_init(get_local_module(BT_UTILS_MODULE));module_start_up(get_local_module(GD_IDLE_MODULE));module_init(get_local_module(BTIF_CONFIG_MODULE));module_init(get_local_module(INTEROP_MODULE));module_init(get_local_module(STACK_CONFIG_MODULE));}
event_init_stack
阶段:基础环境搭建
初始化的模块:
-
OSI_MODULE(操作系统抽象层)
- 原因:必须先初始化,为其他模块提供线程、锁、内存分配等基础能力。
- 依赖:无依赖,是其他所有模块的基础设施。
-
BT_UTILS_MODULE(通用工具)
- 原因:提供地址转换、数据结构等工具,后续模块(如配置管理)可能依赖。
-
BTIF_CONFIG_MODULE(持久化配置)
- 原因:需尽早加载,读取蓝牙适配器的历史配置(如已配对设备)。
-
INTEROP_MODULE(兼容性规则)
- 原因:在协议栈启动前加载设备兼容性规则,避免运行时冲突。
-
STACK_CONFIG_MODULE(运行时配置)
- 原因:设置协议栈参数(如超时时间),影响后续模块行为。
启动的模块:
- GD_IDLE_MODULE(低功耗管理)
- 原因:协议栈初始化阶段可能涉及硬件唤醒,需提前管理功耗状态。
设计逻辑:
此阶段聚焦于 基础设施和静态配置,确保后续模块能在正确的环境和配置下运行。
- 依赖顺序:
OSI_MODULE
→BT_UTILS_MODULE
→ 配置/兼容性模块。 - 功耗控制:初始化时硬件可能未完全就绪,
GD_IDLE_MODULE
负责维持低功耗。
5.2 event_start_up_stack
static void event_start_up_stack(UNUSED_ATTR void* context) {module_shut_down(get_local_module(GD_IDLE_MODULE));module_start_up(get_local_module(GD_SHIM_MODULE));module_start_up(get_local_module(BTIF_CONFIG_MODULE));module_init(get_local_module(BTE_LOGMSG_MODULE));}
event_start_up_stack
阶段:协议栈核心功能启动
停止的模块:
- GD_IDLE_MODULE
- 原因:协议栈正式启动需退出低功耗模式,确保硬件(如蓝牙芯片)全功率运行。
启动的模块:
-
GD_SHIM_MODULE(兼容层)
- 原因:新旧协议栈适配需在核心功能(如 HCI 通信)启动前完成。
-
BTE_LOGMSG_MODULE(日志系统)
- 原因:协议栈运行时需要记录日志,但初始化阶段可能尚未需要详细日志。
设计逻辑:
此阶段是 协议栈激活的关键转折点:
- 功耗与性能权衡:停止
GD_IDLE_MODULE
以换取性能。 - 日志延迟加载:避免初始化阶段的冗余日志污染(如硬件自检日志)。
- Shim 层优先级:确保旧代码能正确调用新 GD 架构的功能。
5.3 event_shut_down_stack
static void event_shut_down_stack(UNUSED_ATTR void* context) {module_shut_down(get_local_module(BTIF_CONFIG_MODULE));module_clean_up(get_local_module(BTE_LOGMSG_MODULE));module_shut_down(get_local_module(GD_SHIM_MODULE));module_start_up(get_local_module(GD_IDLE_MODULE));}
在 bt_stack_manager_thread 的 event_shut_down_stack 阶段:
- 结束 BTIF_CONFIG_MODULE、GD_SHIM_MODULE
- 清理 BTE_LOGMSG_MODULE
- 开启 GD_IDLE_MODULE
event_shut_down_stack
阶段:协议栈软关闭
结束的模块:
-
BTIF_CONFIG_MODULE
- 原因:保存当前状态(如连接设备列表)到持久化配置。
-
GD_SHIM_MODULE
- 原因:关闭新旧协议栈的交互通道,避免残留调用。
清理的模块:
- BTE_LOGMSG_MODULE
- 原因:释放日志资源,确保日志文件完整性。
启动的模块:
- GD_IDLE_MODULE
- 原因:协议栈关闭后,硬件应回到低功耗状态。
设计逻辑:
此阶段是 安全释放资源 的过程:
- 数据持久化:
BTIF_CONFIG_MODULE
必须最后关闭,确保配置保存。 - 功耗优先:关闭后立即启用
GD_IDLE_MODULE
节能。
5.4 event_clean_up_stack
static void event_clean_up_stack(std::promise<void> promise) {module_clean_up(get_local_module(STACK_CONFIG_MODULE));module_clean_up(get_local_module(INTEROP_MODULE));module_clean_up(get_local_module(BTIF_CONFIG_MODULE));module_clean_up(get_local_module(BT_UTILS_MODULE));module_clean_up(get_local_module(OSI_MODULE));module_shut_down(get_local_module(GD_IDLE_MODULE));}
在 bt_stack_manager_thread 的 event_clean_up_stack 阶段:
- 清除 STACK_CONFIG_MODULE、INTEROP_MODULE、BTIF_CONFIG_MODULE、BT_UTILS_MODULE、OSI_MODULE
- 关闭 GD_IDLE_MODULE
event_clean_up_stack
阶段:彻底清理
清除的模块:
- 逆序销毁:
STACK_CONFIG_MODULE
→INTEROP_MODULE
→BTIF_CONFIG_MODULE
→BT_UTILS_MODULE
→OSI_MODULE
- 原因:按依赖关系的逆序销毁(类似栈结构)。
- 例如:
BTIF_CONFIG_MODULE
可能依赖OSI_MODULE
的文件操作,必须先销毁前者。
- 例如:
- 原因:按依赖关系的逆序销毁(类似栈结构)。
关闭 GD_IDLE_MODULE
- 原因:所有模块清理完毕后,彻底关闭功耗管理。
设计逻辑:
此阶段是 资源回收的终局:
- 避免内存泄漏:严格逆序销毁,防止模块间资源悬挂引用。
- 彻底断电:最后关闭
GD_IDLE_MODULE
确保硬件完全休眠。
5.5 总结:模块化设计的优势
- 生命周期管理:
- 模块的加载/卸载顺序严格匹配依赖关系(如
OSI_MODULE
最先加载、最后销毁)。
- 模块的加载/卸载顺序严格匹配依赖关系(如
- 状态隔离:
- 不同阶段通过
GD_IDLE_MODULE
切换功耗状态,避免无效唤醒。
- 不同阶段通过
- 故障安全:
- 关闭时优先保存配置(
BTIF_CONFIG_MODULE
),即使崩溃也能恢复数据。
- 关闭时优先保存配置(
- 动态调整:
- 运行时通过
STACK_CONFIG_MODULE
调整参数,无需重启协议栈。
- 运行时通过
这种设计本质上是一个 分层状态机,通过模块的启停组合实现蓝牙协议栈的 平滑启动、安全关闭和低功耗管理,同时满足 Android 蓝牙对 可靠性、功耗和兼容性 的严苛要求。