赞
踩
HCS(HDF Configuration Source)是 HDF 驱动框架的配置描述参数文件,内容以 Key-Value 为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。 HC-GEN(HDF Configuration Generator)是 HCS 配置转换工具,可以将 HDF 配置文件转换为软件可读取的文件格式。本文不涉及 HC-GEN,假设我们配置好 HCS, 利用其给定的接口可以访问对应设备节点的参数。
HCS 和硬件板卡直接相关,服务于 HDF 驱动框架。下面以一个模拟耳机插拔检测的驱动程序为例,从开发的角度逐步展开说明。
.\vendor\hihope\rk3568\hdf_config\khdf\hdf.hcs
- #include "device_info/device_info.hcs"
- ......
- #include "audio/audio_config.hcs"
- #include "audio/codec_config.hcs"
- #include "audio/dai_config.hcs"
- #include "audio/dma_config.hcs"
- #include "audio/dsp_config.hcs"
- #include "audio/analog_headset_config.hcs" // 新增加文件
- ......
- #include "lcd/lcd_config.hcs"
-
- root {
- module = "rockchip,rk3568_chip";
- }
headset_info 就是耳机插拔检测用到的硬件信息,关键是 headset_gpio
- .\vendor\hihope\rk3568\hdf_config\khdf\audio\analog_headset_config.hcs
- root {
- platform {
- template headset_info {
- match_attr = "";
- serviceName = "";
- }
- headset :: headset_info {
- match_attr = "analog_headset_attr";
- serviceName = "analog_headset_service";
- vendor = 0x0001;
- product = 0x0001;
- version = 0x0100;
- dev_name = "rk809_analog_headset";
- headset_gpio = 115;
- headset_gpio_flag = 0;
- mic_switch_gpio = 0;
- hp_mic_io_value = 0;
- main_mic_io_value = 1;
- headset_wakeup = 1;
- hook_gpio = 0;
- adc_controller_no = 0;
- adc_channel = 0;
- hook_down_type = 0;
- }
- }
- }
在 device_info.hcs 中找到 audio::host 主机节点,配置好服务策略、优先级、加载策略(按时还是按需)、模块名称为驱动加载的名称,服务名称则指向 analog_headset_config.hcs 中的服务名称。模块名称错误驱动程序将不会被加载,服务名称错误则读取参数失败,可能导致驱动程序异常。
关于服务策略、优先级、加载策略在后面描述。
- .\vendor\hihope\rk3568\hdf_config\khdf\device_info\device_info.hcs
- audio :: host {
- hostName = "audio_host";
- priority = 110;
- device_dai :: device {
- device_primary :: deviceNode {
- policy = 1;
- priority = 50;
- preload = 0;
- permission = 0666;
- moduleName = "DAI_RK3568";
- serviceName = "dai_service";
- deviceMatchAttr = "hdf_dai_driver";
- }
- device_hdmi :: deviceNode {
- policy = 1;
- priority = 50;
- preload = 0;
- permission = 0666;
- moduleName = "DAI_RK3568";
- serviceName = "hdmi_dai_service";
- deviceMatchAttr = "hdf_hdmi_dai_driver";
- }
- }
- ......
- // 以下为新增加部分
- device_analog_headset :: device {
- device0 :: deviceNode {
- policy = 1;
- priority = 90;
- preload = 0;
- permission = 0666;
- moduleName = "AUDIO_ANALOG_HEADSET";
- serviceName = "analog_headset_service";
- deviceMatchAttr = "analog_headset_attr";
- }
- }
- }
.\device\board\hihope\rk3568\audio_drivers\headset_monitor\src\analog_headset_core.c
- /* HdfDriverEntry definitions */
- struct HdfDriverEntry g_headsetDevEntry = {
- .moduleVersion = 1,
- .moduleName = "AUDIO_ANALOG_HEADSET",
- .Bind = HdfHeadsetBindDriver,
- .Init = HdfHeadsetInit,
- .Release = HdfHeadsetExit,
- };
- HDF_INIT(g_headsetDevEntry);
- static int32_t HdfHeadsetInit(struct HdfDeviceObject *device)
- {
- const struct DeviceResourceNode *node = NULL;
- static struct HeadsetPdata pdata;
- ......
- node = device->property;
- ret = ReadConfig(node, &pdata);
- ......
- return HDF_SUCCESS;
- }
- #include "device_resource_if.h"
- static int32_t ReadConfig(const struct DeviceResourceNode *node, struct HeadsetPdata *pdata)
- {
- int32_t ret;
- int32_t temp;
- struct DeviceResourceIface *parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
- ret = parser->GetString(node, "dev_name", &pdata->devName, NULL);
- ret = parser->GetUint32(node, "headset_gpio", &pdata->hsGpio, 0);
- ret = parser->GetUint32(node, "headset_gpio_flag", &pdata->hsGpioFlag, OF_GPIO_ACTIVE_LOW);
- ret = ReadHookModeConfig(parser, node, pdata);
- (void)ReadMicConfig(parser, node, pdata);
- ret = parser->GetUint32(node, "headset_wakeup", &temp, 0);
- return HDF_SUCCESS;
- }
.\device\board\hihope\rk3568\audio_drivers\Makefile
- obj-$(CONFIG_DRIVERS_HDF_AUDIO_ANA_HEADSET) += \
- headset_monitor/src/analog_headset_base.o \
- headset_monitor/src/analog_headset_core.o \
- headset_monitor/src/analog_headset_gpio.o \
- headset_monitor/src/analog_headset_adc.o
-
- ccflags-$(CONFIG_DRIVERS_HDF_AUDIO_ANA_HEADSET) += \
- -I$(srctree)/$(KHDF_FRAMEWORK_ROOT_DIR)/model/input/driver \
- -I$(srctree)/drivers/hdf/evdev \
- -I$(srctree)/$(KHDF_AUDIO_RK3568_INC_DIR)/headset_monitor/include
在驱动实现中,使用 device_resource_if.h 中定义的接口对配置进行查询和读取,所在目录.\drivers\hdf_core\interfaces\inner_api\utils\device_resource_if.h。常用 API 介绍如下:
HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
HDF 框架将一类设备驱动放在同一个 Host 里面,开发者也可以将 Host 中的驱动功能分层独立开发和部署,支持一个驱动多个 Node,HDF 驱动模型如下图所示:
开发者应当将同一类的设备放在同一个 Host 里面,在新增设备时,检查是否已经存在同类型的 Host。如果已存在 Host,则将 Device 配置在此 Host 中,禁止重复配置 Host。一个驱动设备应该只属于一类驱动类型,因此也禁止将同一个 Device 配置在不同 Host 当中。
驱动服务必须按照业务规则设置对外发布的策略,禁止设置不必要的发布策略。驱动服务是 HDF 驱动设备对外提供能力的对象,由 HDF 框架统一管理。HDF 框架定义了驱动对外发布服务的策略,是由配置文件中的 policy 字段来控制,policy 字段的取值范围以及含义如下:
- typedef enum {
- /* 驱动不提供服务 */
- SERVICE_POLICY_NONE = 0,
- /* 驱动对内核态发布服务 */
- SERVICE_POLICY_PUBLIC = 1,
- /* 驱动对内核态和用户态都发布服务 */
- SERVICE_POLICY_CAPACITY = 2,
- /* 驱动服务不对外发布服务,但可以被订阅 */
- SERVICE_POLICY_FRIENDLY = 3,
- /* 驱动私有服务不对外发布服务,也不能被订阅 */
- SERVICE_POLICY_PRIVATE = 4,
- /* 错误的服务策略 */
- SERVICE_POLICY_INVALID
- } ServicePolicy;
因此,驱动服务应该按照业务规则来设置发布策略,禁止设置不必要的发布策略,如内核态驱动设置用户态的发布策略。
HDF 驱动加载包括按需加载和按序加载。
按需加载:HDF 框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载。
按序加载:HDF 框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。
HDF 框架结构庞杂,意义深远,值得每个底层开发者不断探索和改善。HCS 仅仅是其中一个功能点,此文旨在抛砖引玉,深层了解还需要阅读专业文档和源码。
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。
这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
HarmonOS基础技能
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
OpenHarmony北向、南向开发环境搭建
获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。