OpenHarmony实战:硬件适配之HCS应用

一、HCS 配置管理

HCS(HDF Configuration Source)是 HDF 驱动框架的配置描述参数文件,内容以 Key-Value 为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。 HC-GEN(HDF Configuration Generator)是 HCS 配置转换工具,可以将 HDF 配置文件转换为软件可读取的文件格式。本文不涉及 HC-GEN,假设我们配置好 HCS, 利用其给定的接口可以访问对应设备节点的参数。

HCS 和硬件板卡直接相关,服务于 HDF 驱动框架。下面以一个模拟耳机插拔检测的驱动程序为例,从开发的角度逐步展开说明。

二、应用举例

第一步,找到 HDF 系统相关总入口 hdf.hcs 文件,在 audio 位置新增加 audio/analog_headset_config.hcs 参数文件,系统在加载的时候会读取该参数文件。

.\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;
        }
    }
}

第三步,这个功能需要在 audio 关键模块加载之后加载

在 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";
        }
    }
}

第四步,驱动程序通过 HDF_INIT 宏,在系统启动时完成设备与服务的绑定,关键就是这个模块名称,找到这个模块名称后,进而去初始化硬件。

.\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);

第五步,初始硬件时,务必先读取必要的 HCS 硬件信息

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;
}

第六步,调用 device_resource_if.h 中对外的接口函数,根据名称读取所有信息到 pdata

#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;
}

第七步,驱动编写完成后,需要就近修改 Makefile 中要编译的驱动源文件

.\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

第八步,这个属于通用功能,板卡支持与否,需要在 Kconfig 文件配置 CONFIG_DRIVERS_HDF_AUDIO_ANA_HEADSET 来决定是否编译以上文件。

三、 device_resource_if.h 接口定义

在驱动实现中,使用 device_resource_if.h 中定义的接口对配置进行查询和读取,所在目录.\drivers\hdf_core\interfaces\inner_api\utils\device_resource_if.h。常用 API 介绍如下:

四、HDF 关键点说明

HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。

4.1. HDF 驱动模型

HDF 框架将一类设备驱动放在同一个 Host 里面,开发者也可以将 Host 中的驱动功能分层独立开发和部署,支持一个驱动多个 Node,HDF 驱动模型如下图所示:

开发者应当将同一类的设备放在同一个 Host 里面,在新增设备时,检查是否已经存在同类型的 Host。如果已存在 Host,则将 Device 配置在此 Host 中,禁止重复配置 Host。一个驱动设备应该只属于一类驱动类型,因此也禁止将同一个 Device 配置在不同 Host 当中。

4.2. 发布策略

驱动服务必须按照业务规则设置对外发布的策略,禁止设置不必要的发布策略。驱动服务是 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;

因此,驱动服务应该按照业务规则来设置发布策略,禁止设置不必要的发布策略,如内核态驱动设置用户态的发布策略。

4.3. 加载时机

HDF 驱动加载包括按需加载和按序加载。
按需加载:HDF 框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载。
按序加载:HDF 框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。

五、总结

HDF 框架结构庞杂,意义深远,值得每个底层开发者不断探索和改善。HCS 仅仅是其中一个功能点,此文旨在抛砖引玉,深层了解还需要阅读专业文档和源码。

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

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

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

相关文章

Git、TortoiseGit、SVN、TortoiseSVN 的关系和区别

Git、TortoiseGit、SVN、TortoiseSVN 的关系和区别 (二)Git(分布式版本控制系统):(二)SVN(集中式版本控制系统)(三)TortoiseGit一、下载安装 git二、安装过程…

“转行做程序员”很难?这里有4个建议

近几年来,传统行业多处于经济下行,加上互联网行业的赚钱效应,想要转行到这一行的人越来越多,其中程序员这个行业更是很多人梦寐以求的。 但另一方面,我们也发现,这些想要转行的同学们往往会遇到很多困扰。…

企业员工在线培训系统功能介绍

随着信息技术的飞速发展,企业员工培训方式正逐步从传统的面授转向灵活高效的在线培训。一个综合性的企业员工在线培训系统能够为员工提供多样化的学习资源、便捷的学习途径和有效的学习监督,以下是该系统的主要功能详细介绍: 1. 课程功能 线…

如何应对光模块故障,只需一条命令!

你们好,我的网工朋友。 是设备就有故障,光模块也不例外,而且很多项目的故障首先要排除光模块的问题。 像光模块型号选用是否正确? 使用的跳线是否正确? 交换机接口是否用匹配? ....各种各样的问题&…

MySQL中count(*) 和 count(1)区别

MySQL 中 count(*) 和 count(1) 的异同 count() 函数的基本原理 语法: COUNT(expr)其中: expr 可以是字段名、常量、表达式或星号 (*)。 用法: count() 函数用于统计满足特定条件的记录数量。它可以有以下几种用法: 1. 统计…

【带你了解下前端开发语言有那些】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

JavaEE初阶之线程安全(一)

目录 题外话 正题 1.线程调度是随机的 2.修改共享数据 知识点 线程同步机制 线程异步机制 举例说明 synchronized() 知识点 举例说明 举例代码详解 死锁 举个例子: 代码 小结 题外话 这两天忽冷忽热的感冒了,昨天状态特别不好断更了一天,今天继续加油! 我会把…

【RT_Thread】---stm32f407zgt6使用env配置工程

用rt_thread env配置工程 1. git rt_thread 源码 2.找到对应芯片厂家扳机支持包 3 重新命名一个自己项目的工程 4 打开env 配置驱动 具体参考官方:Env 用户手册 (rt-thread.org) 5 修改路径为英文 6 修改完boad init 就应该可以用了(还有系统时钟不然会有问题)…

基于stm32的h5的spi屏幕调试

基于stm32的h5的spi屏幕调试 本文目标:基于stm32的基础实验 按照本文的描述,应该可以跑通实验并举一反三。 先决条件:装有编译和集成的开发环境,比如:Keil uVision5、STM32CubeMX 使用外设:GPIO、SPI …

Redis中的复制功能(一)

复制 概述 在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave),如图所示…

Python 全栈体系【四阶】(十八)

第五章 深度学习 一、基本理论 4. 神经网络的改进 4.1 神经网络的局限 全连接神经网络的局限(一) 未考虑数据的“形状”,会破坏数据空间结构。例如,输入数据是图像时,图像通常是高长通道方向上的 3 维形状。但是&a…

基于springboot+vue实现的房源出租信息系统

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…

Java学习之类和对象、内存底层

目录 表格结构和类结构 表格的动作和类的方法 与面向过程的区别 具体实现 对象和类的详解 类的定义 属性(field 成员变量) 方法 示例--编写简单的学生类 简单内存分析(理解面向对象) 构造方法(构造器 constructor) 声明格式: 四…

深入探究Shrio反序列化漏洞

Shrio反序列化漏洞 什么是shrio反序列化漏洞环境搭建漏洞判断rememberMe解密流程代码分析第一层解密第二层解密2.1层解密2.2层解密 exp 什么是shrio反序列化漏洞 Shiro是Apache的一个强大且易用的Java安全框架,用于执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的…

FittenChat:程序员写代码的最好辅助利器,没有之一

🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师,大模型,爬虫、ACM算法 💒 公众号&#xff…

如何评估基于指令微调的视觉语言模型的各项能力-MMBench论文解读

1. 传统基准的固有局限 VQAv2:视觉问题回答数据集,主要用于评估视觉理解与推理能力。COCO Caption:图像描述生成数据集,用于评估模型对图像内容的理解与描述能力。GQA:结合常识的视觉问题回答数据集。OK-VQA:需要外部知识的视觉问题回答数据集。TextVQA:图像中包含文本的…

Linux系统网络的实时性评估

目录 1.使用 cyclictest 测试系统实时性2.测试系统通信实时性2.1 PingPlotter2.2 使用 ping 测试通讯实时性 3. 使用 iperf 测试带宽4.网络性能测试 1.使用 cyclictest 测试系统实时性 安装cyclictest sudo apt-get update sudo apt-get install rt-testscyclictest -p 99 -i…

TS学习01 基本类型、编译选项、打包ts代码

TS学习 TypeScript00 概念01 开发环境搭建02 基本类型基本使用⭐类型 03 编译选项tsconfig.jsoncompilerOptions语法检查相关 04 webpack打包ts代码错误解决 05 babel TypeScript BV1Xy4y1v7S2学习笔记 00 概念 以 JavaScript 为基础构建的语言 一个 JavaScript 的超集 Type…

如何使用KST指标进行多头交易,Anzo Capital一个条件设置

在之前的文章中,我们进行分享了以下知识:什么是KST指标,以及如何进行计算KST指标。有聪明的投资者就在后台进行咨询Anzo Capital昂首资本了,我们知道这些知识有什么用呢? 当然有用了,只要理解背后的逻辑知…

三层架构实验--对抗遗忘

交换配置顺序: channel vlan Trunk stp svi vrrp dhcp 绑定channel [sw1]interface e [sw1]interface Eth-Trunk 0 [sw1-Eth-Trunk0]int g 0/0/22 [sw1-GigabitEthernet0/0/22]eth-trunk 0 [sw1-GigabitEthernet0/0/23]eth-trunk 0 [sw2]interface Eth…