
基于W800的HDF驱动框架适配 原创 精华
作者:润和软件 李璐
HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理和驱动消息机制。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
驱动加载
HDF驱动加载包括按需加载和按序加载。
按需加载: HDF框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载。
按序加载: HDF框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。
驱动服务管理
HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务。
驱动消息机制
HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息。
本文基于W800适配HDF驱动框架,分析轻量系统的HDF驱动框架适配,HDF驱动适配应在内核移植Kconfig适配之后。
驱动启动流程
在系统启动时,HDF驱动框架先启动,通过解析配置文件获取到设备列表,读取".hdf.drivers"段读取到驱动程序(Driver Entry)列表,然后遍历设备列表与驱动程序列表进行匹配,并加载匹配成功的驱动。驱动框架有两大核心管理者:
· DeviceManager 负责设备的管理,包括设备加载、卸载和查询等设备相关功能。
· DeviceServiceManager 负责管理设备发布的接口服务,提供接口服务的发布、查询等功能。
驱动加载主要由 DeviceManager 主导,首先 DeviceManager 要解析配置文件中的 Host 列表,根据 Host 列表中的信息来实例化对应的 Host 对象。Host 解析配置文件获取到关联的设备列表,遍历设备列表去获取与之匹配的驱动程序名称,然后基于.hdf.driver section 获得驱动程序地址。 HDF驱动启动流程如下:
HDF框架启动
在device/soc/winnermicro/wm800/board/app/main.c文件中,DeviceManagerStart()函数为HDF框架入口函数,如下:
获取驱动程序列表
HDF 驱动框架通过将驱动程序入口符号的地址集中存放到一个特殊的 section 来实现对驱动的索引,这个 section 的开头和末尾插入了_hdf_drivers_start、_hdf_drivers_end 两个特殊符号,用于标记这个 section 的范围,两个特殊符号之间的数据即为驱动实现指针。
在文件 device\soc\winnermicro\wm800\board\ld\w800\gcc_csky.ld中,具体实现如下:
获取设备列表
配置文本编译后会变成二进制格式的配置文件,其中设备相关信息被存放在一个用“hdf_manager”标记的 device_info 配置块中,host 的内容以块的形式在 device_info 块中依次排列,host 块中记录了 host 名称、启动优先级和设备列表信息。 设备信息中的 moduleName 字段将用于和驱动程序入口中的 moduleName 进行匹配,从而为设备匹配到正确的驱动程序。
在文件device\soc\winnermicro\wm800\hdf_config\device_info.hcs中,具体实现如下(以GPIO为例):
在文件drivers\adapter\platform\gpio\gpio_wm.c 中,moduleName 字段与设备信息中的 moduleName字段保持一致,如下:
驱动程序加载流程
Device Manager 遍历设备列表,当查找到对应驱动实现时,为设备创建 Device 对象实例,如果设备配置中的 policy 字段为需要对外发布的驱动接口(SERVICE_POLICY_CAPACITY),那么驱动的 Bind 接口将首先被调用,用于关联设备和服务实例。然后驱动的 Init 接口将被调用,用于完成驱动的相关初始化工作。如果驱动被卸载或者因为硬件等原因 Init 接口返回失败,Release 将被调用,用于释放驱动申请的各类配置。
HDF驱动框架适配
HDF驱动框架提供了一套应用访问硬件的统一接口,可以简化应用开发,添加HDF组件需要在//vendor/hihope/neptune_iotlink_demo/kernel_configs添加:
可在kernel/liteos_m中执行make menuconfig,进入 Driver选项选择适配的外设,例如适配UART,可选中 Enable HDF platform uart driver。
驱动适配相关文件放置在drivers/adapter/platform中,对应有gpio,i2c,pwm,spi,uart,watchdog,都是通过HDF机制加载,以GPIO和UART为例进行详细说明。
GPIO适配
1.芯片驱动适配文件位于drivers/adapter/platform目录,在gpio目录增加gpio_wm.c文件,在BUILD.gn文件中,描述了W800驱动的编译适配。如下:
2.gpio_wm.c中GPIO驱动实现如下:
编写一个简单的驱动,首先需要实现驱动程序 (Driver Entry)入口中的三个主要接口:
Bind 接口:实现驱动接口实例化绑定,如果需要发布驱动接口,会在驱动加载过程中被调用,实例化该接口的驱动服务并和 DeviceObject 绑定。 Init 接口:实现驱动的初始化,返回错误将中止驱动加载流程。 Release 接口:实现驱动的卸载,在该接口中释放驱动实例的软硬件资源。
3.在文件device\soc\winnermicro\wm800\hdf_config\device_info.hcs中添加GPIO驱动配置,具体实现如下:
4.在device/board/hihope/shields/neptune100/neptune100.hcs添加gpio硬件描述信息, 添加内容如下:
5.在GpioDriverInit获取hcs参数进行初始化,如下:
UART适配
1.芯片驱动适配文件位于drivers/adapter/platform目录,在uart目录增加uart_wm.c文件,在BUILD.gn文件中,描述了W800驱动的编译适配。如下:
2.uart_wm.c中UART驱动实现如下:
3.在文件device\soc\winnermicro\wm800\hdf_config\device_info.hcs中添加UART驱动配置,具体实现如下:
4.在device/board/hihope/shields/neptune100/neptune100.hcs添加uart硬件描述信息, 添加内容如下:
5.在UartDriverInit获取hcs参数进行初始化,如下:
参考链接
HDF驱动框架:https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md
