OpenHarmony之HDF驱动开发流程指导

开发指导

场景介绍

关于驱动的开发我们主要目的是实现驱动代码的编写,但是驱动开发过程中需要服务管理、消息机制管理,才能使驱动在代码编译过程中进行加载。以下开发步骤中介绍了驱动开发、驱动消息机制管理开发、驱动服务管理开发的步骤。

驱动开发实例

基于HDF框架的驱动开发主要分为三个部分:驱动实现、驱动编译脚本编写和驱动配置。详细开发流程如下所示:

驱动实现

驱动实现包含驱动业务代码实现和驱动入口注册,具体写法如下:

  • 驱动业务代码
#include "hdf_device_desc.h"          // HDF框架对驱动开发相关能力接口的头文件
#include "hdf_log.h"                  // HDF框架提供的日志接口头文件#define HDF_LOG_TAG sample_driver     // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签。// 将驱动对外提供的服务能力接口绑定到HDF框架。
int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
{HDF_LOGD("Sample driver bind success");return HDF_SUCCESS;
}// 驱动自身业务初始化的接口
int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{HDF_LOGD("Sample driver Init success");return HDF_SUCCESS;
}// 驱动资源释放的接口
void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
{HDF_LOGD("Sample driver release success");return;
}

驱动入口注册到HDF框架

// 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量。
struct HdfDriverEntry g_sampleDriverEntry = {.moduleVersion = 1,.moduleName = "sample_driver",.Bind = HdfSampleDriverBind,.Init = HdfSampleDriverInit,.Release = HdfSampleDriverRelease,
};// 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动;当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
HDF_INIT(g_sampleDriverEntry);

驱动编译脚本编写

  • LiteOS
  • 涉及Makefile和BUILD.gn修改:
    • Makefile部分:
    • 驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译。
      include $(LITEOSTOPDIR)/../../drivers/hdf_core/adapter/khdf/liteos/lite.mk # 【必需】导入hdf预定义内容
      MODULE_NAME :=        #生成的结果文件
      LOCAL_INCLUDE :=      #本驱动的头文件目录
      LOCAL_SRCS :=         #本驱动的源代码文件
      LOCAL_CFLAGS :=      #自定义的编译选项
      include $(HDF_DRIVER) #导入Makefile模板完成编译

      编译结果文件链接到内核镜像,添加到drivers/hdf_core/adapter/khdf/liteos目录下的hdf_lite.mk里面,示例如下:

      LITEOS_BASELIB +=  -lxxx  #链接生成的静态库
      LIB_SUBDIRS    +=         #驱动代码Makefile的目录

      BUILD.gn部分:

      添加模块BUILD.gn,可参考如下示例:

      import("//build/lite/config/component/lite_component.gni")
      import("//drivers/hdf_core/adapter/khdf/liteos/hdf.gni")
      module_switch = defined(LOSCFG_DRIVERS_HDF_xxx)
      module_name = "xxx"
      hdf_driver(module_name) {sources = ["xxx/xxx/xxx.c",           #模块要编译的源码文件]public_configs = [ ":public" ] #使用依赖的头文件配置
      }
      config("public") {                 #定义依赖的头文件配置include_dirs = ["xxx/xxx/xxx",             #依赖的头文件目录]
      }

      把新增模块的BUILD.gn所在的目录添加到**/drivers/hdf_core/adapter/khdf/liteos/BUILD.gn**里面:

      group("liteos") {public_deps = [ ":$module_name" ]deps = ["xxx/xxx",#新增模块BUILD.gn所在的目录,/drivers/hdf_core/adapter/khdf/liteos]
      }

      Linux

      如果需要定义模块控制宏,需要在模块目录xxx里面添加Kconfig文件,并把Kconfig文件路径添加到drivers/hdf_core/adapter/khdf/linux/Kconfig里面:

      source "drivers/hdf/khdf/xxx/Kconfig" #目录为hdf模块软链接到kernel里面的目录

      添加模块目录到drivers/hdf_core/adapter/khdf/linux/Makefile

      obj-$(CONFIG_DRIVERS_HDF)  += xxx/

      在模块目录xxx里面添加Makefile文件,在Makefile文件里面添加模块代码编译规则:

      obj-y  += xxx.o

      驱动配置

      HDF使用HCS作为配置描述源码,HCS详细介绍配置管理。

      驱动配置包含两部分,HDF框架定义的驱动设备描述和驱动的私有配置信息,具体写法如下:

    • 驱动设备描述(必选)
    • HDF框架加载驱动所需要的信息来源于HDF框架定义的驱动设备描述,因此基于HDF框架开发的驱动必须要在HDF框架定义的device_info.hcs配置文件中添加对应的设备描述。驱动的设备描述填写如下所示:
      root {device_info {match_attr = "hdf_manager";template host {       // host模板,继承该模板的节点(如下sample_host)如果使用模板中的默认值,则节点字段可以缺省。hostName = "";priority = 100;uid = "";         // 用户态进程uid,缺省为空,会被配置为hostName的定义值,即普通用户。gid = "";         // 用户态进程gid,缺省为空,会被配置为hostName的定义值,即普通用户组。caps = [""];      // 用户态进程Linux capabilities配置,缺省为空,需要业务模块按照业务需要进行配置。template device {template deviceNode {policy = 0;priority = 100;preload = 0;permission = 0664;moduleName = "";serviceName = "";deviceMatchAttr = "";}}}sample_host :: host{hostName = "host0";    // host名称,host节点是用来存放某一类驱动的容器。priority = 100;        // host启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证host的加载顺序。caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH"];   // 用户态进程Linux capabilities配置。device_sample :: device {        // sample设备节点device0 :: deviceNode {      // sample驱动的DeviceNode节点policy = 1;              // policy字段是驱动服务发布的策略,在驱动服务管理章节有详细介绍。priority = 100;          // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序。preload = 0;             // 驱动按需加载字段。permission = 0664;       // 驱动创建设备节点权限moduleName = "sample_driver";      // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致。serviceName = "sample_service";    // 驱动对外发布服务的名称,必须唯一。deviceMatchAttr = "sample_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等。}}}}
      }

      说明:

    • uid、gid、caps等配置项是用户态驱动的启动配置,内核态不用配置。
    • 根据进程权限最小化设计原则,业务模块uid、gid不用配置,如上面的sample_host,使用普通用户权限,即uid和gid被定义为hostName的定义值。
    • 如果普通用户权限不能满足业务要求,需要把uid、gid定义为system或者root权限时,请找安全专家进行评审。
    • 驱动私有配置信息(可选)

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

    • 进程的uid在文件base/startup/init/services/etc/passwd中配置,进程的gid在文件base/startup/init/services/etc/group中配置,进程uid和gid配置参考:系统服务用户组添加方法。
    • caps值:格式为caps = ["xxx"],如果要配置CAP_DAC_OVERRIDE,此处需要填写caps = ["DAC_OVERRIDE"],不能填写为caps = ["CAP_DAC_OVERRIDE"]。
    • preload:驱动按需加载字段。
      root {SampleDriverConfig {sample_version = 1;sample_bus = "I2C_0";match_attr = "sample_config";   // 该字段的值必须和device_info.hcs中的deviceMatchAttr值一致}
      }

      配置信息定义之后,需要将该配置文件添加到板级配置入口文件hdf.hcs,示例如下:

      #include "device_info/device_info.hcs"
      #include "sample/sample_config.hcs"

      想学习更多华为鸿蒙HarmonyOS开发知识,在这里我为大家准备了华为鸿蒙HarmonyOS开发者资料大全,大家可以自行点击链接领取:《做鸿蒙应用开发到底学习些啥?》

      其次就是考虑到市场上还没有系统性的学习资料,同时我也整理了一份《鸿蒙 (Harmony OS)开发学习手册》特意整理成PDF文档方式,分享给大家参考学习,大家可以根据自身情况进行获取:《鸿蒙开发学习指南》

      《鸿蒙 (Harmony OS)开发学习手册》

      一、入门必看

      1. 应用开发导读(ArkTS)

      2. 应用开发导读(Java)

      3.......

      二、HarmonyOS 概念

      1. 系统定义

      2. 技术架构

      3. 技术特性

      4. 系统安全

      5......

      三、如何快速入门?《鸿蒙基础入门开发宝典!》

      1. 基本概念

      2. 构建第一个ArkTS应用

      3. 构建第一个JS应用

      4. ……

      四、开发基础知识

      1. 应用基础知识

      2. 配置文件

      3. 应用数据管理

      4. 应用安全管理

      5. 应用隐私保护

      6. 三方应用调用管控机制

      7. 资源分类与访问

      8. 学习ArkTS语言

      9. ……

      五、基于ArkTS 开发

      1. Ability开发

      2. UI开发

      3. 公共事件与通知

      4. 窗口管理

      5. 媒体

      6. 安全

      7. 网络与链接

      8. 电话服务

      9. 数据管理

      10. 后台任务(Background Task)管理

      11. 设备管理

      12. 设备使用信息统计

      13. DFX

      14. 国际化开发

      15. 折叠屏系列

      16. ……

      更多了解更多鸿蒙开发的相关知识可以参考:《做鸿蒙应用开发到底学习些啥?》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring boot mybatis-plus dynamic-datasource 配置文件 相关依赖环境配置

spring boot mybatis-plus dynamic-datasource 配置文件 相关依赖环境配置 ##yaml配置 server:port: 8866servlet:context-path: /yymtomcat:max-threads: 300connection-timeout: 57000max-connections: 500connection-timeout: 57000 spring:datasource:dynamic:primary: m…

【IPC通信--共享内存mmap】

共享内存是一种高效的进程间通信方式,可以在多个进程之间共享数据,提高程序的效率。mmap是一种常用的实现共享内存的机制,它可以将一个文件或者设备映射到内存中,使得多个进程可以通过访问这块内存来实现数据共享。 一、共享内存…

SpringBoot 源码解析4:refresh 方法解析

SpringBoot 源码解析4:refresh 方法解析 1. refresh 方法解析2. 准备刷新 AbstractApplicationContext#prepareRefresh3. 获取bean工厂 AbstractApplicationContext#obtainFreshBeanFactory4. 准备bean工厂 AbstractApplicationContext#prepareBeanFactory5. Servle…

Java学习,一文掌握Java之SpringBoot框架学习文集(6)

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

5.【CPP】内存管理(text段data段bss段||nwedelete底层实现||源码)

一.内存管理 1.如图 2.heap下面的空间 应用程序加载到内存中由操作系统完成对bss,data,text,stack加载,并在内存分配空间。在编译阶段已经确定分配了多少空间,属于静态分配。 而malloc等在程序运行时在堆上开辟空间则属于动态分配,需要手动f…

k8s---配置资源管理

内容预知 目录 内容预知 secret资源配置 secert的几种模式 pod如何来引用secret 陈述式创建secret 声明式base64编码配置secret 将secret用vlumes的方式挂载到pod中 传参的方式将环境变量导入pod 如何通过secret加密方式获取仓库密码 configmap的资源配置 陈述式创建…

ubuntu 22 搭建git服务

第一步,安装git: sudo apt-get install git 创建用户信息 git config --global user.name soft 第二步,创建一个git用户,用来运行git服务: sudo adduser git 创建git仓库的存储目录、更改文件目录属主为代码仓库…

2.3数据链路层02

2.3 数据链路层 2.3.5 以太网 1、以太网概念 以太网是一种计算机局域网技术。IEEE(电气与电子工程师协会:Institute of Electrical and Electronics Engineers)组织的IEEE802.3标准制定了以太网的技术标准,它规定了包括物理层的…

Gartner发布CPS安全2024年预测:安全形势动荡的四大向量

随着威胁形势、自动化和人工智能采用的步伐以及供应商形势不断快速发展,我们为安全和风险管理领导者提供了四项预测,以规划 2024 年及以后 CPS 安全的未来发展方向。 主要发现 随着人工智能的采用加速增加网络物理系统( CPS)的“智…

MPLS基础架构

目录 一、MPLS多协议标签交换概述 1、MPLS是什么 2、MPLS-VPN 3、MPLS起源 (1)、MPLS解决的问题 MPLS解决了三层转发短板问题。 (2)、交换机转发流程 (3)、路由器转发流程 (4)、交换…

【程序员的自我修养11】栈与函数调用过程

绪论 大家好,欢迎来到【程序员的自我修养】专栏。正如其专栏名,本专栏主要分享学习《程序员的自我修养——链接、装载与库》的知识点以及结合自己的工作经验以及思考。编译原理相关知识本身就比较有难度,我会尽自己最大的努力,争…

gradle版本中-bin与-all区别

打开android studio下载的gradle文件,发现-all比-bin多了一个docs文件夹和一个src文件夹。-bin是编译后的二进制发布版,-all还包含了源码和文档,比-bin大了几十兆,两者其余没有区别。 android开发只关注gradle功能不关注实现的情况…

基于K-Means聚类与RFM模型分析顾客消费情况【500010102】

项目说明 本数据集是生成式模拟数据,本项目通过可视化分析对数据进行初步探索,再通过时间序列针对店铺的销售额进行分析,对时序图进行分解,发现数据存在季节性,并且通过auto_arima自动选择参数建立了SARIMA模型&#…

IOS-高德地图路径绘制-Swift

本文展示的是在IOS开发中调用高德地图进行驾车路径绘制,开发语言是Swift。 IOS高德地图集成请看:IOS集成高德地图Api 使用路径规划功能需要集成高德地图的搜索功能。 pod AMapSearch定义AMapSearchAPI 定义主搜索对象 AMapSearchAPI ,并继承…

AI对决:ChatGPT与文心一言的深度比较

. 个人主页:晓风飞 专栏:数据结构|Linux|C语言 路漫漫其修远兮,吾将上下而求索 文章目录 引言ChatGPT与文心一言的比较Chatgpt的看法文心一言的看法Copilot的观点chatgpt4.0的回答 模型的自我评价自我评价 ChatGPT的优势在这里插入图片描述 文…

Linux下的HTTP代理服务器Squid的配置和使用

Squid是一个流行的Linux下的HTTP代理服务器软件。通过Squid,你可以在Linux服务器上设置一个代理服务器,以便为客户端提供安全的网络连接和数据传输。以下是Squid的配置和使用指南。 1. 安装Squid 首先,你需要确保你的Linux系统上已经安装了…

国标GB28181安防视频监控平台EasyCVR视频分享页增加精简模式

智慧安防平台EasyCVR能在复杂的网络环境中(专网、局域网、广域网、VPN、公网等)将前端海量的设备进行统一集中接入与视频汇聚管理,平台支持设备通过4G、5G、WIFI、有线等方式进行视频流的快捷传输,可以兼容各品牌的IPC、NVR、移动…

寒假学习打字:提前实现弯道超车

寒假对于学生来说,通常是一个宝贵的时间段,可以用来放松、充实自己,或者提高一项重要的技能——打字。在这个数字时代,打字技能变得比以往任何时候都更加重要。无论是在学校的论文写作,还是在工作中处理电子邮件&#…

低代码高逻辑谱写IT组织和个人的第二成长曲线 | 专访西门子Mendix中国区总经理王炯

在今天快速演进的数字化转型浪潮中,低代码平台已经成为推动企业敏捷适应市场变化的关键引擎。在此背景下,西门子Mendix作为市场上的领导者,以其创新的低代码解决方案不断地刷新着行业标准。 近日,LowCode低码时代访谈了西门子Men…

C#上位机与欧姆龙PLC的通信12----【再爆肝】上位机应用开发(WPF版)

1、先上图 继上节完成winform版的应用后,今天再爆肝wpf版的,看看看。 可以看到,wpf的确实还是漂亮很多,现在人都喜欢漂亮的,颜值高的,现在是看脸时代,作为软件来说,是交给用户使用的…