当前位置:   article > 正文

OpenHarmony之HDF驱动开发流程指导

OpenHarmony之HDF驱动开发流程指导

开发指导

场景介绍

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

驱动开发实例

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

驱动实现

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

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

    驱动入口注册到HDF框架

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

    驱动编译脚本编写

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

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

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

      BUILD.gn部分:

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

      1. import("//build/lite/config/component/lite_component.gni")
      2. import("//drivers/hdf_core/adapter/khdf/liteos/hdf.gni")
      3. module_switch = defined(LOSCFG_DRIVERS_HDF_xxx)
      4. module_name = "xxx"
      5. hdf_driver(module_name) {
      6. sources = [
      7. "xxx/xxx/xxx.c", #模块要编译的源码文件
      8. ]
      9. public_configs = [ ":public" ] #使用依赖的头文件配置
      10. }
      11. config("public") { #定义依赖的头文件配置
      12. include_dirs = [
      13. "xxx/xxx/xxx", #依赖的头文件目录
      14. ]
      15. }

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

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

      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配置文件中添加对应的设备描述。驱动的设备描述填写如下所示:
      1. root {
      2. device_info {
      3. match_attr = "hdf_manager";
      4. template host { // host模板,继承该模板的节点(如下sample_host)如果使用模板中的默认值,则节点字段可以缺省。
      5. hostName = "";
      6. priority = 100;
      7. uid = ""; // 用户态进程uid,缺省为空,会被配置为hostName的定义值,即普通用户。
      8. gid = ""; // 用户态进程gid,缺省为空,会被配置为hostName的定义值,即普通用户组。
      9. caps = [""]; // 用户态进程Linux capabilities配置,缺省为空,需要业务模块按照业务需要进行配置。
      10. template device {
      11. template deviceNode {
      12. policy = 0;
      13. priority = 100;
      14. preload = 0;
      15. permission = 0664;
      16. moduleName = "";
      17. serviceName = "";
      18. deviceMatchAttr = "";
      19. }
      20. }
      21. }
      22. sample_host :: host{
      23. hostName = "host0"; // host名称,host节点是用来存放某一类驱动的容器。
      24. priority = 100; // host启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证host的加载顺序。
      25. caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH"]; // 用户态进程Linux capabilities配置。
      26. device_sample :: device { // sample设备节点
      27. device0 :: deviceNode { // sample驱动的DeviceNode节点
      28. policy = 1; // policy字段是驱动服务发布的策略,在驱动服务管理章节有详细介绍。
      29. priority = 100; // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序。
      30. preload = 0; // 驱动按需加载字段。
      31. permission = 0664; // 驱动创建设备节点权限
      32. moduleName = "sample_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致。
      33. serviceName = "sample_service"; // 驱动对外发布服务的名称,必须唯一。
      34. deviceMatchAttr = "sample_config"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等。
      35. }
      36. }
      37. }
      38. }
      39. }

      说明:

    • 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:驱动按需加载字段。
      1. root {
      2. SampleDriverConfig {
      3. sample_version = 1;
      4. sample_bus = "I2C_0";
      5. match_attr = "sample_config"; // 该字段的值必须和device_info.hcs中的deviceMatchAttr值一致
      6. }
      7. }

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/246711
推荐阅读
相关标签
  

闽ICP备14008679号