当前位置: 首页 > wzjs >正文

天津网站建设推广服务实时排名软件

天津网站建设推广服务,实时排名软件,广州营销型网站建设公司,dedecms金融网站模板在分析openharmony的hdf框架的设备驱动加载器(IDriverLoader)时发现在创建实例时会首先判断一下是否完成了驱动入口的构建(HdfDriverEntryConstruct),如果没有构建会重新构建,这与我开始以为的不一致(我一直以为是采用的linux内核方式,只是由…

在分析openharmony的hdf框架的设备驱动加载器(IDriverLoader)时发现在创建实例时会首先判断一下是否完成了驱动入口的构建(HdfDriverEntryConstruct),如果没有构建会重新构建,这与我开始以为的不一致(我一直以为是采用的linux内核方式,只是由hdf来将驱动注册进去),oh将这部分由hdf框架接管了。下面我便将这部分实现驱动程序的动态加载和管理的技术细节进行分析。

实现驱动程序的动态加载和管理主要过程如下:

  • 驱动注册通过 HDF_DRIVER_INIT 宏将驱动入口点注册.hdf.driver 段。
  • 驱动加载:由设备管理器解析配置文件并调用驱动的 BindInit 函数
  • 服务发布与订阅:通过 HdfDeviceNodePublishServiceHdfDeviceSubscribeService 实现。
  • 驱动卸载:通过 Release 函数释放驱动资源

在使用前首先看下驱动是如何应用的(有个大概的使用思路)

struct HdfDriverEntry g_i2cManagerEntry = {//驱动程序的入口信息.moduleVersion = 1,//驱动模块的版本号.Bind = I2cManagerBind,//用于将驱动与设备对象关联.Init = I2cManagerInit,//用于完成驱动的初始化操作.Release = I2cManagerRelease,//用于释放驱动占用的资源.moduleName = "HDF_PLATFORM_I2C_MANAGER", //必须与 device_info.hcs 文件中的设备名称一致
};
HDF_INIT(g_i2cManagerEntry);//用于将驱动程序的入口结构注册到 HDF 框架中

下面分别介绍动态加载和管理的四个主要过程。

驱动注册

在 OpenHarmony 中,驱动程序通过 HDF_INIT宏注册到 .hdf.driver 段中。这个宏将驱动程序的入口点信息存储到特定的内存段,供运行时加载

在hdf_core\interfaces\inner_api\host\shared\hdf_device_desc.h文件中我们可以看到实际HDF_INIT宏实际调用的为HDF_DRIVER_INIT。

#define HDF_INIT(module)  HDF_DRIVER_INIT(module)
  • HDF_DRIVER_INIT说明

结合hdf_core\framework\core\common\include\host\hdf_device_section.h代码的宏定义

//这用于确保驱动程序的入口点不会被编译器优化掉
#define USED_ATTR __attribute__((used))//用于将变量或函数放置到指定的内存段(section)中
//将驱动程序的入口点信息存储到 .hdf.driver 段中
//这个段在运行时会被 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))

定义一个全局变量(module##HdfEntry),其名称由驱动模块名(module)拼接而成。使用 USED_ATTR 确保该变量不会被优化掉。使用 HDF_SECTION 将该变量放置到 .hdf.driver 段中。将该变量的值设置为驱动模块的地址(&(module))。这样,驱动程序的入口点信息就会被存储到 .hdf.driver 段中,供运行时扫描和加载。

此时便有个疑问,我们只知道驱动程序的入口点信息就会被存储到 .hdf.driver 段中,那我们如何访问或使用它呢?

答案就在hdf_core\framework\core\common\include\host\hdf_device_section.h文件中的以下两个函数中

/*** 这个宏定义用于获取指定变量的地址。* 声明一个外部变量(extern type name)。* 返回该变量的地址(&(name))。* 这个宏主要用于定义 _hdf_drivers_start 和 _hdf_drivers_end,标记驱动程序入口点的范围。*/
#define HDF_DRIVER_SEC_NAME(type, name) \({extern type name;            \&(name);                       \})/**通过 HDF_DRIVER_SEC_NAME 宏,获取 _hdf_drivers_start 和 _hdf_drivers_end 的地址。
这些地址在运行时被 HDF 框架用来遍历 .hdf.driver 段中的驱动程序入口点。
HDF 框架可以通过 _hdf_drivers_start 和 _hdf_drivers_end 之间的范围,动态加载所有注册的驱动程序。
*/
#define HDF_DRIVER_BEGIN() HDF_DRIVER_SEC_NAME(size_t, _hdf_drivers_start)
#define HDF_DRIVER_END() HDF_DRIVER_SEC_NAME(size_t, _hdf_drivers_end)

经过对上述代码的理解我们知道如何来使用了,但是此时还有一个疑问没有解决,**那就是_hdf_drivers_start和_hdf_drivers_end变量在哪定义的呢?它在哪被赋值了呢?**通过对代码的搜索可以看到在链接器脚本(vmlinux.lds.S)中有相关定义。如下图所示:

在这里插入图片描述

这段代码的作用是:

  1. 定义一个名为 .init.hdf_table 的段
  2. 该段的起始位置设置 _hdf_drivers_start 符号
  3. 所有标记为 .hdf.driver 的数据(即驱动程序入口点)放入该段。
  4. 在该段的结束位置设置 _hdf_drivers_end 符号

这部分的内容有点绕为了更好的总结在这儿弄了个使用demo,可以供参考理解:

// 定义一个驱动程序模块
struct HdfDriverEntry MyDriver;// 注册驱动程序模块
HDF_DRIVER_INIT(MyDriver);// 在代码中使用 HDF_DRIVER_BEGIN 和 HDF_DRIVER_END 获取驱动程序范围
size_t *start = HDF_DRIVER_BEGIN();
size_t *end = HDF_DRIVER_END();// 遍历驱动程序入口点
for (size_t *ptr = start; ptr < end; ptr++) {struct HdfDriverEntry *driver = (struct HdfDriverEntry *)(*ptr);// 加载驱动程序
}

驱动加载

驱动加载过程由 HDF 框架的设备管理器(Device Manager)和设备主机(Device Host)协同完成,这部分详细的过程比较复杂(本周应该能写完这篇汇总的),此处只列出核心点

  • 设备管理器初始化

    static int __init DeviceManagerInit(void)
    {int ret = DeviceManagerStart();if (ret < 0) {HDF_LOGE("%s start failed %d", __func__, ret);} else {HDF_LOGD("%s start success", __func__);}return ret;
    }
    late_initcall(DeviceManagerInit);
    

    设备管理器在系统启动时通过 late_initcall 初始化,并开始加载驱动。

  • 驱动加载流程

    1. 设备管理器解析配置文件(device_info.hcs),获取设备和驱动的映射关系
    2. 根据配置文件中的 preload 字段,决定驱动是按需加载还是按序加载
    3. 遍历 .hdf.driver 段,获取驱动程序的入口地址
    4. 调用驱动的 BindInit 函数完成初始化

代码调用过程如下:
在这里插入图片描述

int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode)
{const struct HdfDriverEntry *driverEntry = devNode->driver->entry;int ret = DeviceDriverBind(devNode);if (ret != HDF_SUCCESS) {return ret;}ret = driverEntry->Init(&devNode->deviceObject);if (ret != HDF_SUCCESS) {return HDF_DEV_ERR_DEV_INIT_FAIL;}ret = HdfDeviceNodePublishService(devNode);if (ret != HDF_SUCCESS) {return HDF_DEV_ERR_PUBLISH_FAIL;}return ret;
}

服务发布与订阅

HDF 框架支持服务发布和订阅机制,允许驱动程序在初始化后发布服务接口,供其他模块使用

  • 服务发布

    int HdfDeviceNodePublishService(struct HdfDeviceNode *devNode);
    
  • 服务订阅

其他模块可以通过 HdfDeviceSubscribeService 订阅驱动服务。当驱动加载完成后,框架会将服务接口发布给订阅者

int HdfDeviceSubscribeService(struct HdfDeviceObject *deviceObject, const char *serviceName, struct SubscriberCallback callback);

对此部分内容需要详细了解的可以参考

驱动卸载

和驱动加载相对应的卸载驱动的函数为HdfDeviceUnlaunchNode,当驱动被卸载或初始化失败时,HDF 框架会调用驱动的 Release 函数释放资源:

static void HdfDeviceUnlaunchNode(struct HdfDeviceNode *devNode)
{....if (devNode->driver != NULL) {driverEntry = devNode->driver->entry;//从设备节点中获取驱动程序对象(devNode->driver)}if (driverEntry != NULL && driverEntry->Release != NULL) {driverEntry->Release(&devNode->deviceObject);//如果驱动程序的入口结构和 Release 函数指针都有效,调用 Release 函数释放驱动占用的资源,即驱动中传入的release函数}....
}
http://www.dtcms.com/wzjs/392253.html

相关文章:

  • 手机网站Com学电商运营的培训机构
  • 自己做的网站本地虚拟上传seo研究
  • wordpress编辑用户中心上海seo关键词优化
  • 合肥网站建设公司哪家好seo搜狗
  • WORDPRESS菜单位置添加搜索框seo实战密码第三版pdf
  • 王野苏婉卿seo专员是什么职位
  • 网站和app软件制作公司品牌宣传策略
  • 摄像头怎么做直播网站百度上海总部
  • 搞笑网站全站源码网络服务商怎么咨询
  • 临海城市建设网站百度竞价排名什么意思
  • 做网站下载哪个软件云南网站建设公司哪家好
  • 医院建设网站要求分析 amp河南百度推广公司
  • wp网站如何做多级联动筛选框营销型网站的公司
  • 网页设计教学设计滨州网站seo
  • 汕头cms模板建站免费网站生成器
  • 建设网站的法律可行性百度热门搜索排行榜
  • 企业年金百度上如何做优化网站
  • 企业自助建站系统怎么操作品牌推广的渠道有哪些
  • 网站建设图文搜索引擎优化的主要工作
  • 上海响应式网站开发网站关键词排名分析
  • 大数据营销心得体会搜索引擎排名优化方法
  • 百货商城网站建设百度官网网页版
  • 公司推广做哪个网站广州网站建设系统
  • 做幼儿手工网站seo快速优化排名
  • 成都网站建设公司官网免费seo推广公司
  • 南宁有本地租房做网站吗指数基金怎么选
  • 自己如何建立一个网站接单平台app
  • 帮人做网站如何免费自己创建网站
  • 网站建设威客平台免费网页设计制作网站
  • 用服务器做网站新媒体营销案例ppt