一、案例简介
该程序是基于OpenHarmony标准系统编写的基础外设类:简易HDF驱动。
目前已在凌蒙派-RK3568开发板跑通。
详细资料请参考官网:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony。
二、基础知识
1、OpenHarmony HDF开发简介
HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
2、OpenHarmony HDF驱动开发
HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个Host(设备容器)里面,用于管理一组设备的启动加载等过程。在划分Host时,驱动程序是部署在一个Host还是部署在不同的Host,主要考虑驱动程序之间是否存在耦合性,如果两个驱动程序之间存在依赖,可以考虑将这部分驱动程序部署在一个Host里面,否则部署到独立的Host中是更好的选择。Device对应一个真实的物理设备。DeviceNode是设备的一个部件,Device至少有一个DeviceNode。每个DeviceNode可以发布一个设备服务。驱动即驱动程序,每个DevicdNode唯一对应一个驱动,实现和硬件的功能交互。
3、OpenHarmony HDF驱动加载
HDF驱动框架提供把和配置的设备列表匹配成功的驱动程序加载起来的功能。
支持按需加载和按序加载两种策略,具体设备的加载策略由配置文件中的preload字段来控制,配置值参考如下:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
(1)按需加载
- preload字段配置为0(DEVICE_PRELOAD_ENABLE),则系统启动过程中默认加载。
- preload字段配置为1(DEVICE_PRELOAD_ENABLE_STEP2),当系统支持快速启动的时候,则在系统完成之后再加载这一类驱动,否则和DEVICE_PRELOAD_ENABLE含义相同。
- preload字段配置为2(DEVICE_PRELOAD_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务时,如果驱动服务不存在,HDF框架会尝试动态加载该驱动。
(2)按序加载(默认加载策略)
配置文件中的priority(取值范围为整数0到200)是用来表示host(驱动容器)和驱动的优先级。不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。
4、OpenHarmony HDF驱动服务管理
驱动服务是HDF驱动设备对外提供能力的对象,由HDF框架统一管理。驱动服务管理主要包含驱动服务的发布和获取。
(1)驱动服务的发布策略
HDF框架定义了驱动对外发布服务的策略,由配置文件中的policy字段来控制,policy字段的取值范围以及含义如下:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
(2)驱动服务的接口说明
针对驱动服务管理功能,HDF框架开放了以下接口供开发者调用,如下表所示:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
5、驱动消息机制管理
当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。
消息机制的功能主要有以下两种:
- 用户态应用发送消息到驱动。
- 用户态应用接收驱动主动上报事件。
消息机制接口如下所示:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
6、配置树配置
HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。
HC-GEN(HDF Configuration Generator)是HCS配置转换工具,可以将HDF配置文件转换为软件可读取的文件格式:
- 在弱性能环境中,转换为配置树源码或配置树宏定义,驱动可直接调用C代码或宏式APIs获取配置。
- 在高性能环境中,转换为HCB(HDF Configuration Binary)二进制文件,驱动可使用HDF框架提供的配置解析接口获取配置。
HCS经过HC-GEN编译生成HCB文件,HDF驱动框架中的HCS Parser模块会从HCB文件中重建配置树,HDF驱动模块使用HCS Parser提供的配置读取接口获取配置内容。
三、代码解析
1、配置文件
(1)device_info.hcs
创建config/device_info.hcs,用于驱动设备描述,具体内容如下:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
注意:
- device_rk3568_sample:为配置树的类设备结点。
- deviceMatchAttr:关键字必须与config.hcs的match_attr匹配。
(2)config.hcs
创建config/config.hcs,用于定义私有变量,具体内容如下:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
由于我们没有用到其他私有变量,故不做定义。
(3)参与配置树编译
编辑//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,将device_info.hcs添加配置树中。具体内容如下所示:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
2、HDF驱动
(1)driver_hdf_sample.c
头文件
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
定义打印标签
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
建议读者用HDF_LOGI、HDF_LOGE等打印信息。
驱动初始化
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
驱动释放
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
驱动绑定
将驱动对外提供的服务能力接口绑定到HDF框架,通过struct IDeviceIoService设置Dispatch函数。
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
HdfSampleDriverDispatch()挂载载struct IDeviceIoService的函数指针成员Dispatch,它相当于Linux的ioctl,可与应用程序进行数据交互。
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
驱动注册
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
(2)Makefile
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
(3)参与Linux内核编译
编辑//drivers/hdf_core/adapter/khdf/linux/Makefile,添加一段代码,将sample驱动参与Linux内核编译中。具体如下所示:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
3、应用程序
(1)sample_test.c
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
(2)BUILD.gn
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
(3)参与应用程序编译
编辑//vendor/lockzhiner/rk3568/samples/BUILD.gn,开启sample编译。具体如下:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
四、编译说明
建议使用docker编译方法,运行如下:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区
五、运行结果
该程序运行结果如下所示:
凌蒙派-RK3568开发板-基础外设类:简易HDF驱动-开源基础软件社区