0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浅述OpenHarmony HDF 配置管理分析及使用

电子发烧友开源社区 来源:OpenAtom OpenHarmony 作者:OAOH 2021-09-22 14:45 次阅读

HDF配置管理概述

HCS(HDF Configuration Source)是 HDF 驱动框架的配置描述源码,内容以 Key-Value 为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。
HC-GEN(HDF Configuration Generator)是 HCS 配置转换工具,可以将 HDF 配置文件转换为软件可读取的文件格式:
  • 在弱性能环境中,转换为配置树源码,驱动可直接调用 C 代码获取配置。

  • 在高性能环境中,转换为 HCB(HDF Configuration Binary)二进制文件,驱动可使用 HDF 框架提供的配置解析接口获取配置。

以下是使用 HCB 模式的典型应用场景:

f54147e2-0b50-11ec-8fb8-12bb97331649.png

图1 配置使用流程图

HCS 经过 HC-GEN 编译生成 HCB 文件,HDF 驱动框架中的 HCS Parser 模块会从 HCB 文件中重建配置树,HDF 驱动模块使用 HCS Parser 提供的配置读取接口获取配置内容。

f55f2244-0b50-11ec-8fb8-12bb97331649.png

图2 HCS的架构图

HCS 文本更适合人类阅读,但是并不方便程序直接存取,所以经过 HC-GEN 编译,输出二进制的 HCB 数据。HCB 在编译后打包进内核镜像的.rodata 只读分区,在启动加载时,框架定位到 HCB 数据头,再将二进制数据重新构造为树形数据结构供驱动查询和读取。下面详细分析 HC-GEN 实现。

HCS源码语法

HCS 的语法介绍如下: 关键字HCS 配置语法保留了以下关键字:

f5a02334-0b50-11ec-8fb8-12bb97331649.png

基本结构HCS 主要分为属性(Attribute)和节点(Node)两种结构。
  • 属性

    属性即最小的配置单元,是一个独立的配置项。语法如下:
attribute_name = value;
attribute_name 是字母、数字、下划线的组合且必须以字母或下划线开头,字母区分大小写。value 的可用格式如下:
  • 数字常量,支持二进制、八进制、十进制、十六进制数,具体参考数据类型节。

  • 字符串,内容使用双引号("")引用。

  • 节点引用。

  • attribute 必须以分号(;)结束且必须属于一个 node。

  • 节点

节点是一组属性的集合,语法如下:

1.  node_name {2.        module = "sample";3.        ...4.}
  • node_name 是字母、数字、下划线的组合且必须以字母或下划线开头,字母区分大小写。

  • 大括号后无需添加结束符“;”。

  • root为保留关键字,用于声明配置表的根节点。每个配置表必须以 root 节点开始。

  • root 节点中必须包含 module 属性,其值应该为一个字符串,用于表征该配置所属模块。

  • 节点中可以增加 match_attr 属性,其值为一个全局唯一的字符串。在解析配置时可以调用查找接口以该属性的值查找到包含该属性的节点。

数据类型
  • 整型

整型长度自动推断,根据实际数据长度给与最小空间占用的类型。

  • 二进制,0b 前缀,示例:0b1010。

  • 八进制,0 前缀,示例:0664。

  • 十进制 ,无前缀,且支持有符号与无符号,示例:1024,+1024 均合法。负值在读取时注意使用有符号数读取接口。
  • 十六进制,0x 前缀,示例:0xff00、0xFF。

  • 字符串

字符串使用双引号("")表示。

  • 数组

数组元素支持整型、字符串,不支持混合类型。整型数组中 uint32_t uint64_t 混用会向上转型为 uint64_t 数组。整型数组与字符串数组示例如下:
attr_foo = [0x01, 0x02, 0x03, 0x04];attr_bar=["hello","world"];
  • bool类型

bool 类型中 true 表示真,false 表示假。 注释HCS 支持两种注释风格。单行注释:
1.  // comment
多行注释:
2.  /*3.  comment4.*/
其他语法
  • 模板
模板的用途在于生成严格一致的 node 结构,以便对同类型 node 进行遍历和管理。

使用 template 关键字定义模板 node,子 node 通过双冒号“::”声明继承关系。子节点可以改写但不能新增和删除 template 中的属性,子节点中没有定义的属性将使用 template 中的定义作为默认值。示例如下:
root {    module = "sample";    template foo {        attr_1 = 0x1;        attr_2 = 0x2;    }    bar :: foo {    }    bar_1 :: foo {        attr_1 = 0x2;    }}
生成配置树如下:
root {    module = "sample";    bar {        attr_1 = 0x1;        attr_2 = 0x2;    }    bar_1 {        attr_1 = 0x2;        attr_2 = 0x2;    }}
在上述示例中,bar 和 bar_1 节点继承了 foo 节点,生成配置树节点结构与 foo 保持了完全一致,只是属性的值不同。
  • 引用修改

引用修改可以实现修改另外任意一个节点的内容,语法为:
node :& source_node
上述语句表示 node 中的内容是对 source_node 节点内容的修改。示例如下:
root {    module = "sample";    foo {        foo_ :& root.bar{            attr = "foo";        }        foo1 :& foo2 {            attr = 0x2;        }        foo2 {            attr = 0x1;        }    }
    bar {        attr = "bar";    }}
最终生成配置树为:
root {    module = "sample";    foo {        foo2 {            attr = 0x2;        }    }    bar {        attr = "foo";    }}
在以上示例中,可以看到 foo.foo_节点通过引用将 bar.attr 属性的值修改为了"foo",foo.foo1 节点通过引用将 foo.foo2.attr 属性的值修改为了 0x2。

foo.foo_以及 foo.foo1 节点表示对目标节点内容的修改,其自身并不会存在最终生成的配置树中。
  • 引用同级 node,可以直接使用 node 名称,否则被引用的节点必须使用绝对路径,节点间使用“.”分隔,root 表示根节点,格式为 root 开始的节点路径序列,例如 root.foo.bar 即为一个合法的绝对路径。
  • 如果出现修改冲突(即多处修改同一个属性),编译器将提示 warning,因为这种情况下只会生效某一个修改而导致最终结果不确定。
节点复制节点复制可以实现在节点定义时从另一个节点先复制内容,用于定义内容相似的节点。语法为:
node : source_node
上述语句表示在定义"node"节点时将另一个节点"source_node"的属性复制过来。示例如下:
root {    module = "sample";    foo {        attr_0 = 0x0;    }    bar:foo {        attr_1 = 0x1;    }}
上述代码的最终生成配置树为:
root {    module = "sample";    foo {        attr_0 = 0x0;    }    bar {        attr_1 = 0x1;        attr_0 = 0x0;    }}
在上述示例中,编译后 bar 节点即包含 attr_0 属性也包含 attr_1 属性,在 bar 中对 attr_0 的修改不会影响到 foo。在 foo 和 bar 在同级 node 中可不指定 foo 的路径,否则需要使用绝对路径引用。

删除

要对 include 导入的 base 配置树中不需要的节点或属性进行删除,可以使用 delete 关键字。下面的举例中 sample1.hcs 通过 include 导入了 sample2.hcs 中的配置内容,并使用 delete 删除了 sample2.hcs 中的 attribute2 属性和 foo_2 节点,示例如下:
1.  #include "sample1.hcs"2.  root {3.      attr_2 = delete;4.      foo_2 : delete {5.      }6.}
属性引用为了在解析配置时快速定位到关联的节点,可以把节点作为属性的右值,通过读取属性查找到对应节点。语法为:
1.  attribute = &node;

HCB二进制格式

HCB 为便于程序读取的 HCS 的二进制数据格式,按照下面的编码表进行数据组织:

f5cd2cf8-0b50-11ec-8fb8-12bb97331649.png

以一个示例分析下 HCS 源码和 HCB 的对应关系:
root {    module = "sample";    gpio = [1, 2];}
上述 HCS 编译后的 HCB 数据如下:

f5d959c4-0b50-11ec-8fb8-12bb97331649.png

HC-GEN使用介绍

hc-gen 是 HCS 的编译器,用于在编译时将 HCS 转化为 HCB,也可以将 HCB 反编译为 HCS 以验证配置数据的正确性,这在驱动调试时将很有帮助。hc-gen v0.7 之前版本作为 prebuilt 文件以二进制下载方式提供。0.7 版本开始,为了更好的支持多环境部署和版本管理,hc-gen 在编译过程中从源码构建。如果调试需要,可以在 OpenHarmony 源码的 drivers/framework/tools/hc-gen 下执行 make 生成,生成产物在该目录的 build 子目录中。
cd drivers/framework/tools/hc-genmake
./build/hc-gen –v>Hcscompiler0.7
驱动开发过程中,在 hcs 配置文件修改后,可以手动使用 hc-gen 快速验证配置的正确性,生成 HCB 配置文件方法:
hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName]
在驱动调试时,可以使用 hc-gen 反编译 HCB 文件获得 HCS 源码,进行配置数据核对。反编译 HCB 文件为 HCS 方法:
hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName]

HCS文件编译过程

linux 内核中,HCS 编译基于 KBuild 自定义规则实现自主的编译过程,Makefile 入口在 drivers/adapter/khdf/linux/hcs/Makefile。
HC_GEN_DIR := $(abspath $(SOURCE_ROOT)/drivers/framework/tools/hc-gen)HC_GEN := $(HC_GEN_DIR)/build/hc-genLOCAL_HCS_ROOT := $(abspath $(dir $(realpath $(lastword $(MAKEFILE_LIST)))))
# LOCAL_HCS_ROOT为根据目标平台和产品拼接出的HCS路径HCS_DIR := $(LOCAL_HCS_ROOT)HCB_FLAGS := -b -i -a
HCS_OBJ := hdf_hcs_hex.oHCS_OBJ_SRC := $(subst .o,.c,$(notdir $(HCS_OBJ)))
CONFIG_GEN_HEX_SRC := $(addprefix $(LOCAL_HCS_ROOT)/, $(HCS_OBJ_SRC))CONFIG_HCS_SRC := $(subst _hcs_hex.o,.hcs,$(addprefix $(HCS_DIR)/, $(HCS_OBJ)))
# 使用自定义的.o生成规则覆盖KBbuild默认规则$(obj)/$(HCS_OBJ): $(CONFIG_GEN_HEX_SRC)         $(Q)$(CC) $(c_flags) -c -o $@ $<        $(Q)rm -f $<
# 将HCB文件生成后再转换为.c文件中的hex数组,依赖目标为hc-gen工具$(CONFIG_GEN_HEX_SRC):  $(LOCAL_HCS_ROOT)/%_hcs_hex.c: $(HCS_DIR)/%.hcs | $(HC_GEN)        $(Q)echo gen hdf built-in config        $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi        $(Q)$(HC_GEN) $(HCB_FLAGS) -o $(subst _hex.c,,$(@)) $<
# 生成hc-gen工具$(HC_GEN):         $(Q)make -C $(HC_GEN_DIR)
obj-$(CONFIG_DRIVERS_HDF)+=$(HCS_OBJ)
在 HDF 适配其他平台时,可以复用该 Makefile,核心变化点在正确配置对应平台的 HCS 根路径。

HCS配置使用

HCS配置读取接口

在驱动实现中,可以使用 device_resource_if.h 中定义的接口对配置进行查询和读取。常用 API 介绍如下:

f5e38a3e-0b50-11ec-8fb8-12bb97331649.jpg

配置读取接口使用实例UART 控制器驱动为例看 HCS 的使用。UART 在 HCS 中 device_info.hcs 中配置的设备信息为:
device_uart :: device {    device0 :: deviceNode {        policy = 1;        priority = 40;        permission = 0644;        moduleName = "HDF_PLATFORM_UART";        serviceName = "HDF_PLATFORM_UART_0";        deviceMatchAttr = "hisilicon_hi35xx_uart_0";    }}
在 hi35xx_uart_config.hcs 中配置如下:
root {    platform {        uart_config {            device_uart_0x0000  {                serviceName = "";                match_attr = "hisilicon_hi35xx_uart_0";                driver_name = "ttyAMA";                num = 0;            }        }    }}
注意到 UART 使用了 match_attr 特性,这样驱动框架在 device_uart 设备加载时将自动将 device_uart_0x0000 节点关联到该设备。UART 的配置解析代码如下:
static int32_t HdfUartInit(struct HdfDeviceObject *obj){    int32_t ret;    struct DeviceResourceIface *iface = NULL;    devResourceIface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);    if (devResourceIface == NULL) {        HDF_LOGE("%s: face is invalid", __func__);        return HDF_FAILURE;    }
    devResourceIface->GetUint32(obj->property, "num", &host->num, 0);devResourceIface->GetString(obj->property, "driver_name", &drName, "ttyAMA");……       ret = memcpy_s(g_driverName, UART_NAME_LEN - 1, drName, strlen(drName));    if (ret != EOK) {        return HDF_FAILURE;    }    host->method = &g_uartHostMethod;    return HDF_SUCCESS;}
device_uart_0x0000 节点被自动关联到了 HdfDeviceObject 的 property 成员。使用 DeviceResourceGetIfaceInstance 接口获取到 HCS 接口实例后调用其成员方法 GetUint32 读取名为"num"的无符号值属性,使用 GetString 接口读取名为"driver_name"的字符串属性。从配置中获取到属性值后,再根据配置值完成相关软硬件的初始化。

总结

本文从全景介绍了 HCS 配置管理方案,重点分析了 HC-GEN 的实现和 HCS 的编译过程,希望对读者理解 HCS 的原理和配置方法能有所帮助。关于 HDF 驱动框架的更多分析,请关注后续文章。

编辑:jq


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6867

    浏览量

    88800
  • 二进制
    +关注

    关注

    2

    文章

    792

    浏览量

    41593
  • 编译器
    +关注

    关注

    1

    文章

    1618

    浏览量

    49043
  • C代码
    +关注

    关注

    1

    文章

    89

    浏览量

    14285
  • 驱动框架
    +关注

    关注

    0

    文章

    14

    浏览量

    4025
  • OpenHarmony
    +关注

    关注

    25

    文章

    3657

    浏览量

    16129

原文标题:OpenHarmony HDF 配置管理分析及使用

文章出处:【微信号:HarmonyOS_Community,微信公众号:电子发烧友开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    鸿蒙OpenHarmony南向/北向快速开发教程-迅为RK3568开发板

    优化开发流程-配置远程访问环境 P8_优化开发流程-编译源码和烧写镜像 P9_OpenHarmony源码目录介绍 P10_整体移植方案介绍 P11_编译目标分析 P12_编译框架基本概念
    发表于 07-23 10:44

    园区智慧用电管理系统的设计与应用

    程瑜 安科瑞电气股份有限公司 上海嘉定 201801 摘要:为解决目前园区用电管理紊乱、数据采集不便、运维智能化水平低等问题。研究搭建出园区智慧用电管理系统。本系统由网关、PC、手机、智能物联网设备
    的头像 发表于 07-10 09:15 441次阅读
    <b class='flag-5'>浅</b><b class='flag-5'>述</b>园区智慧用电<b class='flag-5'>管理</b>系统的设计与应用

    华为云应用管理和运维平台ServiceStage全新上线

    2024年5月22日,华为云应用管理和运维平台ServiceStage全新上线,提供基于模板的自动化部署、环境配置管理、全链路灰度发布、同城双活高可用架构部署、单元化架构管理等新特性,满足客户针对各类应用的全托管需求,受益客户用
    的头像 发表于 05-24 15:24 746次阅读
    华为云应用<b class='flag-5'>管理</b>和运维平台ServiceStage全新上线

    鸿蒙开发:【OpenHarmony 4.0 Release指导】

    OpenHarmony 4.0版本如期而至,开发套件同步升级到API 10。相比3.2 Release版本,新增4000多个API,应用开发能力更加丰富;HDF新增200多个HDI接口,硬件适配更加便捷;我们持续优化图形框架和方舟编译器(ArkCompiler)
    的头像 发表于 05-14 09:59 1281次阅读
    鸿蒙开发:【<b class='flag-5'>OpenHarmony</b> 4.0 Release指导】

    OpenHarmony开发实例:【配置应用签名信息】

    使用真机设备运行和调试OpenHarmony应用前,需要对应用进行签名才能正常运行。
    的头像 发表于 04-22 16:52 380次阅读
    <b class='flag-5'>OpenHarmony</b>开发实例:【<b class='flag-5'>配置</b>应用签名信息】

    鸿蒙开发实例:【配置OpenHarmony SDK】

    在设置OpenHarmony应用开发环境时,需要开发者在DevEco Studio中配置对应的SDK信息。
    的头像 发表于 04-22 15:24 1745次阅读
    鸿蒙开发实例:【<b class='flag-5'>配置</b><b class='flag-5'>OpenHarmony</b> SDK】

    域环境中的用户与组配置管理

    在域服务器打开组策略管理编辑器-安全设置-受限制的组-添加组-输入administrators-添加成员-选择要添加的成员(testdomain admins)-应用-在客户机上面刷新策略
    的头像 发表于 04-15 10:14 559次阅读
    域环境中的用户与组<b class='flag-5'>配置管理</b>

    鸿蒙开发实战:【Hdf Framework】

    该仓主要存放OpenHarmony驱动子系统核心源码信息(包括驱动框架、配置管理配置解析、驱动通用框架模型、硬件通用平台能力接口等),旨在为开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
    的头像 发表于 03-21 20:29 428次阅读
    鸿蒙开发实战:【<b class='flag-5'>Hdf</b> Framework】

    启动System Init进入OpenHarmony系统过程分析与适配

    1 关键字 启动、Init、产品配置、启动配置 2 简要描述 本文档主要以XX开发版为例分析OpenHarmony系统启动过程、产品配置、启
    发表于 01-26 10:04

    OpenHarmony社区运营报告(2023年11月)

    点击蓝字 ╳ 关注我们 开源项目 OpenHarmony 是每个人的 OpenHarmony ●截至2023年11月,OpenAtom OpenHarmony(简称“OpenHarmony
    的头像 发表于 12-08 21:15 676次阅读
    <b class='flag-5'>OpenHarmony</b>社区运营报告(2023年11月)

    一文电路系统中的谐振(下)

    前两篇中,我们介绍了谐振电路系统的时域分析方法和频域分析方法,并结合了不同的电路实例,总结了软开关ZVS的实现条件。
    的头像 发表于 12-05 16:43 2044次阅读
    一文<b class='flag-5'>浅</b><b class='flag-5'>述</b>电路系统中的谐振(下)

    一文电路系统中的谐振(中)

    在上一篇中,我们建立了谐振电路系统的时域模型和频域模型,简单地分析了单管并联谐振电路实例中谐振网络的应用及其实现零电压(ZVS)开通的机理。
    的头像 发表于 12-05 16:40 1891次阅读
    一文<b class='flag-5'>浅</b><b class='flag-5'>述</b>电路系统中的谐振(中)

    zookeeper的核心配置文件是什么

    ,Zookeeper被广泛应用于服务发现、分布式锁、配置管理等场景中。在Zookeeper的设计中,核心配置文件是zoo
    的头像 发表于 12-04 10:33 735次阅读

    民机机载软件的配置管理

    配置管理(Configuration Management)在航空领域经常又称为构型管理,是现代复杂产品研制的核心技术。与很多传统观念中配置管理是对文档和版本的简单管理不同,现代复杂产
    的头像 发表于 12-01 16:15 787次阅读
    民机机载软件的<b class='flag-5'>配置管理</b>

    Linux网络基本配置管理

    Linux是一种开源操作系统,被广泛用于服务器和网络设备中。在Linux中,网络配置管理是一个重要且复杂的任务。本篇文章将详细介绍Linux网络基本配置管理的知识。 网络
    的头像 发表于 11-27 16:51 883次阅读