主要介绍input的hdf驱动架构,由于目前手中没有开发板,只能从代码层面进行分析,后续进行实际操作后会持续更新。如有错误希望大家指正、交流。

首先需要熟悉OpenHarmony的驱动架构,如下图:

img OpenHarmony驱动架构

图 1 OpenHarmony驱动架构

HDF驱动架构主要组成部分:

  • HDI(Hardware Device Interface,硬件设备统一接口)层:通过规范化的设备接口标准,为系统提供统一、稳定的硬件设备操作接口。

  • HDF驱动框架:提供统一的硬件资源管理、驱动加载管理、设备节点管理、设备电源管理以及驱动服务模型等功能,需要包含设备管理、服务管理、DeviceHost、PnPManager等模块。

  • 统一的配置界面:支持硬件资源的抽象描述,屏蔽硬件差异,可以支撑开发者开发出与配置信息不绑定的通用驱动代码,提升开发及迁移效率,并可通过HC-Gen等工具快捷生成配置文件。

  • 操作系统抽象层(OSAL,Operating System Abstraction Layer):提供统一封装的内核操作相关接口,屏蔽不同系统操作差异,包含内存、锁、线程、信号量等接口。

  • 平台驱动:为外设驱动提供Board硬件(如:I2C/SPI/UART总线等平台资源)操作统一接口,同时对Board硬件操作进行统一的适配接口抽象以便于不同平台迁移。

  • 外设驱动模型:面向外设驱动,提供常见的驱动抽象模型,主要达成两个目的,提供标准化的器件驱动,开发者无需独立开发,通过配置即可完成驱动的部署;提供驱动模型抽象,屏蔽驱动与不同系统组件间的交互,使得驱动更具备通用性。

1. 南向HDF编译架构

img input南向HDF编译流程

图 2 input南向HDF编译流程

1.1.配置HDF的kconfig参数

路径1:kernel/linux/config/linux-5.10/base_defconfig

CONFIG_DRIVERS_HDF=y

路径2:kernel/linux/config/linux-5.10/rk3568/arch/arm64_defconfig

CONFIG_DRIVERS_HDF_INPUT=y

CONFIG_DRIVERS_HDF_TP_5P5_GT911=y

在最后编译完成的内核中执行“make menuconfig”可以看到,input的HDF驱动配置已开:

img

1.2. 根据kconfig配置编译相应模块

路径:drivers/hdf_core/adapter/khdf/linux/model/input/Makefile


INPUT_ROOT_DIR = ../../../../../framework/model/input/driver

obj-$(CONFIG_DRIVERS_HDF_INPUT) += \

​        $(INPUT_ROOT_DIR)/input_bus_ops/input_i2c_ops.o \

​        $(INPUT_ROOT_DIR)/hdf_input_device_manager.o \

​        $(INPUT_ROOT_DIR)/input_config_parser.o \

​        $(INPUT_ROOT_DIR)/event_hub.o \

​        $(INPUT_ROOT_DIR)/hdf_touch.o \

​        $(INPUT_ROOT_DIR)/hdf_key.o \

​        $(INPUT_ROOT_DIR)/hdf_hid_adapter.o

obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \

​       $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o

obj-$(CONFIG_ARCH_NXP_TOUCH) += \

​       $(INPUT_ROOT_DIR)/touchscreen/touch_ft5x06.o

obj-$(CONFIG_DRIVERS_HDF_TP_2P35_FT6236) += \

​       $(INPUT_ROOT_DIR)/touchscreen/touch_ft6336.o

obj-$(CONFIG_DRIVERS_HDF_INPUT_INFRARED) += \

​       $(INPUT_ROOT_DIR)/hdf_infrared.o

obj-$(CONFIG_DRIVERS_HDF_TP_5P43_FT5406) += \

​       $(INPUT_ROOT_DIR)/touchscreen/touch_ft5406.o

 

ccflags-y +=-I$(srctree)/drivers/hdf/framework/model/input/driver \

​      -I$(srctree)/drivers/hdf/framework/model/input/driver/input_bus_ops \

​     、、、 、、、 #省略

​      -I$(srctree)/drivers/hdf/khdf/osal/include

ccflags-y +=-I$(srctree)/bounds_checking_function/include \

​      -I$(srctree)/drivers/hdf/evdev

这里是一个常见的编译脚本,开启配置后,将对应源文件编译成库。

1.3. 设备树私有信息配置

路径1:vendor/hihope/rk3568/hdf_config/khdf/input/input_config.hcs

包括了设备类型、上下电时序等,平台硬件信息包含了器件使用的GPIO的电口信息等,需要根据具体使用的硬件修改。


boardConfig {

match_attr = "touch_device1";

inputAttr {

/* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */

  inputType = 0;

  solutionX = 720;

  solutionY = 1280;

  devName = "main_touch";

  }

 

// Hi3516DV300-Runhe  gt911--5p5 & 4p0

busConfig {

  // 0:i2c 1:spi

  busType = 0;

  busNum = 1;

  clkGpio = 86;

  dataGpio = 87;

  i2cClkIomux = [0x114f0048, 0x403];

  i2cDataIomux = [0x114f004c, 0x403];

 }

pinConfig {

  rstGpio = 14;

  intGpio = 13;

  rstRegCfg = [0x112f0094, 0x400];

  intRegCfg = [0x112f0098, 0x400];

 }

路径2:vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs

主要配置的驱动注册到HDF框架做需要的设备驱动描叙信息,如驱动的加载与否及加载次序等。

该文件提供了 Input 模型各层驱动注册到 HDF 框架所必需的信息,各驱动层私有配置信息过“deviceMatchAttr”字段与 input_config.hcs 中的“match_attr”相关内容进行匹配。

配置文件中与input模块相关的部分内容说明:

 input :: host {

   hostName = "input_host";

   priority = 100;

   device_input_manager :: device {

   device0 :: deviceNode {

​       policy = 2;

​       priority = 100;

​       preload = 0;

​       permission = 0660;

​       moduleName = "HDF_INPUT_MANAGER";

​       serviceName = "hdf_input_host";

​       deviceMatchAttr = "";

​     }

   }

   device_hdf_touch :: device {

​     device0 :: deviceNode {

​       policy = 2;

​       priority = 120;

​       preload = 0;

​       permission = 0660;

​       moduleName = "HDF_TOUCH";

​       serviceName = "hdf_input_event1";

​       deviceMatchAttr = "touch_device1";

​     }

   }

1.4. 解析私有配置

路径:drivers/hdf_core/framework/model/input/driver/input_config_parser.c

此文件对HDF中设备树的私有配置进行解析,部分接口如下:

static int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode,

  BoardAttrCfg *attr)

{

  int32_t ret;

  ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0);

  CHECK_PARSER_RET(ret, "GetUint8");

  ret = parser->GetString(attrNode, "devName", &attr->devName, NULL);

  CHECK_PARSER_RET(ret, "GetString");

  ret = parser->GetUint32(attrNode, "solutionX", &attr->resolutionX, 0);

  CHECK_PARSER_RET(ret, "GetUint32");

  ret = parser->GetUint32(attrNode, "solutionY", &attr->resolutionY, 0);

  CHECK_PARSER_RET(ret, "GetUint32");

  return HDF_SUCCESS;

}

1.5. 驱动注册、绑定

路径:drivers/hdf_core/framework/model/input/driver

将hcs文件的信息解析完成后,会将对应的设备添加到“BoardAttrCfg *attr”结构体中,给驱动的接口调用。

此路径下放的是驱动的源文件以及头文件,主要是做驱动的初始化、事件处理、注册和绑定等动作,对应图1中的4、5。

路径:drivers\hdf_core\framework\model\input\driver\hdf_touch.c

struct HdfDriverEntry g_hdfTouchEntry = {

  .moduleVersion = 1,

  .moduleName = "HDF_TOUCH",

  .Bind = HdfTouchDriverBind,

  .Init = HdfTouchDriverProbe,

  .Release = HdfTouchDriverRelease,

};

路径:drivers\hdf_core\framework\model\input\driver\touchscreen\touch_gt911.c

struct HdfDriverEntry g_touchGoodixChipEntry = {

  .moduleVersion = 1,

  .moduleName = "HDF_TOUCH_GT911",

  .Init = HdfGoodixChipInit,

  .Release = HdfGoodixChipRelease,

};

2. 北向HDI编译架构

OpenHarmony中hdi_input_udriver接口编译流程如下:

img hdi_input_udriver编译流程

图 3 hdi_input_udriver编译流程

2.1. config.json文件

配置子系统以及子系统特性,例子如下:

{

​    "subsystem": "hdf",

​    "components": [

​     { "component": "hdf_core", "features":[ "hdf_core_platform_test_support = true" ] },

​     { "component": "drivers_peripheral_display", "features":[] },

​     { "component": "drivers_peripheral_input", "features":[

​      "drivers_peripheral_input_feature_lite_support_test = true"

​     ] }

​       、、、、#省略

​    ]

   },

2.2. bundle.json配置

路径:drivers/peripheral/input/bundle.json

每个模块下面都会存放一个bundle.json文件,文件描述了模块名、子模块、特性以及编译路径等信息。

 "name": "drivers_peripheral_input",

  "subsystem": "hdf",

  "features": [

   "drivers_peripheral_input_feature_model",

   "drivers_peripheral_input_feature_udriver",

   "drivers_peripheral_input_feature_lite_support_test",

   "drivers_peripheral_input_feature_support_ddk"

  ],

"adapted_system_type": ["standard", "small"],

、、、省略

 "build": {

   "sub_component": [

​    "//drivers/peripheral/input:input_entry"

   ],

“name”:组件名。

“subsystem”:子系统名称。

“features”:特性。

“adapted_system_type”:适配系统类型。

“sub_component”:子组件路径。

2.3. Input模块编译入口

路径:drivers/peripheral/input/BUILD.gn

此文件对ohos的系统类型、开启的特性进行区分,然后进入不同的编译分支。标准系统走下方的group,如果开启drivers_peripheral_input_feature_udriver特性,那么将依赖

"udriver:hdi_input_udriver"if (defined(ohos_lite)) {

 group("input_entry") {

  deps = [ "hal:hdi_input" ]

 }

} else {

 group("input_entry") {

  deps = [ "hdi_service:hdi_input_service" ]

  if (drivers_peripheral_input_feature_model) {

   deps += [ "hal:hdi_input" ]

  }

  if (drivers_peripheral_input_feature_udriver) {

   deps += [ "udriver:hdi_input_udriver" ]

  }

  if (drivers_peripheral_input_feature_support_ddk) {

   deps += [ "ddk_service:hid_ddk_target" ]

  }

 }

}

2.4. 编译hdi接口文件

路径:drivers/peripheral/input/udriver/BUILD.gn

此文件对用户态的input hdi接口文件进行编译,并生成.so库。

if (drivers_peripheral_input_feature_udriver) {

 ohos_shared_library("hdi_input_udriver") {

  sources = [

   "src/input_device_manager.cpp",

   "src/input_manager.cpp",

  ]

​      、、、、省略

  if (is_standard_system) {

   external_deps = [

​    "c_utils:utils",

​    "hdf_core:libhdf_utils",

​    "hilog:libhilog",

   ]

  } else {

   external_deps = [ "hilog:libhilog" ]

  }

   、、、、省略

  install_enable = true

  subsystem_name = "hdf"

  part_name = "drivers_peripheral_input"

 }

} else {

 group("hdi_input_udriver") {

  deps = []

 }

}
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐