Android O引入了HIDL的结构。本文不讲HIDL的实现细节。本文通过介绍蓝牙模块使用HIDL前后之间的差别,搞明白HIDL的设计思想。
蓝牙与底层的交互
- 打开并配置transport layer(UART, USB等)。
- 上电
- 下载firmware patch
- 配置firmware相关参数
- LPM(Low Power Management)相关配置(蓝牙工作时,始终要用到lmp的功能)
- 蓝牙收发数据时,transport layer(H4, BCSP等)的拆包和组包工作。
引入HIDL之前,bluedroid与底层相关的代码
主要的代码在system/bt/hci/src/下面
Bluedroid之前的代码(Android N及之前)已经对具体芯片相关的代码做了一套统一的接口。
bt/hc/src/vendor.c
static const bt_vendor_callbacks_t lib_callbacks = {
sizeof(lib_callbacks),
firmware_config_cb,
sco_config_cb,
low_power_mode_cb,
sco_audiostate_cb,
buffer_alloc_cb,
buffer_free_cb,
transmit_cb,
epilog_cb,
a2dp_offload_cb
};
static const vendor_t interface = {
vendor_open,
vendor_close,
send_command,
send_async_command,
set_callback,
vendor_ssrcleanup
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
每个厂商都要为他们的每一款芯片实现libbt-vendor.so,包含注册callback,打开驱动节点,上电,设蓝牙地址,下载firmware patch,配置firmware,lmp操作等功能。在vendor.c中会加载这个libbt-vendor.so的库,并调用相应API让蓝牙芯片工作。
跟transport layer相关的代码是hci_hal_xx.c。实现蓝牙SPEC Vol4: Host Controller Interface相关的功能。有H4, BCSP, USB等。需要有个线程从驱动读取数据,然后再去掉transport layer的包头,再把数据给上层。向下发数据时,也需要加上transport layer的包头。
跟LMP相关的代码在low_power_manager.c中。主要是发送数据包后计时,如果超过一定时间没有再发送数据,那就发送命令给芯片,让芯片进入低功耗模式。
引入HIDL后的代码
引入HIDL后,把bluedroid中的hci_audio.c,hci_hal_xx.c, low_power_manager.c, vendor.c都挪到HIDL那部分了。目前HIDL中还是沿用以前的设计,加载libbt-vendor.so模块,跟芯片交互。HIDL提供API和Callback给Bluedroid。HIDL创建一个线程去读取驱动的数据,并进行transport layer的拆包,组包的工作。LMP功能也在HIDL实现。
hardware/interfaces/bluetooth/1.0/
IBluetoothHci.hal
interface IBluetoothHci {
initialize(IBluetoothHciCallbacks callback);
sendHciCommand(HciPacket command);
sendAclData(HciPacket data);
sendScoData(HciPacket data);
close();
}
IBluetoothHciCallbacks.hal
interface IBluetoothHciCallbacks {
initializationComplete(Status status);
hciEventReceived(HciPacket event);
aclDataReceived(HciPacket data);
scoDataReceived(HciPacket data);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
其中IBluetoothHci的代码实现在HIDL里, IBluetoothHciCallbacks的代码实现在Bluedroid里,初始化时,Bluedroid把callback注册到HIDL里。
我们可以看出来,引入HIDL后,Bluedroid只负责Host部分代码,基本上与芯片无关(除了几个Vendor HCI Command,但是不影响Bluedroid的功能)。Google可以只关心蓝牙Host部分的功能,完全与蓝牙硬件解耦。
HIDL好处
就蓝牙来说HIDL的好处并不是很明显,因为Bluedroid开始就已经定义了一套标准的接口,芯片厂商按照接口来做,对Bluedroid的代码改变不是很大,而且蓝牙协议很严格,transport layer也就那几种,几乎没变动。目前想到的对Google的好处是:
1. 完全隔离硬件的变化,Google只负责标准相关的代码,不用去维护各种硬件相关的代码(修改硬件相关的BUG或引入新的硬件都要提交新的代码,但是这些提交对很多人来说都没有用),极大地减轻了维护代码的工作。能够更好地管理维护他们的核心代码。
2. 可以给硬件厂商定义一套规范标准。对HIDL进行版本控制,就是对规范版本控制