1. 课程导入
各位同学,咱们今天正式开讲HDF框架。说实话,我第一次接触HDF时,心里也犯嘀咕——这不就是鸿蒙版的设备驱动框架吗?后来深入项目才发现,事情没那么简单。
HDF的全称是Hardware Driver Foundation,翻译过来就是硬件驱动基础框架。它在鸿蒙系统里的位置,相当于Linux内核中的设备驱动模型。但你要是把它当成Linux驱动模型的简单移植,那就大错特错了。
1.1 HDF在鸿蒙系统中的定位
先看一张图,你就明白HDF到底站在哪了。
从这张图你能看到,HDF夹在系统服务层和内核层之间。它不直接跟硬件打交道,而是通过内核去操作硬件。那它到底干了什么?
- 驱动管理:驱动的加载、卸载、绑定、生命周期管理,全归它管
- 设备发现:硬件插拔、设备枚举、资源匹配,自动完成
- 电源管理:设备休眠唤醒、功耗控制,统一策略
- 配置解析:用HCS配置文件描述硬件信息,不用改代码
- 消息通信:驱动之间、驱动与用户态之间,走统一通道
说白了,HDF就是鸿蒙硬件驱动的大管家。你写驱动时,只需要关心硬件操作本身,其他杂事交给HDF。
1.2 HDF框架核心设计思想
HDF的设计思想,我总结为四个关键词。你在后面写驱动时会反复遇到它们。
| 设计思想 | 核心含义 | 我遇到的坑 |
|---|---|---|
| 分层解耦 | 驱动按功能分层,每层只做自己的事 | 曾经把业务逻辑写在中断里,调试到崩溃 |
| 配置驱动 | 硬件信息写在HCS文件,驱动代码不动 | 改配置比改代码快10倍,真的 |
| 统一接口 | 所有驱动对外暴露标准API | 用户态调驱动像调函数一样简单 |
| 跨内核 | 同一套驱动代码,跑在LiteOS和Linux上 | 这个特性救了我一次项目延期 |
1.2.1 分层解耦
HDF把驱动拆成三层:
- 驱动管理层:负责驱动生命周期、设备匹配、电源策略
- 驱动服务层:提供对外接口,比如open/read/write/ioctl
- 驱动实现层:真正操作寄存器、处理中断的地方
我在项目中遇到过一个问题:某传感器驱动里,有人把业务逻辑直接写在中断处理函数里。结果中断一多,系统直接卡死。后来按HDF的分层思想,把中断只做数据采集,业务逻辑放到工作队列里,问题就解决了。
1.2.2 配置驱动
HDF用HCS(HDF Configuration Source)文件来描述硬件信息。比如传感器挂在哪条I2C总线上、地址是多少、中断引脚是哪个,全写在配置文件里。
// 一个典型的HCS配置片段
root {
sensor_config {
board_config {
i2c_bus = 2; // I2C总线号
i2c_addr = 0x76; // 设备地址
irq_gpio = 18; // 中断引脚
power_ctrl = 1; // 电源控制使能
}
}
}
为什么要这么做?你想想看,如果硬件改了个引脚,传统做法要改驱动代码重新编译。有了HCS,改一下配置文件,重启就生效。我在一个项目里,光靠改配置就适配了3款不同型号的传感器,驱动代码一行没动。
1.2.3 统一接口
HDF给所有驱动定义了标准接口。不管你是I2C传感器、SPI显示屏还是GPIO按键,对外暴露的API风格都一样。
// HDF标准驱动接口
struct HdfDriverEntry g_sensorDriverEntry = {
.moduleVersion = 1,
.moduleName = "HDF_SENSOR",
.Bind = SensorBind, // 绑定服务
.Init = SensorInit, // 初始化
.Release = SensorRelease // 释放资源
};
这种统一性带来的好处是——上层应用调驱动时,根本不用关心底层是什么硬件。我做过一个项目,用户态程序通过HDF接口同时操作了温度传感器、加速度计和陀螺仪,代码风格完全一致。
1.2.4 跨内核
鸿蒙支持LiteOS和Linux双内核。HDF在这两个内核上提供了同一套API。你写的驱动,只要遵循HDF规范,就能无缝切换内核。
1.3 HDF与Linux设备模型的对比
很多同学是从Linux驱动转过来的。咱们直接对比一下,心里就有数了。
| 对比维度 | Linux设备模型 | HDF框架 |
|---|---|---|
| 设计哲学 | 一切皆文件,驱动通过file_operations暴露 | 一切皆服务,驱动通过Service发布 |
| 配置方式 | Device Tree(DTS) | HCS配置文件 |
| 驱动模型 | platform_driver + platform_device | HdfDriverEntry + HdfDeviceObject |
| 用户态访问 | open/read/write/ioctl系统调用 | HDF提供的Service接口,支持IPC |
| 电源管理 | runtime PM + system suspend/resume | HDF统一电源管理框架 |
| 跨内核支持 | 仅Linux | LiteOS + Linux |
| 热插拔 | udev机制 | HDF设备发现机制 |
我来解释几个关键差异:
- 配置方式:Linux用DTS,HDF用HCS。语法上HCS更简洁,而且支持运行时重载。我个人觉得HCS比DTS好读多了。
- 用户态访问:Linux驱动暴露设备节点,用户态通过系统调用访问。HDF驱动暴露Service,用户态通过IPC调用。这意味着HDF驱动天然支持跨进程访问。
- 驱动模型:Linux的platform_driver需要手动匹配设备。HDF的HdfDriverEntry由框架自动匹配,你只需要注册就行。
一句话总结:Linux设备模型是面向文件的,HDF是面向服务的。如果你习惯Linux那套,转过来需要适应一下,但适应之后你会发现HDF在嵌入式场景下更顺手。
1.4 本章小结
咱们这一章把HDF的定位、设计思想和对比都过了一遍。核心记住三点:
- HDF是鸿蒙硬件驱动的统一管理平台,位于系统服务层和内核层之间
- 它的设计思想是分层解耦、配置驱动、统一接口、跨内核
- 跟Linux设备模型比,HDF更强调服务化和配置化,适合嵌入式场景