mp_hi3781v735 平台适配兆通微 9612U 蓝牙模组
基于 OpenHarmony 6.1 Release
1. 适配背景与目标
本文以 mp_hi3781v735 平台 为例,介绍在 OpenHarmony 6.1 Release 系统中适配 兆通微 9612U USB 蓝牙模组 的过程。
蓝牙模组本身只是一个硬件设备。将其接入开发板后,系统并不能天然识别和使用该模组,需要通过驱动和适配层完成硬件与操作系统之间的衔接。驱动适配的核心目标是让系统能够正确完成以下动作:
- 发现蓝牙 USB 设备;
- 加载对应内核驱动;
- 初始化蓝牙 HCI 通路;
- 向 OpenHarmony 蓝牙协议栈提供统一访问接口;
- 支持上层应用通过标准蓝牙 API 使用蓝牙功能。
本次适配主要包括三个部分:
- 编译并加载 USB 蓝牙内核驱动
ztop_bt_usb.ko; - 集成蓝牙 Vendor 适配层
libbt_vendor.so; - 修改 OpenHarmony 系统配置,使驱动和适配库随系统镜像一同编译、打包和加载。
2. USB 蓝牙内核驱动适配
2.1 .ko 内核模块的作用
.ko 是 Linux Kernel Object 的缩写,即 Linux 内核模块。它允许开发者在系统运行时动态加载一段内核态代码,而无需重新编译完整内核。
在本案例中,兆通微提供的 USB 蓝牙驱动最终会编译生成:
ztop_bt_usb.ko
该模块负责完成 USB 蓝牙芯片和 Linux 内核之间的对接,使内核能够识别并驱动 9612U 蓝牙模组。
2.2 ztop_bt_usb.ko 的功能定位
ztop_bt_usb.ko 的主要作用是建立底层硬件访问通路。它位于内核空间,向上承接蓝牙 HCI 数据传输需求,向下控制 USB 蓝牙设备。
简单来说,它解决的是:
系统内核如何识别并驱动这个 USB 蓝牙模组。
在整体蓝牙架构中,ztop_bt_usb.ko 并不直接面向应用层,而是为用户空间的 Vendor 适配库和蓝牙协议栈提供底层能力。
3. 编译 ztop_bt_usb.ko
3.1 编译环境准备
模组厂商提供的驱动源码放置在项目根目录下:
ZTOP/
其中,内核驱动源码目录为:
ZTOP/bt_driver/bt_driver
本次驱动编译的大致调用链如下:
build_log_parse.sh
-> Makefile
-> make_helpers/build_plat/*.mk
-> ztop_bt_usb.ko
其中,make_helpers/build_plat/*.mk 是不同平台的编译参数配置文件,是本次适配中需要重点关注的部分。
3.2 平台配置文件
平台定义文件位于:
make_helpers/build_plat/*.mk
适配新平台时,需要参考厂商已有平台的 .mk 文件,新增或修改对应平台配置。本案例中新增或调整的是 hi3781v735 平台相关配置。
需要重点确认以下参数:
| 参数 | 含义 | mp_hi3781v735 示例 |
|---|---|---|
ARCH |
CPU 架构 | arm64 |
CROSS_COMPILE |
交叉编译器前缀 | aarch64-v100-linux- |
KVER |
目标板内核版本 | 5.10.210-shaolingun+ |
KSRC |
内核编译产物目录 | out/shaolingun/obj/KERNEL_OBJ_D |
OS_TYPE |
系统类型 | OS_ANDROID 或 OS_LINUX |
BUILD_ARGS |
编译器及构建参数 | V=$(V) LLVM=$(LLVM) CC=$(CC) LD=$(LD) |

其中,
KVER 应与开发板上的内核版本保持一致,可通过以下命令确认:
uname -r
KSRC 需要指向编译机上的内核编译产物目录,并且该目录下应存在 .config 文件:
ls out/shaolingun/obj/KERNEL_OBJ_D/.config
如果 KVER 或 KSRC 配置错误,通常会导致模块编译失败,或者编译出的 .ko 文件无法在目标板上加载。
上述参数对应Makefile 文件中

3.3 编译入口脚本
驱动编译入口脚本为:
build_log_parse.sh
该脚本接收三个核心参数:
product:产品类型;interface:接口类型;build-plat:构建平台,对应.mk平台配置文件。
本案例中可执行以下命令:
./build_log_parse.sh --product=zt9612 --interface=usb --build-plat=hi3781v735
由于厂商脚本中已设置默认产品和接口参数,如果默认值与本次目标一致,也可以简化为:
./build_log_parse.sh --build-plat=hi3781v735
编译成功后,应生成目标内核模块:
ztop_bt_usb.ko
4. 系统启动阶段自动加载驱动
4.1 init 配置文件
为了让系统启动时自动加载蓝牙 USB 驱动,需要修改平台 init 配置文件:
vendor/hisilicon/mp_hi3781v735/image_cfg/system/cfg/init.shaolingun.cfg
该文件中的 pre-init、init、fs、boot 等字段代表系统启动过程中的不同阶段。init 进程会在不同阶段执行对应的命令。
4.2 fs 阶段配置
fs 阶段通常用于执行文件系统准备、驱动模块加载、设备节点初始化等操作。
本次适配中,核心命令为:
insmod /vendor/etc/bluetooth/ztop_bt_usb.ko
该命令用于加载兆通微 USB 蓝牙内核驱动。
同时,还需要配置相关设备节点权限,例如:
chown bluetooth bluetooth /dev/uhid
/dev/uhid 是用户态 HID 设备接口,蓝牙 HID 相关功能可能依赖该节点。
4.3 boot 阶段配置
boot 阶段一般用于系统启动后期的权限配置、服务运行环境准备等。
本次涉及的典型配置包括:
chown blue_host blue_host /sys/class/rfkill/rfkill0/state
chown bluetooth bluetooth /dev/tun
其中:
/sys/class/rfkill/rfkill0/state用于控制无线设备开关状态;/dev/tun用于虚拟网络设备访问,部分蓝牙网络相关功能可能依赖该节点。

需要说明的是,本次适配属于系统版本升级适配,部分原有权限配置如
0777、0775 存在权限过宽的问题。为了降低版本升级带来的行为差异,本次暂未调整这些历史配置,但后续正式产品化时建议结合安全规范进一步收敛权限。
5. 蓝牙 Vendor 适配层集成
5.1 Vendor 适配层的作用
蓝牙 Vendor 适配层位于 OpenHarmony 蓝牙 HDI Service 与底层蓝牙硬件之间,核心产物为:
libbt_vendor.so
它本质上是一个蓝牙 HCI 传输层适配库,用于屏蔽底层模组差异。
上层 HDI Service 只需要通过统一接口调用:
init();op();close()。
至于底层使用 USB 还是 UART、H4 还是 H5 协议,则由 Vendor 适配层负责处理。
在本案例中,厂商提供的 Vendor 适配层源码位于:
ZTOP/bt_driver/code/libbt-vendor
5.2 创建蓝牙部件目录
在 OpenHarmony 工程中创建蓝牙适配目录:
device/board/hisilicon/shaolingun/bluetooth
将厂商源码中的以下目录复制到该目录下:
codec
include
src
同时创建配置目录:
device/board/hisilicon/shaolingun/bluetooth/cfg
并将以下文件复制到 cfg 目录:
ztop_bt_usb.ko
ztopbt.conf
最终目录结构示例如下:
device/board/hisilicon/shaolingun/bluetooth
├── BUILD.gn
├── cfg
│ ├── ztop_bt_usb.ko
│ └── ztopbt.conf
├── codec
├── include
└── src
6. 配置 OpenHarmony 编译系统
6.1 编写 BUILD.gn
在以下路径创建 BUILD.gn 文件:
device/board/hisilicon/shaolingun/bluetooth/BUILD.gn
该文件主要完成三件事:
- 定义蓝牙构建组
bt_group; - 将
ztop_bt_usb.ko和ztopbt.conf预置到系统镜像; - 编译生成
libbt_vendor动态库。
示例配置如下:
import("//build/ohos.gni")
group("bt_group") {
deps = [
":ztop_bt_usb",
":ztopbt.conf",
":libbt_vendor",
]
}
config("bt_warnings") {
cflags = [
"-Wall",
"-Werror",
"-Wno-unused-but-set-variable",
"-Wno-switch",
"-Wno-unused-function",
"-Wno-unused-parameter",
"-Wno-unused-variable",
"-Wno-implicit-function-declaration",
"-Wno-incompatible-pointer-types",
"-Wno-ignored-attributes",
"-Wno-misleading-indentation",
]
}
ohos_prebuilt_etc("ztop_bt_usb") {
source = "cfg/ztop_bt_usb.ko"
install_enable = true
install_images = [ chipset_base_dir ]
subsystem_name = "device_shaolingun"
part_name = "device_shaolingun"
relative_install_dir = "./bluetooth"
}
ohos_prebuilt_etc("ztopbt.conf") {
source = "cfg/ztopbt.conf"
install_enable = true
install_images = [ chipset_base_dir ]
subsystem_name = "device_shaolingun"
part_name = "device_shaolingun"
relative_install_dir = "./bluetooth"
}
ohos_shared_library("libbt_vendor") {
output_name = "libbt_vendor"
sources = [
"codec/plc/sbcplc.c",
"codec/sbc/sbc.c",
"codec/sbc/sbc_primitives.c",
"codec/sbc/sbc_primitives_mmx.c",
"codec/sbc/sbc_primitives_neon.c",
"src/ztop_socket.c",
"src/bt_vendor_ztop.c",
"src/hardware.c",
"src/userial_vendor.c",
"src/upio.c",
"src/bt_list.c",
"src/bt_skbuff.c",
"src/hci_h5.c",
"src/ztop_parse.c",
"src/ztop_btservice.c",
"src/hardware_uart.c",
"src/hardware_usb.c",
"src/ztop_heartbeat.c",
"src/ztop_poll.c",
"src/ztop_btsnoop_net.c",
]
include_dirs = [
"include",
"codec/sbc",
"codec/plc",
"//commonlibrary/c_utils/base/include",
"//base/hiviewdfx/interfaces/innerkits/libhilog/include",
"//drivers/peripheral/bluetooth/hci/hdi_service/implement",
]
configs = [ ":bt_warnings" ]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
]
install_enable = true
install_images = [ chipset_base_dir ]
subsystem_name = "device_shaolingun"
part_name = "device_shaolingun"
}
配置完成后,编译系统会将:
ztop_bt_usb.ko
ztopbt.conf
libbt_vendor.z.so
打包到对应镜像中。
6.2 修改 bundle.json
为了让蓝牙适配部件参与系统编译,需要修改:
device/board/hisilicon/shaolingun/bundle.json
在 sub_component 中加入蓝牙构建目标:
{
"build": {
"sub_component": [
"//device/board/hisilicon/shaolingun/cfg:init_configs",
"//device/board/hisilicon/shaolingun/hardware:hardware_group",
"//device/board/hisilicon/shaolingun/bluetooth:bt_group"
],
"test": []
}
}
完成后,执行项目对应的增量编译命令,即可将蓝牙 Vendor 适配层和相关配置文件集成到系统镜像中。
7. OpenHarmony 蓝牙接口适配
OpenHarmony 蓝牙框架通过 HDI Service 与底层 Vendor 适配库交互。对于具体蓝牙模组而言,接口适配的重点在于确保:
- HDI Service 能够正确加载
libbt_vendor.z.so; - Vendor 库提供的
init、op、close等接口符合 OpenHarmony 预期; - HCI 通路初始化成功;
- 蓝牙控制命令和事件能够正常收发;
- 蓝牙服务启动过程中无 HCI 初始化失败、权限不足或设备节点缺失等异常。
本案例中,兆通微厂商提供的源码原始目标环境为 Android,因此在 OpenHarmony 6.1 Release 中集成时,需要重点关注接口定义的差异。
参考文档:
芯片解决方案--SL8541e-OpenHarmony蓝牙适配分析及方案
兆通微 9612U 模组OpenHarmony蓝牙驱动接口适配方案
8. 适配验证建议
完成编译和烧录后,可以从以下几个方面验证适配结果。
8.1 驱动加载验证
确认内核模块是否已加载:
lsmod | grep ztop
查看内核日志:
dmesg | grep -i ztop
dmesg | grep -i bluetooth
dmesg | grep -i usb
如果 ztop_bt_usb.ko 加载失败,通常需要重点检查:
.ko 文件路径是否正确;
uname -r 是否与编译时 KVER 一致;
内核符号是否匹配;
init 阶段是否正确执行 insmod;
USB 蓝牙设备是否被内核识别。
8.2 文件打包验证
确认相关文件是否已进入系统镜像:
ls -l /vendor/etc/bluetooth/
预期应能看到:
ztop_bt_usb.ko
ztopbt.conf
同时确认 Vendor 库是否存在:
ls -l /vendor/lib64/ | grep libbt_vendor
或根据实际安装路径检查:
find /vendor -name "libbt_vendor*"
8.3 蓝牙服务验证
查看蓝牙相关日志
hilog | grep -i bluetooth
hilog | grep -i hci
hilog | grep -i vendor
适配成功后,通常应满足以下现象:
- 蓝牙服务正常启动;
- HCI 初始化无失败日志;
- 系统设置中可以打开蓝牙;
- 可以扫描附近蓝牙设备;
- 可完成基础配对或连接测试。
9. 总结
本案例完成了 mp_hi3781v735 平台上兆通微 9612U USB 蓝牙模组在 OpenHarmony 6.1 Release 中的适配工作。整体适配链路可以概括为:
USB 蓝牙硬件
-> ztop_bt_usb.ko 内核驱动
-> libbt_vendor.z.so Vendor 适配层
-> OpenHarmony 蓝牙 HDI Service
-> 蓝牙协议栈与应用层接口
其中:
-
ztop_bt_usb.ko负责内核态 USB 蓝牙设备驱动; -
libbt_vendor.z.so负责用户态 HCI 传输和厂商适配; -
ztopbt.conf提供模组相关配置; -
init 配置负责系统启动阶段自动加载驱动并设置设备权限;
-
BUILD.gn和bundle.json负责将相关产物纳入 OpenHarmony 编译和镜像打包流程。
从适配经验看,蓝牙模组迁移到 OpenHarmony 平台时,最关键的是理清 内核驱动、Vendor 适配层、HDI Service、系统权限和镜像打包 之间的关系。只要这几层边界清楚,后续定位编译失败、驱动加载失败或蓝牙服务初始化失败都会更有方向。
更多推荐

所有评论(0)