Harmony 鸿蒙驱动开发

驱动开发

驱动模型介绍

HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个Host(设备容器)里面,用于管理一组设备的启动加载等过程。在划分Host时,驱动程序是部署在一个Host还是部署在不同的Host,主要考虑驱动程序之间是否存在耦合性,如果两个驱动程序之间存在依赖,可以考虑将这部分驱动程序部署在一个Host里面,否则部署到独立的Host中是更好的选择。Device对应一个真实的物理设备。DeviceNode是设备的一个部件,Device至少有一个DeviceNode。每个DeviceNode可以发布一个设备服务。驱动即驱动程序,每个DevicdNode唯一对应一个驱动,实现和硬件的功能交互。HDF驱动模型如下图所示:

图1 HDF驱动模型

驱动开发步骤

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

  1. 驱动实现

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

  • 驱动业务代码

      #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**里面:
    
    
       ```c
       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权限时,请找安全专家进行评审。

    • 进程的uid在文件base/startup/init_lite/services/etc/passwd中配置,进程的gid在文件base/startup/init_lite/services/etc/group中配置,进程uid和gid配置参考:系统服务用户组添加方法。

    • caps值:格式为caps = [“xxx”],如果要配置CAP_DAC_OVERRIDE,此处需要填写caps = [“DAC_OVERRIDE”],不能填写为caps = [“CAP_DAC_OVERRIDE”]。

    • preload:驱动按需加载字段,参考驱动加载。

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

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

      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"
    

为了能让大家更好的学习鸿蒙 (OpenHarmony) 开发技术,这边特意整理了《鸿蒙 (OpenHarmony)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

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

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. ……

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门?:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里巴巴开源联邦学习框架FederatedScope

5月5日,阿里巴巴达摩院发布新型联邦学习框架FederatedScope,声称可以在不共享训练数据的情况下开发机器学习算法,从而保护隐私。,其源代码现已在Apache 2.0许可下发布在GitHub上。 介绍 该平台被描述为一个全面的联邦学习框架&a…

compose部署tomcat

1.部署tomcat 1.1.下载相关镜像tomcat8.5.20 $ docker pull tomcat:8.5.20 1.2 在/data目录下创建tomcat/webapps目录 mkdir -p /data/tomcat/webapps 注意:这里是准备将宿主机的/data/tomcat/webapps映射到容器的 /usr/…

Oracle篇—分区表和分区索引的介绍和分类(第一篇,总共五篇)

☘️博主介绍☘️: ✨又是一天没白过,我是奈斯,DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux,也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注❣…

ChatGPT 引导语写法参考(翻译类引导语)

充当英语翻译和改进者 我想让你充当英文翻译员、拼写纠正员和改进员。我会用任何语言与你交谈,你会检测语言,翻译它并用我的文本的更正和改进版本用英文回答。我希望你用更优美优雅的高级英语单词和句子替换我简化的 A0 级单词和句子。保持相同的意思&am…

顶顶通呼叫中心中间件利用自动外呼进入机器人的压力测试配置流程

文章目录 前言呼入进入机器人配置流程呼入配置创建线路创建线路组创建自动外呼任务1. 实现“一端放音,另一端进入机器人”操作创建拨号方案—“模拟放音”呼叫路由—“internal”启用拨号方案—“模拟放音”队列外呼配置 2. 实现“两端都进入机器人”操作队列外呼配…

JavaWeb会议管理系统

相关技术: Servlet Tomcat jsp MySQL 有需要的可以联系我。 功能介绍: 会员管理系统:系统管理、用户管理、角色管理、菜单管理、日志管理、部门管理 会议管理:会议室管理、我的会员、会员纪要、修改密码、安全退出 会议室管…

C/C++读写文件和stringstream类

目录 C处理文件打开文件两种函数的区别 读文件两种函数区别其它读操作的函数fgetc:从文件中读取一个字符fgets:从文件中读取一个字符串fscanf:按格式从文件中读取指定内容,与scanf函数类似 写文件其它的常用写操作函数fputc&#…

【网站项目】基于SSM的263货物进销管理系统

🙊作者简介:多年一线开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

Java项目:基于ssm框架实现的电影评论系统(ssm+B/S架构+源码+数据库+毕业论文)

一、项目简介 本项目是一套ssm826基于ssm框架实现的电影评论系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#x…

Elasticsearch:2023 年 Lucene 领域发生了什么?

作者:来自 Elastic Adrien Grand 2023 年刚刚结束,又是 Apache Lucene 开发活跃的一年。 让我们花点时间回顾一下去年的亮点。 社区 2023 年,有: 5 个次要版本(9.5、9.6、9.7、9.8 和 9.9),1 …

【CSP-J/S】复赛注意事项 上机文件组织形式

每年 CSP-J/S 复赛都有很多同学因为一些小失误导致一年的努力付之东流。Tony老师整理了一些复赛容易踩坑的点,或许对你有帮助! 一、文件的输入输出 CSP、NOIP复赛与我们平时在Online Judge做题形式会有一些区别,需要我们将文件放入规定的地…

基于模糊PID控制器的风力温度控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 模糊逻辑控制原理 4.2 PID控制原理 4.3 模糊PID控制器原理 4.4 整体系统概述 5.完整工程文件 1.课题概述 当房间的温度不能保持目标温度时,这个系统中的某个部件肯定出现问题了&#x…

flink学习之窗口处理函数

窗口处理函数 什么是窗口处理函数 Flink 本身提供了多层 API,DataStream API 只是中间的一环,在更底层,我们可以不定义任何具体的算子(比如 map(),filter(),或者 window()),而只是…

怎么缩小动图的大小?一分钟快速压缩gif体积

GIF动图是一种使用GIF文件格式创建的动画图像。GIF是一种常见的图像文件格式,它支持多帧图像以形成连续播放的动画效果。与其他图像格式只能表示静态图像不同,GIF格式可以存储多个图像帧,并通过在特定时间间隔内循环播放这些帧来创建动画效果…

Instagram被停用怎么办?2024年ins停权最新解决方法

大家有没有遇到过 Instagram 账号突然无缘无故消失的情况?这很有可能是 Instagram 无故禁用了你的账号,面对 Instagram 账号突然被停用的情况,许多用户都感到困惑和无助。这个问题可能影响到你的社交生活,甚至是商业活动。但别担心…

写给不耐烦程序员的 JavaScript 指南(五)

第七部分:集合 原文:exploringjs.com/impatient-js/pt_collections.html 译者:飞龙 协议:CC BY-NC-SA 4.0 下一步:30 同步迭代 三十、同步迭代 原文:exploringjs.com/impatient-js/ch_sync-iteration.htm…

【开源】基于JAVA的人事管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员功能模块2.2 普通员工功能模块2.3 答辩文案 三、系统展示四、核心代码4.1 查询职称4.2 新增留言回复4.3 工资申请4.4 工资审核4.5 员工请假 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的人…

制造领域 物料清单(BOM)与零件明细表的区别

有许多人分不清物料清单(BOM)与零件明细表的区别,其实它们在企业的生产管理软件中起着不同的作用,各有各的特色,但是却有不尽相同。接下来我们就来区分一下吧 物料清单(BOM),是详细记录一个项目所用到的所有下阶材料及相关属性,亦即母件与所有子件的从属…

【2024-01-22】某极验3流程分析-滑块验证码

声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、抓包流程分析1.刷新页面2.点击按钮进行验证…

第二证券:暴跌超24%!美农产品贸易巨头一夜蒸发超600亿

当地时刻1月22日,美股三大股指集体收涨,道指与标普500指数再创前史新高,道指初次收在38000点上方。到收盘,道指涨0.36%,标普500指数涨0.22%,纳指涨0.32%。 大型科技股涨跌不一,其中&#xff0c…