1# 配置管理 2 3 4## 配置概述 5 6HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。 7 8HC-GEN(HDF Configuration Generator)是HCS配置转换工具,可以将HDF配置文件转换为软件可读取的文件格式: 9 10- 在弱性能环境中,转换为配置树源码或配置树宏定义,驱动可直接调用C代码或宏式APIs获取配置。 11 12- 在高性能环境中,转换为HCB(HDF Configuration Binary)二进制文件,驱动可使用HDF框架提供的配置解析接口获取配置。 13 14以下是使用HCB模式的典型应用场景: 15 16 **图1** 配置使用流程图 17 18 ![配置使用流程](figures/配置使用流程图.png) 19 20HCS经过HC-GEN编译生成HCB文件,HDF驱动框架中的HCS Parser模块会从HCB文件中重建配置树,HDF驱动模块使用HCS Parser提供的配置读取接口获取配置内容。 21 22 23## 配置语法 24 25HCS的语法介绍如下: 26 27 28### 关键字 29 30HCS配置语法保留了以下关键字。 31 32 **表1** HCS配置语法保留关键字 33 34| 关键字 | 用途 | 说明 | 35| -------- | -------- | -------- | 36| root | 配置根节点 | - | 37| include | 引用其他HCS配置文件 | - | 38| delete | 删除节点或属性 | 只能用于操作include导入的配置树 | 39| template | 定义模板节点 | - | 40| match_attr | 用于标记节点的匹配查找属性 | 解析配置时可以使用该属性的值查找到对应节点 | 41 42 43### 基本结构 44 45HCS主要分为属性(Attribute)和节点(Node)两种结构。 46 47**属性** 48 49属性即最小的配置单元,是一个独立的配置项。语法如下: 50 51 52``` 53 attribute_name = value; 54``` 55 56- attribute_name是**字母、数字、下划线**的组合且必须以字母或下划线开头,字母区分大小写。 57 58- value的可用格式如下: 59 60 - 数字常量,支持二进制、八进制、十进制、十六进制数,具体参考[数据类型](#数据类型)章节。 61 - 字符串,内容使用双引号("")引用。 62 - 节点引用。 63 64- attribute必须以分号(;)结束且必须属于一个node。 65 66**节点** 67 68节点是一组属性的集合,语法如下: 69 70 71``` 72 node_name { 73 module = "sample"; 74 ... 75 } 76``` 77 78- node_name是**字母、数字、下划线**的组合且必须以字母或下划线开头,字母区分大小写。 79 80- 大括号后无需添加结束符“;”。 81 82- root为保留关键字,用于声明配置表的根节点。每个配置表必须以root节点开始。 83 84- root节点中必须包含module属性,其值应该为一个字符串,用于表征该配置所属模块。 85 86- 节点中可以增加match_attr属性,其值为一个全局唯一的字符串。当驱动程序在解析配置时可以以该属性的值为参数调用查找接口查找到包含该属性的节点。 87 88 89### 数据类型 90 91在属性定义中使用自动数据类型,不显式指定类型,属性支持的数据类型如下: 92 93**整型** 94 95 整型长度自动推断,根据实际数据长度给与最小空间占用的类型。 96- 二进制,0b前缀,示例:0b1010。 97 98- 八进制,0前缀,示例:0664。 99 100- 十进制 ,无前缀,且支持有符号与无符号,示例:1024,+1024均合法。驱动程序在读取负值时注意使用有符号数读取接口。 101 102- 十六进制,0x前缀,示例:0xff00、0xFF。 103 104**字符串** 105 106字符串使用双引号("")表示。 107 108**数组** 109 110数组元素支持整型、字符串,不支持混合类型。整型数组中uint32_t uint64_t混用会向上转型为uint64_t数组。整型数组与字符串数组示例如下: 111 112 113``` 114attr_foo = [0x01, 0x02, 0x03, 0x04]; 115attr_bar = ["hello", "world"]; 116``` 117 118**bool类型** 119 120bool类型中**true**表示真,**false**表示假。 121 122 123### 预处理 124 125**include** 126 127用于导入其他HCS文件。语法示例如下: 128 129 130``` 131#include "foo.hcs" 132#include "../bar.hcs" 133``` 134 135- 文件名必须使用双引号(""),不在同一目录使用相对路径引用。被include文件也必须是合法的HCS文件。 136 137- 多个include,如果存在相同的节点,后者覆盖前者,其余的节点依次展开。 138 139 140### 注释 141 142支持两种注释风格。 143 144- 单行注释。 145 146 147 ``` 148 // comment 149 ``` 150 151- 多行注释。 152 153 154 ``` 155 /* 156 comment 157 */ 158 ``` 159 160 > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br> 161 > 多行注释不支持嵌套。 162 163 164### 引用修改 165 166引用修改可以实现修改另外任意一个节点的内容,语法为: 167 168 169``` 170 node :& source_node 171``` 172 173 上述语句表示node中的内容是对source_node节点内容的修改。示例如下: 174 175``` 176root { 177 module = "sample"; 178 foo { 179 foo_ :& root.bar{ 180 attr = "foo"; 181 } 182 foo1 :& foo2 { 183 attr = 0x2; 184 } 185 foo2 { 186 attr = 0x1; 187 } 188 } 189 190 bar { 191 attr = "bar"; 192 } 193} 194``` 195 196最终生成配置树为: 197 198 199``` 200root { 201 module = "sample"; 202 foo { 203 foo2 { 204 attr = 0x2; 205 } 206 } 207 bar { 208 attr = "foo"; 209 } 210} 211``` 212 213在以上示例中,可以看到foo.foo_节点通过引用将bar.attr属性的值修改为了"foo",foo.foo1节点通过引用将foo.foo2.attr属性的值修改为了0x2。foo.foo_以及foo.foo1节点表示对目标节点内容的修改,其自身并不会存在最终生成的配置树中。 214 215- 引用同级node,可以直接使用node名称,否则被引用的节点必须使用绝对路径,节点间使用“.”分隔,root表示根节点,格式为root开始的节点路径序列,例如root.foo.bar即为一个合法的绝对路径。 216 217- 如果出现修改冲突(即多处修改同一个属性),编译器将提示warning,因为这种情况下只会生效某一个修改而导致最终结果不确定。 218 219 220### 节点复制 221 222节点复制可以实现在节点定义时从另一个节点先复制内容,用于定义内容相似的节点。语法为: 223 224 225``` 226 node : source_node 227``` 228 229上述语句表示在定义"node"节点时将另一个节点"source_node"的属性复制过来。示例如下: 230 231 232``` 233root { 234 module = "sample"; 235 foo { 236 attr_0 = 0x0; 237 } 238 bar:foo { 239 attr_1 = 0x1; 240 } 241} 242``` 243 244上述代码的最终生成配置树为: 245 246 247``` 248root { 249 module = "sample"; 250 foo { 251 attr_0 = 0x0; 252 } 253 bar { 254 attr_1 = 0x1; 255 attr_0 = 0x0; 256 } 257} 258``` 259 260在上述示例中,编译后bar节点即包含attr_0属性也包含attr_1属性,在bar中对attr_0的修改不会影响到foo。 261 262在foo和bar在同级node中可不指定foo的路径,否则需要使用绝对路径引用,参考[引用修改](#引用修改)。 263 264 265### 删除 266 267要对include导入的base配置树中不需要的节点或属性进行删除,可以使用delete关键字。下面的举例中sample1.hcs通过include导入了sample2.hcs中的配置内容,并使用delete删除了sample2.hcs中的attribute2属性和foo_2节点,示例如下: 268 269 270``` 271// sample2.hcs 272root { 273 attr_1 = 0x1; 274 attr_2 = 0x2; 275 foo_2 { 276 t = 0x1; 277 } 278} 279 280// sample1.hcs 281#include "sample2.hcs" 282root { 283 attr_2 = delete; 284 foo_2 : delete { 285 } 286} 287``` 288 289上述代码在生成过程中将会删除root.foo_2节点与attr_2,最终生成配置树为: 290 291 292``` 293root { 294 attr_1 = 0x1; 295} 296``` 297 298> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br> 299> 在同一个HCS文件中不允许使用delete,建议直接删除不需要的属性。 300 301 302### 属性引用 303 304为了在解析配置时快速定位到关联的节点,可以把节点作为属性的右值,通过读取属性查找到对应节点。语法为: 305 306 307``` 308 attribute = &node; 309``` 310 311上述语句表示attribute的值是一个节点node的引用,在解析时可以用这个attribute快速定位到node,便于关联和查询其他node。示例如下: 312 313 314``` 315node1 { 316 attributes; 317} 318node2 { 319 attr_1 = &root.node1; 320} 321``` 322 323或 324 325 326``` 327node2 { 328 node1 { 329 attributes; 330 } 331 attr_1 = &node1; 332} 333``` 334 335 336### 模板 337 338模板的用途在于生成严格一致的node结构,以便对同类型node进行遍历和管理。 339 340使用template关键字定义模板node,子node通过双冒号“::”声明继承关系。子节点可以改写或新增但不能删除template中的属性,子节点中没有定义的属性将使用template中的定义作为默认值。示例如下: 341 342 343``` 344root { 345 module = "sample"; 346 template foo { 347 attr_1 = 0x1; 348 attr_2 = 0x2; 349 } 350 351 bar :: foo { 352 } 353 354 bar_1 :: foo { 355 attr_1 = 0x2; 356 } 357} 358``` 359 360生成配置树如下: 361 362 363``` 364root { 365 module = "sample"; 366 bar { 367 attr_1 = 0x1; 368 attr_2 = 0x2; 369 } 370 bar_1 { 371 attr_1 = 0x2; 372 attr_2 = 0x2; 373 } 374} 375``` 376 377在上述示例中,bar和bar_1节点继承了foo节点,生成配置树节点结构与foo保持了完全一致,只是属性的值不同。 378 379 380## 配置生成 381 382hc-gen是配置生成的工具,可以对HCS配置语法进行检查并把HCS源文件转化成HCB二进制文件。 383 384 385### hc-gen介绍 386 387hc-gen参数说明: 388 389 390``` 391Usage: hc-gen [Options] [File] 392options: 393 -o <file> output file name, default same as input 394 -a hcb align with four bytes 395 -b output binary output, default enable 396 -t output config in C language source file style 397 -m output config in macro source file style 398 -i output binary hex dump in C language source file style 399 -p <prefix> prefix of generated symbol name 400 -d decompile hcb to hcs 401 -V show verbose info 402 -v show version 403 -h show this help message 404``` 405 406生成.c/.h配置文件方法: 407 408 409``` 410hc-gen -o [OutputCFileName] -t [SourceHcsFileName] 411``` 412 413生成HCB配置文件方法: 414 415 416``` 417hc-gen -o [OutputHcbFileName] -b [SourceHcsFileName] 418``` 419 420生成宏定义配置文件方法: 421 422 423``` 424hc-gen -o [OutputMacroFileName] -m [SourceHcsFileName] 425``` 426 427反编译HCB文件为HCS方法: 428 429 430``` 431hc-gen -o [OutputHcsFileName] -d [SourceHcbFileName] 432``` 433