1. 背景
本节主要讨论 高通 蓝牙 hal 中,的一些流程。 看看你是否都清楚如下问题:
- 高通芯片电如何控制?
- 串口是在哪里控制的?
- 固件如何下载?
- 初始化流程是怎么样的?
如果你已经对上述讨论的问题,已经很清楚了,那你无需阅读该文章,请自行忽略。当然,也可以给笨叔挑挑错。 欢迎评论,一起探讨,毕竟都是笨叔自己的理解,难免有点出入,我也想进步!!!
在阅读这篇文章之前, 可以先阅读一下两篇文章。
【android bluetooth 框架分析 02】【Module详解 3】【HciHal 模块介绍】
【android bluetooth 协议分析 02】【bluetooth hal 层详解 2】【蓝牙hal层hidl_1.0和hidl_1.1层接口的区别是什么】
我们这里按照 hidl 1.0 接口讲解。1.1 类似。
2. bt server 触发流程
我们先来回顾一下,bt.server 是如何触发 hal 之间的通信的。
在 HciHal 模块的 Start 函数中,我们会去向 SM 获取 hal_1.0 服务, 并且调用 hal 的 initialize 接口
// system/gd/hal/hci_hal_android_hidl.cc
void Start() override {
std::string instance = GetHciInstance();
if (bt_hci_1_1_ != nullptr) {
} else {
// 1. 向 SM 获取 IBluetoothHci_1_0 服务。
bt_hci_ = IBluetoothHci_1_0::getService(instance);
}
LOG_INFO("GetService Done.");
callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会调用我们的 接口
if (bt_hci_1_1_ != nullptr) {
} else {
// 2. 调用 hal 接口, 触发 hal 初始化,将回调接口告知 hal进程。
bt_hci_->initialize(callbacks_);
}
// 3. 等待 hal initialize 执行完成。
callbacks_->GetInitPromise()->get_future().wait();
}
可以将上面 HciHal 模块的 Start 函数 总结为三步:
- 向 SM 找 bt hal 1.0 服务
- 调用 hal initialize
- 等待 hal initialize 完成
我们本节讨论的 蓝牙芯片上电,打开蓝牙串口, 固件下载。 都是在 这里调用 hal initialize 到 hal initialize 完成直接 进行的。
1. 向 SM 找 bt hal 1.0 服务
std::string GetHciInstance() {
char buf[64];
int hci_adapter = InitFlags::GetAdapterIndex();
// 0 -> "default" (default bluetooth adapter)
// 1 -> "hci1" (new bluetooth adapter)
if (hci_adapter > 0) {
snprintf(buf, sizeof(buf), "hci%d", hci_adapter);
} else {
snprintf(buf, sizeof(buf), "default");
}
return std::string(buf);
}
- 如果是 bt0 就找寻 android.hardware.bluetooth@1.0::IBluetoothHci/default 服务, 如果是 bt1 就找寻 android.hardware.bluetooth@1.0::IBluetoothHci/hci1 服务
bt_hci_ = IBluetoothHci_1_0::getService(instance);
- 通过 IBluetoothHci_1_0::getService 就能获取到 android.hardware.bluetooth@1.0::IBluetoothHci/default 服务。
2. 调用 hal initialize
callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会调用我们的 接口
bt_hci_->initialize(callbacks_);
class InternalHciCallbacks : public IBluetoothHciCallbacks {
};
- InternalHciCallbacks 继承了 IBluetoothHciCallbacks。 hal 侧的回调就是调用到这里。
- 通过 调用 hal 的 initialize 方法将 bt.server 的回调函数注册进 hal.
调用 hal 的 initialize 方法 , 将完成很多工作。 完成的工作将在 hal 侧详细介绍。我们这里先梳理流程。
当 hal 侧处理完 initialize 后, 会通知 bt.server.继续执行。
3. 等待 hal initialize 完成
callbacks_->GetInitPromise()->get_future().wait();
std::promise<void>* GetInitPromise() {
return init_promise_;
}
- 通过 init_promise_ 实现等待。
我们看一下, hal 是如何通知我们的。
class InternalHciCallbacks : public IBluetoothHciCallbacks {
Return<void> initializationComplete(HidlStatus status) {
common::StopWatch stop_watch(__func__);
//ASSERT(status == HidlStatus::SUCCESS);
if (status != HidlStatus::SUCCESS) {
ALOGE("HidlStatus is not SUCCESS");
exit(EXIT_FAILURE);
}
init_promise_->set_value();
return Void();
}
}
在第2步,我们将 InternalHciCallbacks 注册进了 hal 进程。 hal 在处理完成 initialize 后,会通过 initializationComplete 告知 .bt.server.
此时,这里的等待就会退出, 继续执行其他操作。
3. hal 侧逻辑
1. hal服务启动和注册
android 系统中 会在对应的 rc 文件中启动当前的 蓝牙hal
service vendor.bluetooth-1-0-xxxx /vendor/bin/hw/android.hardware.bluetooth@1.0-service-xxxx
interface android.hardware.bluetooth@1.0::IBluetoothHci default
class hal
user bluetooth
group bluetooth system wakelock oem_2901 net_raw oem_2912
capabilities BLOCK_SUSPEND NET_ADMIN
// hidl_hci/1.0/default/service.cpp
int main() {
ALOGI("BT-Transport driver main");
(void)umask(S_IWGRP | S_IWOTH);
struct sched_param rt_params;
rt_params.sched_priority = BT_TX_RT_PRIORITY;
android::hardware::ProcessState::initWithMmapSize((size_t)(256144));
configureRpcThreadpool(1, true /*callerWillJoin*/);
ALOGI("isVendorEnhancedFramework: %d", isVendorEnhancedFramework);
ALOGI("Registering BT Service");
status_t status;
status = registerBluetoothHci(); // 注册蓝牙服务
if (status != OK)
ALOGI("Error while registering BT service: %d", status);
ALOGI("BTTPI: Main, joinRpcThreadpool for HIDL");
joinRpcThreadpool();
return status;
}
static status_t registerBluetoothHci()
{
status_t status;
#ifdef DUAL_BT
const char *bt_hci_instance = "hci1";
#else
const char *bt_hci_instance = "default";
#endif
#ifdef LAZY_SERVICE
status = registerLazyPassthroughServiceImplementation<IBluetoothHci>(bt_hci_instance);
#else
status = registerPassthroughServiceImplementation<IBluetoothHci>(bt_hci_instance);
#endif
return status;
}
我们当前的 hal 支持双蓝牙, 从 DUAL_BT 可以看出来,我们通过 编译来控制 编译两个不同的 bin. 用于 bt0 和 bt1.
在 registerBluetoothHci 函数中 当 registerPassthroughServiceImplementation<>() 被调用时:
- 框架在 libhidltransport.so 内部调用一个动态查找函数
- 它尝试在你的 HAL .so 中查找函数:
extern “C” IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
3. 如果找到了,就调用它并返回 HAL 实例
// hidl_hci/1.0/default/bluetooth_hci.cpp
IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name)
{
ALOGI("%s ,new BluetoothHci() name:%s slot:%d", __func__, name, Util::getHwSlot());
Util::init(name);
return new BluetoothHci(Util::getHwSlot());
}
BluetoothHci 继承 IBluetoothHci 接口
class BluetoothHci : public IBluetoothHci {
public:
BluetoothHci();
BluetoothHci(int slot);
~BluetoothHci();
Return<void> initialize(
const ::android::sp<IBluetoothHciCallbacks>& cb) override;
Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
Return<void> close() override;
Return<void> debug(const hidl_handle& handle,
const hidl_vec<hidl_string>& options) override;
private:
void sendDataToController(HciPacketType type, const hidl_vec<uint8_t>& data);
void startDetectBluetooth(int slot);
void stopDetectBluetooth();
::android::sp<IBluetoothHciCallbacks> event_cb_;
::android::sp<BluetoothDeathRecipient> deathRecipient;
int hw_slot_;
std::thread detect_bt_thread_;
};
extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
// bt0 调用
01-13 02:03:20.629763 714 714 I vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: HIDL_FETCH_IBluetoothHci ,new BluetoothHci() name:default slot:0
// bt1 调用
01-13 02:03:20.630275 715 715 I vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: HIDL_FETCH_IBluetoothHci ,new BluetoothHci() name:hci1 slot:0
// 此时 bt0 的服务就已经注册成功了。 bt.server 就可以 get 当前服务了。
01-13 02:03:20.641529 714 714 I HidlServiceManagement: Registered android.hardware.bluetooth@1.0::IBluetoothHci/default
2. initialize 调用
当 bt.server 调用 bt_hci_->initialize(callbacks_);
将调用到如下代码
// hidl_hci/1.0/default/bluetooth_hci.cpp
Return<void> BluetoothHci::initialize(
const ::android::sp<IBluetoothHciCallbacks>& cb)
{
bool rc = false;
ALOGW("BluetoothHci::initialize(), slot%d", hw_slot_);
if (cb == nullptr) {
ALOGE("%s: Received NULL callback from BT client", __func__);
return Void();
}
::android::sp<IBluetoothHciCallbacks> event_cb_tmp;
event_cb_tmp = cb; // 将我们 bt.server 传递进来的 回调保存在 event_cb_tmp 中了。
// 1. 调用 DataHandler::Init 方法
rc = DataHandler::Init( TYPE_BT,
[this, event_cb_tmp](bool status) {
if (event_cb_tmp != nullptr) {
ALOGI("%s: Set callbacks received from BT client inorder "
"to provide status and data through them", __func__);
event_cb_ = event_cb_tmp;
}
if (event_cb_ != nullptr) {
auto hidl_client_status = event_cb_->initializationComplete(
status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback initializationComplete failed");
}
}
},
[this, event_cb_tmp](HciPacketType type, const hidl_vec<uint8_t> *packet) {
DataHandler *data_handler = DataHandler::Get();
if (event_cb_tmp == nullptr) {
ALOGE("BluetoothHci: event_cb_tmp is null");
if (data_handler)
data_handler->SetClientStatus(false, TYPE_BT);
return;
}
/* Skip calling client callback when client is dead */
if(data_handler && (data_handler->GetClientStatus(TYPE_BT) == false)) {
ALOGI("%s: Skip calling client callback when client is dead", __func__);
return;
}
Logger::Get()->UpdateRxTimeStamp();
switch (type) {
case HCI_PACKET_TYPE_EVENT:
{
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_EVT_CALL_BACK);
#endif
auto hidl_client_status = event_cb_tmp->hciEventReceived(*packet);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback hciEventReceived failed");
if (data_handler)
data_handler->SetClientStatus(false, TYPE_BT);
}
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_POST_STACK_EVT_CALL_BACK);
#endif
}
break;
case HCI_PACKET_TYPE_ACL_DATA:
{
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_ACL_CALL_BACK);
#endif
auto hidl_client_status = event_cb_tmp->aclDataReceived(*packet);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback aclDataReceived failed");
if (data_handler)
data_handler->SetClientStatus(false, TYPE_BT);
}
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_POST_STACK_ACL_CALL_BACK);
#endif
}
break;
default:
ALOGE("%s Unexpected event type %d", __func__, type);
break;
}
});
if (!rc && (cb != nullptr)) {
...
} else if (rc && (cb != nullptr)) {
ALOGI("%s: linking to deathRecipient", __func__);
cb->linkToDeath(deathRecipient, 0);
}
return Void();
}
// BluetoothHci::initialize 函数调用开始
01-13 02:03:26.451268 714 714 W vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: BluetoothHci::initialize(), slot0
01-13 02:03:26.451326 714 714 W vendor.RunningAndroid.bluetooth@1.0-data_handler: DataHandler:: Init()
01-13 02:03:26.451454 714 714 I vendor.RunningAndroid.bluetooth@1.0-data_handler: data_service_setup_sighandler: Entry
01-13 02:03:26.451487 714 714 D vendor.RunningAndroid.bluetooth@1.0-data_handler: isProtocolAdded:
01-13 02:03:26.451498 714 714 I vendor.RunningAndroid.bluetooth@1.0-data_handler: isProtocolAdded: status:0
01-13 02:03:26.451507 714 714 I vendor.RunningAndroid.bluetooth@1.0-data_handler: Open init_status 0
01-13 02:03:26.451897 714 714 D vendor.RunningAndroid.bluetooth@1.0-wake_lock: Init wakelock is initiated
// BluetoothHci::initialize 函数调用退出
01-13 02:03:26.452016 714 714 I vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: initialize: linking to deathRecipient
在 BluetoothHci::initialize 中最主要就是调用 DataHandler::Init
1. DataHandler::Init
// hidl_hci/1.0/default/data_handler.cpp
bool DataHandler::Init(ProtocolType type, InitializeCallback init_cb,
DataReadCallback data_read_cb)
{
// lock required incase of multiple binder threads
ALOGW("DataHandler:: Init()");
std::unique_lock<std::mutex> guard(init_mutex_);
Get();
// 将上述两个回调 传入 他的 Open 函数
return data_handler->Open(type, init_cb, data_read_cb);
}
DataHandler::Init 有两个回调 :
-
InitializeCallback init_cb
-
DataReadCallback data_read_cb
1. InitializeCallback init_cb
其中 InitializeCallback init_cb 传入的内容是:
[this, event_cb_tmp](bool status) {
if (event_cb_tmp != nullptr) {
ALOGI("%s: Set callbacks received from BT client inorder "
"to provide status and data through them", __func__);
event_cb_ = event_cb_tmp;
}
if (event_cb_ != nullptr) {
auto hidl_client_status = event_cb_->initializationComplete(
status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback initializationComplete failed");
}
}
}
2. DataReadCallback data_read_cb
DataReadCallback data_read_cb 传入的内容是:
[this, event_cb_tmp](HciPacketType type, const hidl_vec<uint8_t> *packet) {
DataHandler *data_handler = DataHandler::Get();
if (event_cb_tmp == nullptr) {
ALOGE("BluetoothHci: event_cb_tmp is null");
if (data_handler)
data_handler->SetClientStatus(false, TYPE_BT);
return;
}
/* Skip calling client callback when client is dead */
if(data_handler && (data_handler->GetClientStatus(TYPE_BT) == false)) {
ALOGI("%s: Skip calling client callback when client is dead", __func__);
return;
}
Logger::Get()->UpdateRxTimeStamp();
switch (type) {
case HCI_PACKET_TYPE_EVENT:
{
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_EVT_CALL_BACK);
#endif
auto hidl_client_status = event_cb_tmp->hciEventReceived(*packet);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback hciEventReceived failed");
if (data_handler)
data_handler->SetClientStatus(false, TYPE_BT);
}
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_POST_STACK_EVT_CALL_BACK);
#endif
}
break;
case HCI_PACKET_TYPE_ACL_DATA:
{
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_ACL_CALL_BACK);
#endif
auto hidl_client_status = event_cb_tmp->aclDataReceived(*packet);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback aclDataReceived failed");
if (data_handler)
data_handler->SetClientStatus(false, TYPE_BT);
}
#ifdef DUMP_RINGBUF_LOG
Logger::Get()->UpdateRxEventTag(RX_POST_STACK_ACL_CALL_BACK);
#endif
}
break;
default:
ALOGE("%s Unexpected event type %d", __func__, type);
break;
}
}
将上述两个回调 传入 他的 Open 函数
2. DataHandler::Open
bool DataHandler::Open(ProtocolType type, InitializeCallback init_cb,
DataReadCallback data_read_cb)
{
char dst_buff[MAX_BUFF_SIZE];
char init_buff[MAX_BUFF_SIZE];
struct timeval tv;
std::map<ProtocolType, ProtocolCallbacksType *>::iterator it;
std::unique_lock<std::mutex> guard(internal_mutex_);
ALOGI("Open init_status %d \n", init_status_);
// update the pending Init cb and other callbacks
it = protocol_info_.find(type);
if (it == protocol_info_.end()) {
ProtocolCallbacksType *cb_data = new (ProtocolCallbacksType);
cb_data->type = type;
cb_data->is_pending_init_cb = true;
cb_data->init_cb = init_cb; // 将我们回调保存在 cb_data 中
cb_data->data_read_cb = data_read_cb;
protocol_info_[type] = cb_data;
}
switch (init_status_) { // 这里默认的 状态是 0: INIT_STATUS_IDLE
...
case INIT_STATUS_IDLE:
init_status_ = INIT_STATUS_INITIALIZING;
break;
}
// 在这里 创建了一个 线程
init_thread_ = std::thread(...);
return true;
}
也就是说 bt.server 调用 initialize 函数后,hal 侧启动了一个线程 专门干这个事情。 initialize 函数就顺利返回了。
主要 initialize 的工作全部在 该线程中处理了。
3. 转门的线程处理 initialize 工作
线程处理函数如下:
[this, type]() {
// 1. 启动定时器
StartInitTimer();
if (!IsSocAlwaysOnEnabled()) {
soc_need_reload_patch = true;
}
ALOGI("%s: soc_need_reload_patch = %d", __func__, soc_need_reload_patch); // 这里是1
if (soc_type_ == BT_SOC_SMD) {
} else {
// 2. 创建 UartController 对象
controller_ = static_cast<Controller *> (new UartController(soc_type_));
}
if (controller_) {
int retry_count = 0;
// 进入循环 初始化。如果初始化失败,接着尝试
while (retry_count < INIT_MAX_RETRY_TIMES) {
// 3. 调用 controller_->Init 函数
status = controller_->Init([this](ProtocolType ptype, HciPacketType type,
const hidl_vec<uint8_t> *hidl_data) {
OnPacketReady(ptype, type, hidl_data);
});
if (status)
break;
++retry_count;
}
}
...
// 4. 初始化成功后 停止定时器
StopInitTimer();
std::unique_lock<std::mutex> guard(internal_mutex_);
if (status) {
/* Stop moving further if timeout detected */
{
guard.unlock();
std::unique_lock<std::mutex> lock(DataHandler::init_timer_mutex_);
if (GetInitTimerState() == TIMER_OVERFLOW) {
ALOGW("Initialization timeout detected cleanup is in process");
// Init thread exited.
is_init_thread_killed = true;
return;
}
guard.lock();
init_status_ = INIT_STATUS_SUCCESS;
ALOGD("Firmware download succeded.");
}
} else {
...
}
std::map<ProtocolType, ProtocolCallbacksType *>::iterator it;
for (auto& it: protocol_info_) {
ProtocolCallbacksType *cb_data = (ProtocolCallbacksType*)it.second;
cb_data->is_pending_init_cb = false;
gettimeofday(&tv, NULL);
snprintf(dst_buff, sizeof(dst_buff), "Init callback status = %d", status);
BtState::Get()->AddLogTag(cb_status_buf, tv, dst_buff);
BtState::Get()->SetTsStatusOfCbSent(cb_status_buf);
// 5. 调用回调
cb_data->init_cb(status);
}
// clear the list if the controller open call fails
if (!status) {
...
}
guard.unlock();
// BT ON successful
property_set("persist.vendor.service.bdroid.system_delay_crash_count", "0");
// Init thread exited.
is_init_thread_killed = true;
ALOGD("%s: init thread exited now", __func__);
}
这个线程 主要做如下几件事情:
- 启动定时器
- 创建 UartController 对象
- 调用 controller_->Init 函数
- 初始化成功后 停止定时器
- 调用回调 init_cb
1. 启动定时器
启动定时器的目的是, 为了 防止 Controller 交互时, 无响应。 这里不是重点。暂时忽略。
2.创建 UartController 对象
// hidl_hci/1.0/default/uart_controller.cpp
UartController::UartController(BluetoothSocType soc_type)
: soc_crashed(false), soc_type_(soc_type),
hci_packetizer_([this](hidl_vec<uint8_t> *data) { OnPacketReady(data); })
{
...
}
UartController 没有啥可以讲述的,一堆变量。暂时忽略
3. 调用 controller_->Init 函数
bool UartController::Init(PacketReadCallback pkt_read_cb)
{
power_manager_.Init(soc_type_);
// 1. 给芯片 上电
if (soc_need_reload_patch) {
// power off the chip first
power_manager_.SetPower(false);
// power on the chip using power manager
power_manager_.SetPower(true);
}
// 2. 初始化 HciTransport
hci_transport_ = static_cast<HciTransport*> (uart_transport);
ret = uart_transport->Init(soc_type_, soc_need_reload_patch);
// 3. 创建 固件 补丁管理器
patch_dl_manager = new (std::nothrow)PatchDLManager(soc_type_, uart_transport, &power_manager_);
uart_transport->ClockOperation(USERIAL_OP_CLK_ON);
//Download the NVM/RAM patch
if (soc_need_reload_patch) {
logger_->PropertyGet("vendor.wc_transport.skip_patch_dload", skip_patch_download, "false");
if (strcmp(skip_patch_download, "true") != 0) {
// 4. 开始打补丁, 下载固件
if (patch_dl_manager->PerformChipInit() < 0) {
}
temp_add_on_features = patch_dl_manager->GetAddOnFeatureList();
} else {}
}
// 获取 controller 的芯片版本, 做记录使用
chipset_ver_ = patch_dl_manager->GetChipVersion();
init_done_ = true;
ALOGD("Init succeded");
return init_done_;
}
由于篇幅原因,这里将于 下一篇,中讲解 这部分内容
4. 初始化成功后 停止定时器
这里不是重点。暂时忽略。
5. 调用回调 init_cb
当芯片上完电, 已经下载完固件后, 将调用 回调。
cb_data->init_cb(status);
这里将回调到 3.2.1.1 小节中的回调。
[this, event_cb_tmp](bool status) {
if (event_cb_tmp != nullptr) {
ALOGI("%s: Set callbacks received from BT client inorder "
"to provide status and data through them", __func__);
event_cb_ = event_cb_tmp;
}
if (event_cb_ != nullptr) {
auto hidl_client_status = event_cb_->initializationComplete(
status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
if(!hidl_client_status.isOk()) {
ALOGE("Client dead, callback initializationComplete failed");
}
}
}
- 最终会回调到 bt.server 中的 initializationComplete 函数。告知 bt.server 初始化成功。