2.2.2驱动私有配置信息(可选)

如果驱动有私有配置,则可以添加一个驱动的配置文件,用来填写一些驱动的默认配置信息,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init传递给驱动,驱动的配置信息示例如下:

root {  
	SampleDriverConfig {
		sample_version = 1; 
		sample_bus = "I2C_0"; 
		match_attr = "sample_config";   //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致
	}
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

3.HDF 驱动加载

HDF驱动加载包括按需加载和按序加载。按需加载是HDF框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载;按序加载是HDF框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。HDF框架定义的驱动按需加载方式的策略是由配置文件中的 preload 字段来控制,preload 字段的取值范围以及含义如下:

驱动的按序加载是通过配置文件中的 priority(取值范围为整数 0 到 200)来决定的,priority 值越小,表示的优先级越高。驱动的加载顺序,优先根据 host 的 priority 决定,如果host 的 priority 相同,再根据 host 内的驱动 priority 值来决定加载顺序。

3.1 HDF_INIT宏展开

驱动入口注册到HDF框架,会调用HDF_INIT函数将驱动入口地址注册到HDF框架。
#define HDF_SECTION__attribute__((section(“.hdf.driver”)))
#define HDF_DRIVER_INIT(module)
const size_t USED_ATTR module##HdfEntry HDF_SECTION = (size_t)(&(module))

可以看到 HDF_INIT 宏是定义了一个“驱动模块名+HdfEntry”的符号放到".hdf.driver"所在 section,该符号指向的内存地址即为驱动程序入口结构体的地址。这个特殊的 section 将用于开机启动时查找设备驱动。

3.2获取驱动列表

HDF驱动框架通过将驱动程序入口符号的地址集中存放到一个特殊的 section 来实现对驱动的索引,这个section的开头和末尾插入了_hdf_drivers_start、_hdf_drivers_end两个特殊符号,用于标记这个 section 的范围,两个特殊符号之间的数据即为驱动实现指针。

3.3获取设备列表

配置文本编译后会变成二进制格式的配置文件,其中设备相关信息被存放在一个用“hdf_manager”标记的 device_info 配置块中,host的内容以块的形式在device_info 块中依次排列,host块中记录了host名称、启动优先级和设备列表信息。设备信息中的 moduleName字段将用于和驱动程序入口中的moduleName进行匹配,从而为设备匹配到正确的驱动程序,完成设备与驱动的匹配,具体流程图如下:

3.4驱动框架启动

late_initcall宏展开

__define_initcall宏展开

___define_initcall宏展开

宏含义:
1)声明一个类型为initcall_t,名称为__initcall_DeviceManagerInit的函数指针
2)将这个函数指针初始化为DeviceManagerInit
3)编译的时候需要把这个函数指针变量放置到名称为“.initcall7.init”的section中,其实质就是将这个函数DeviceManagerInit的首地址放置到了这个.initcall7.init的section中

内核初始化的内存图:

其中__init用来标示的是初始化函数,在初始化后不会再调用,__initdata是初始化数据,__initparam是初始化参数,其他7个初始化宏就是初始化函数会用到的,初始化的时候按
照.initcall1.init->.initcall7.init的顺序初始化。do_basic_setup执行.initcall1.init->.initcall7.init的顺序初始化。

4总结

1)在系统启动时,DeviceManagerInit通过late_initcall先启动。
2) Device Manager 根据 Device Information 信息,解析配置文件中的 Host 列表,根据 Host 列表中的信息来实例化对应的 Host 对象。
3)Host遍历设备列表去获取与之匹配的驱动程序名称,然后基于驱动程序名称遍历.hdf.driver section 获得驱动程序地址。
4)设备与驱动匹配成功之后,获取指定驱动的入口地址,加载对应的设备驱动程序。
5)调用指定驱动的 Bind 接口,用于关联设备和服务实例。
6)调用指定驱动的 Init 接口,用于完成驱动的相关初始化工作。
7)如果驱动被卸载或者因为硬件等原因 Init 接口返回失败,Release 将被调用,用于释放驱动申请的各类资源。

如果大家想更加深入的学习 OpenHarmony(鸿蒙南向) 开发的全栈内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

系统架构分析:https://qr18.cn/CgxrRy

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

写在最后

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/maniuT/article/details/139864698","extend1":"pc","ab":"new"}">> id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"> class="blog_extension blog_extension_type2" id="blog_extension"> class="extension_official" data-report-click="{"spm":"1001.2101.3001.6471"}" data-report-view="{"spm":"1001.2101.3001.6471"}"> class="blog_extension_card_left"> class="blog_extension_card_cont"> 鸿蒙开发学习资料领取!!! class="blog_extension_card_cont_r"> 微信名片
注:本文转载自blog.csdn.net的沧海一笑-dj的文章"https://blog.csdn.net/dengjin20104042056/article/details/99880335"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!