Sensor 驱动开发
1.1 概述
Sensor 是较为常见的输入设备,用于感知环境状态,从而实现相应的响应。相较于原始的 Linux 驱动模式,KaihongOS 在 HDF(Hardware Driver Foundation)层实现 Sensor 的驱动。这种实现方式能够实现一次开发,支持在不同的内核环境部署,比如轻量级系统、小系统或者标准 Linux 系统。此外,在 HDF 框架中,对于不同的驱动能够实现统一管理,每一个驱动都对外能够提供服务,对应用层来说,只需调用 HDI(Hardware Device Interface)接口即可获取驱动服务的能力。
1.2 Sensor 驱动模型
OpenHarmony 中基于 HDF 驱动框架的 Sensor 驱动模型如下图:

图 1-1 Sensor 驱动模型
Sensor 驱动模型屏蔽硬件器件差异,为上层 Sensor 服务系统提供稳定的 Sensor 基础能力接口,包括 Sensor 列表查询、Sensor 启停、Sensor 订阅及取消订阅、Sensor 参数配置等功能。Sensor 设备驱动的开发是在 HDF 驱动框架基础上,结合操作系统抽象层(OSAL,Operating System Abstraction Layer)和平台驱动接口(比如 I2C/SPI/UART 总线等平台资源)能力,屏蔽不同操作系统和平台总线资源差异,实现 Sensor 驱动“一次开发,多系统部署”的目标。
如图 1-1 所示,OpenHarmony 中 Sensor 驱动模型的分为以下层级:
- Hardware:此层决定了 Sensor 设备与 CPU 是如何连接的,外设使用何种方式(比如 I2C、SPI、GPIO 等)进行通讯等等。
- Driver:该层实现硬件外设驱动,包括 HdfDriverEntry 中的 bind Init、realese 函数,以及数据 OpsCall 里面的 ReadData。
- HDI:接口定义与实现。接口主要包括所有 Sensor 信息查询、Sensor 启停、Sensor 订阅/取消订阅、Sensor 参数配置等稳定的接口,简化服务开发。
- Framework:上层 Sensor 服务。
1.3 HCS 配置
对于不同的平台,需要在对应的平台目录修改对应的 hcs 文件,下面示例为 khdvk_rk3568_a 平台下新增 sensor 模块的修改方法。
1.3.1 配置 device_info.hcs
文件路径
vendor/kaihong/khdvk_rk3568_a/hdf_config/khdf/device_info/device_info.hcs
配置说明
在 device_info.hcs 中添加以下信息:

图 1-2 配置 device_info.hcs
主要字段说明如下:
- policy:服务策略。取值“0”表示不发布服务,取值“1”表示向内核态发布服务,取值“2”表示向内核用户态发布服务。
- moduleName:与驱动实现的 HdfDriverEntry 结构体中的 moduleName 相同。
- deviceMatchAttr:驱动的私有配置信息。
- serviceName:服务名称,最终会在/dev/节点下生成 serviceName 的节点(生成节点的前提条件是 policy 配置为大于等于 1)。
1.3.2 配置 sensor_config.hcs
文件路径
vendor/kaihong/khdvk_rk3568_a/hdf_config/khdf/sensor/sensor_config.hcs
配置说明
在 sensor_config.hcs 中添加如下内容:
#include "accel/bmi160_config.hcs"
1.3.3 配置 bmi160_config.hcs
文件路径
vendor/kaihong/khdvk_rk3568_a/hdf_config/khdf/sensor/accel/bmi160_config.hcs
配置说明
新增文件夹 accel,并新建文件 bmi160_config.hcs,文件内容如下:
root {
accel_bmi160_chip_config : sensorConfig {
match_attr = "hdf_sensor_accel_driver";
sensorInfo :: sensorDeviceInfo {
sensorName = "accelerometer";
vendorName = "borsh_bmi160"; // max string length is 16 bytes
sensorTypeId = 1; // enum SensorTypeTag
sensorId = 1; // user define sensor id
power = 230;
}
sensorBusConfig :: sensorBusInfo {
busType = 0; // 0:i2c 1:spi
busNum = 6;
busAddr = 0x68;
regWidth = 1; // 1byte
}
sensorIdAttr :: sensorIdInfo {
chipName = "bmi160";
chipIdRegister = 0x00;
chipIdValue = 0xd1;
}
sensorRegConfig {
/* regAddr: register address
value: config register value
len: size of value
mask: mask of value
delay: config register delay time (ms)
opsType: enum SensorOpsType 0-none 1-read 2-write 3-read_check 4-update_bit
calType: enum SensorBitCalType 0-none 1-set 2-revert 3-xor 4-left shift 5-right shift
shiftNum: shift bits
debug: 0-no debug 1-debug
save: 0-no save 1-save
*/
/* regAddr, value, mask, len, delay, opsType, calType, shiftNum, debug, save */
initSeqConfig = [
0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0,
0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
];
enableSeqConfig = [
0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0,
0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0,
0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0
];
disableSeqConfig = [
0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
];
}
}
}
注意根据实际情况修改以上加粗内容的配置。
1.4 编译选项修改
- 在 drivers/hdf_core/adapter/khdf/linux/model/sensor/Kconfig 中添加以下内容:
config DRIVERS_HDF_SENSOR_ACCEL_BMI160
bool "Enable HDF accel bmi160 sensor driver"
default n
depends on DRIVERS_HDF_SENSOR_ACCEL
help
Answer Y to enable HDF accel bmi160 sensor driver.
- 在 drivers/hdf_core/adapter/khdf/linux/model/sensor/Makefile 中添加以下内容:
obj-$(CONFIG_DRIVERS_HDF_SENSOR_ACCEL_BMI160) += $(SENSOR_ROOT_CHIPSET)/chipset/accel/accel_bmi160.o
添加后如下图所示:

图 1-3 修改 Makefile
对应的驱动实现文件如下:
drivers/peripheral/sensor/chipset/accel/accel_bmi160.c
drivers/peripheral/sensor/chipset/accel/accel_bmi160.h
- 内核 defconfig 配置
在
device/board/kaihong/khdvk_rk3568_a/kernel/config/khdvk_rk3568_a/khdvk_rk3568_a_defconfig
文件中添加以下内容:
CONFIG_DRIVERS_HDF_SENSOR=y
CONFIG_DRIVERS_HDF_SENSOR_ACCEL=y
CONFIG_DRIVERS_HDF_SENSOR_ACCEL_BMI160=y
1.5 应用代码目录说明
Sensor 驱动对外服务的接口实现均在 drivers/peripheral/sensor 路径下,该目录对应的功能说明如下:
/drivers/peripheral/sensor
├── hal
│ └── include
│ └── src
├── interfaces
│ └── include
├── hdi_service
├── test
│ └── unittest
1.6 常见问题处理
- 确认 HCS 配置的准确性,包括 I2C 总线、Sensor 寄存器初始化、Sensor 使能等信息。
- 确认是否修改了编译选项,使其正常编译进去。
- 若应用使能不上,确认模块是否要配置权限,以及是否要 touch hdf.hcs 更改时间戳。
如果 khdf 存在缓存被刷的情况,查看打印建议使用 printk 函数。