编辑语:
技术解码栏目:是面向开发者详细解读芯片开放社区(OCC)上关于处理器、芯片、基础软件平台、集成开发环境及应用开发平台的相关技术,方便开发者学习及快速上手,提升开发效率。
01 前言
本文是YoC YAML语法规范介绍的下篇,在上篇中,我们带大家简单了解了YoC YAML语法,并重点对YAML语法进行了分类,最后以KV组件为例,讲解了YoC如何利用YAML脚本对KV组件进行管理,并分别对脚本里的六个部分作了介绍。
本文将承接上文,对YoC YAML语法规范作进一步详细描述和解释,为开发者用户在组件管理上提供帮助。
02 YoC YAML语法
2.1.组件定义
组件是完成某项特定功能的软件库,可以向开发者提供调用API,来满足应用需求。组件由软件描述信息、源代码或者库文件构成。
组件目录结构中必须包含下述文件:
- 说明文档:README.md
- 描述文件:package.yaml
2.1.1 说明文档
README.md 文件要介绍清楚该组件的功能以及特色,包含组件快速使用的方法,以及简单的示例代码。参考模板如下:
# 概述 # 组件安装 # 接口 # 示例 # 运行资源
2.1.2 描述文件
## 第一部分:基础信息 name: helloworld # <必选项> 包名称 (符合C语言变量命名规则),长度少于等于64字节 description: 简洁直白用一句完成组件介绍 # <必选项> 建议至少20字以上 version: v7.3.0 # <必选项> 组件版本号 type: common # <必选项> 组件类型,为:solution, chip, board, common tag: 通用组件 # <可选项> 组件分类,缺省值:'' keywords: # <可选项> 标签,会影响到组件被搜索的效果,合理的标签很重要 【目前铁三角没有用到】 - base - XML author: # <可选项> 原作者信息 name: Dave Gamble (original author), Max Bruckner (current maintainer) license: MIT # <可选项> 源代码的许可证,要确保所有代码、文件的许可证不冲突。如: # GPLv2,LGPLv2.1,MIT,Apache license v2.0,BSD # 默认值: Apache license v2.0 homepage: https://www.t-head.cn ## 第二部分:依赖信息 # 指定该组件依赖的组件及版本,版本支持条件比较,支持:>=v1.0, >v1.0, ==v1.0, <=v1.0, <v1.0, v1.0 # 未指定条件时,默认为 ==,如 v1.0 与 ==v1.0 # depends: # <可选项> 该组件依赖其他的组件,合理的依赖才能保证组件能编译、使用 # - minilibc: v7.2.0 # - aos: >= v7.2.0 depends: - minilibc: v7.2.0 - aos: >= v7.2.0 # YOC:表示使用当前版本以上的最新版本 (此项待定) # 指定当前solution可以使用的sdk组件及版本, sdk_chip关键字只能出现在solution类型组件package.yaml里 sdk_chip: - sc5654_platform: v7.2.0 - cb2201_platform: v7.2.0 # YOC:表示使用当前版本以上的最新版本 (此项待定) ## 第三部分:板级信息 # hw_info: # 对 solution、board、chip 三个字段的改进,统称为 hw_info 字段 # cpu_id: cpu0 # cpu_name: CK804EF # vendor_name: t-head # chip_name: csi_pangu # <可选项> 指定芯片组件名,未设置时,使用depends中 chip 第一个组件 # board_name: pangu_cpu0 # <可选项> 指定开发板组件名,未设置时,使用depends中 board 第一个组件 # ld_script: configs/gcc_eflash.ld # <可选项> 连接时使用 LD 脚本,当选把未设置时,使用对应的 board 的 LD 脚本 # flash_program: bin/flash_program.elf # <可选项> 芯片全局烧写程序 # cpu0: # cpu_name: CK804EF # <必选项> 该芯片使用的 CPU 型号 # ld_script: configs/gcc_eflash.ld # <必选项> 连接时使用 LD 脚本 # flash_program: bin/flash_program.elf # <可选项> 该CPU对应烧写程序,未指定时使用全局烧写程序 # cpu1: # cpu_name: CK804EF # <必选项> 该芯片使用的 CPU 型号 # ld_script: configs/gcc_eflash.ld # <可选项> 连接时使用 LD 脚本 # flash_program: bin/flash_program.elf # <可选项> 该CPU对应烧写程序,未指定时使用全局烧写程序 ## solution component # hw_info: # cpu_id: cpu0 # board_name: pangu_cpu0 # cpu_name: CK805EF # vendor_name: t-head # chip_name: 'csi_pangu' # ld_script: configs/gcc_eflash.ld.S ## board component # hw_info: # chip_name: csi_pangu # ld_script: configs/gcc_eflash.ld ## chip component (单处理器) # hw_info: # cpu_name: CK804EF # ld_script: configs/gcc_eflash.ld # flash_program: bin/flash_program.elf ## chip component(多处理器) # hw_info: # cpu0: # cpu_name: CK804EF # <必选项> 该芯片使用的 CPU 型号 # ld_script: configs/gcc_eflash.ld # <必选项> 连接时使用 LD 脚本 # flash_program: bin/flash_program.elf # <可选项> 该CPU对应烧写程序,未指定时使用全局烧写程序 # cpu1: # cpu_name: CK804EF # <必选项> 该芯片使用的 CPU 型号 # ld_script: configs/gcc_eflash.ld # <必选项> 连接时使用 LD 脚本 # flash_program: bin/flash_program.elf # <可选项> 该CPU对应烧写程序,未指定时使用全局烧写程序 # flash_program: bin/flash_program.elf # <可选项> 芯片全局烧写程序 hw_info: cpu_name: CK804EF # 大小写不敏感 ld_script: configs/gcc_eflash.ld ## 第四部分:编译连接信息 # build_config: # <可选项> 编译配置项 # include: # <可选项> 编译时,影响编译器的-I 参数 ,全局有效 # - src # include 只能是该软件包下的目录,不能使用外部目录 # internal_include: # <可选项> 编译时,影响编译器的-I 参数 ,组件内有效 # - include # cflag: '' # <可选项> C 编译器所需要要的编译参数 # cxxflag: '' # <可选项> CXX 编译器所需要要的编译参数 # asmflag: '' # <可选项> 汇编器所需要要参数 # define: # <可选项> 宏定义, 增加编译器的-D 选项,如: # XXX: 1 # -DXXX=1 # AAA: 1 # -DAAA # STR: "abc" # -DSTR=\"abc\" # libs: # 该组件中支持的二进制静态库,如:libxxx.a, libyyy.a # - xxx # -lxxx # - yyy # -lyyy # libpath: # 指定静态库所在的路径(相对于该组件路径) # - libs # -Llibs build_config: include: - src internal_include: - include ## source_file: # <可选项> 指定参与编译的源代码文件,支持通配符,采用相对路径 # - src/*.c # 例:组件 src 目录下所有的扩展名为 c 的源代码文件 source_file: - src/*.c ## 第五部分:配置信息 # def_config: # 组件的可配置项 # CONFIG_DEBUG: y # CONFIG_PARAM_NOT_CHECK: y # CONFIG_CLI: y def_config: CONFIG_DEBUG: y CONFIG_PARAM_NOT_CHECK: y CONFIG_CLI: y ## 第六部分:安装信息 # 注意:该字段在后续使用中会越来越少,甚至会被弃用。所以不建议使用。 # install: # - dest: include/ # 安装的目的路径 dest是相当路径,通常是相对于YoC SDK 安装目录 # source: # 安装源列表 # - src/*.h # 支持通配符,相对路径 install: - dest: include/ source: - src/*.h ## 第七部分:导出部分 export: - dest: <SOLUTION_PATH>/generated/data # 导出来到指定的位置 source: - bootimgs/boot - bootimgs/tee - configs/config.yaml
2.1.3 存储约定
为了保证 package.yaml文件的可读性与简约性,对 package.yaml文件的存储制定如下约定:
- 字段的存储顺序与模板一致,保留模板的注释说明,数据与DICT 按读入时顺序保存 < 优选项>;
- 默认值为空时,字段不出现在文件中 <优选项>;
- 字符串不使用引号,除语法要求外 <优选项>;
- 缩进采用两个空格字符 < 强制项>;
- 一级字段之间增加一行空行,二级及以下字段不使用空行,第一部分基础信息一级字段间不使用空行 < 优选项>;
2.2 硬件信息
字段 hw_info 用于配置该组件对硬件的依赖,该字段用于 chip、board、solution三种类型的组件中, common 类型该字段定义无效。
2.2.1 chip组件
chip 组件中hw_info包含:
- cpu_name: CPU 名字,例:'ck801', 'ck802', 'ck803', 'ck805', 'ck803f', 'ck803ef', 'ck803efr1', 'ck804ef', 'ck805f', 'ck805ef', 'cortex-m0';
- vendor_name: 芯片的供应商名;
- arch_name: 芯片架构名称,例如:'arm', 'csky';
- ld_script: 该芯片应用编程默认使用的连接器脚本文件;
- flash_program: 芯片 FLASH 烧写程序;
- toolchain_prefix: 编译器前缀,例如:csky-abiv2-elf,可以选项,未指定时,根据 cpu_name 来推断编译器前缀。
2.2.2 board组件
board 组件的hw_info 字段包含:
- chip_name: 该开发板组件对应的芯片组件的名字,该字段是可选项;
- ld_script: 使用该开发板的默认连接脚本,可选项,如果未指定,默认使用所依赖的 chip_name 组件的 ld_script 文件。
# board component hw_info: chip_name: csi_pangu # <可选项> 指定芯片组件名,未设置时,使用depends中 chip 第一个组件 ld_script: configs/gcc_eflash.ld # <可选项> 连接时使用 LD 脚本,当选把未设置时,使用对应的 board 的 LD 脚本
2.2.3 solution组件
solution 组件的hw_info 字段包含:
- board_name: 该solution 组件使用的开发板组件名字;
- chip_name:指定 solution组件使用的 chip 组件,未指定时,使用 board_name 指定的 board 组件 hw_info 指定的 chip 组件;
- cpu_id: 当该方案使用的芯片上有多个异构CPU时,指定对应的 CPU 配置;
- cpu_name: 未指定时,使用 chip 组件的 cpu_name;
- ld_script: 使用该solution 组件指定的连接脚本,未设置时,按 board、chip 组件依赖查找 到 ld_script 配置,当 cpu_id 与 cpu_name、ld_script 同时指定时, cpu_name、ld_script 优先于 cpu_id;
- flash_program: 芯片 FLASH 烧写程序;
- toolchain_prefix: 编译器前缀,例如:csky-abiv2-elf,可以选项,未指定时,根据 cpu_name 来推断编译器前缀。
2.3 组件配置
组件可以定义一组配置项def_config,配置项在全工程内有效,示例:
def_config: CONFIG_DEBUG: 1 CONFIG_ARCH_CSKY: 1 CONFIG_PARAM_NOT_CHECK: 1 CONFIG_CLI: 1 CONFIG_NETMGR_WIFI: 1
配置采用 Key-Value 形式,该配置通过C语言宏的方式定义,Key 为宏名,Value 为宏的值,Value 符合 yaml 标准的类型,可以是字符串、数值、布尔型,如:
def_config: CONFIG_DEBUG: true CONFIG_INT: 1 CONFIG_STR: "abc"
对应的C代码形式:
#define CONFIG_DEBUG 1 #define CONFIG_INT 1 #define CONFIG_STR "abc"
对应GCC 命令行参数: -DCONFIG_DEBUG=1 -DCONFIG_INT=1 -DCONFIG_STR=\"abc\" 每个组件都可以定义自己的配置项,组件内的配置项为该配置项的默认值。当 common 组件、chip 组件、board 组件、solution 组件都存在相同配置时,优先顺序为 :solution > board > chip > common
2.4 变量
在编译工程中,组件配置及内置的会产生出配置变量,在 package.yaml 中,可以使用配置变量来动态指定,变量使用方式为<变更名>, 例如:
# 根据 CPU 类型,使用不同的静态库 build_config: libs: - mqtt libpath: - libs/<cpu> # 或者 build_config: libs: - mqtt-<cpu> libpath: - libs
# 根据 chip 及cpu,编译不同的源代码 source_file: - src/<chip>/<cpu>/*.c
# 根据配置变量选择不同的源代码 # <ver>/*.c ? <condition> # 当 <condition>值为 'Y', 'YES', 'OK', '1', 'True'时,该选择有效 source_file: - src/<chip>/<cpu>/*.c ? <CONFIG_DEBUG>
2.4.1 内置变量
- : 大写 cpu arch 型号;
- : 小写 cpu arch 型号;
- : CPU型号的数字, rsicv 对应是rv32;
:CK保持原定义,型号的数字;RISCV对应不再全部是RV32,而是如下对应表项:剑池CDK V2.6.9其以后的版本中实现。
e902 | riscv/rv32_16gpr |
e902m | riscv/rv32_16gpr |
e902t | riscv/rv32_16gpr |
e902mt | riscv/rv32_16gpr |
e906 | riscv/rv32_32gpr |
e906F | riscv/rv32f_32gpr |
e906FD | riscv/rv32fd_32gpr |
c906 | riscv/rv64_32gpr |
c906fd | riscv/rv64fd_32gpr |
c906v | riscv/rv64fd_32gpr |
c906fdv | riscv/rv64fd_32gpr |
c910 | riscv/rv64fd_32gpr |
c910v | riscv/rv64fd_32gpr |
其他RV处理器 | rv32 |
- : CPU指令架构 小写 'csky', 'rsicv','arm';
- : CPU指令架构 大写 'CSKY', 'RSICV','ARM';
- : 芯片供应商大写;
- : 芯片供应商小写;
- : 芯片名字大写;
- : 芯片名字小写;
- : 开发板名字大写;
- : 开发板名字小写;
- 开发板组件所在路径;
- 芯片组件所在路径;
- 方案组件所在路径;
2.4.2 配置项变量
组件配置项也会生成同名的变量,例如:
def_config: CONFIG_DEBUG: 1 CONFIG_ARCH_CSKY: 1 CONFIG_PARAM_NOT_CHECK: 1
增加变量:<CONFIG_DEBUG>=1、<CONFIG_ARCH_CSKY>=1、<CONFIG_PARAM_NOT_CHECK>=1
2.5 组件分类
根据组件的特点,分为以下4种类型组件:
- solution:方案组件
- board:开发板组件
- chip:芯片驱动组件
- common:通用组件
2.5.1 board类型组件
提供芯片开发板的管脚配置、初始化函数、二进制数据等,该组件可以生成库文件
hw_info: # <过时配置> 当 type 为 board,该字段为 board 相关配置 chip_name: csi_pangu # 该开发板使用的芯片组件名 ld_script: configs/gcc_eflash.ld # <可选项> 连接时使用 LD 脚本,当选把未设置时,使用对应的 board 的 LD 脚本
说明:
- board 组件的 hw_info 组件,需要包含该组件对应的芯片组件名,即设置 ``hw_info.chip_name `字段;
- ld_script 字段可以缺省,未指定 ld_script 时,使用所依赖的芯片的 hw_info.ld_script。
2.5.2 chip类型组件
提供芯片的 CSI 驱动功能,该组件可以生成库文件
hw_info: # <过时配置> 当 type 为 board,该字段为 board 相关配置 cpu_name: CK804EF # <必选项> 该开发板使用的芯片组件名 ld_script: configs/gcc_eflash.ld # <可选项> 连接时使用 LD 脚本,当选把未设置时,使用对应的 board 的 LD 脚本 ... build_config: # <必选项> 编译配置项 cflag: > -nostdlib -mistack -Wpointer-arith -Wundef -Wall -Wl,-EL -ffunction-sections -fdata-sections -fno-inline-functions -fno-builtin -fno-strict-aliasing -fno-strength-reduce
说明:
- hw_info.cpu_name 对应的CPU名称:CK801, CK802, ck803, CK805, CK803F, CK803EF, CK803EFR1, CK804EF, CK805F, CK805EF, RV32EMC;
- hw_info.ld_script: 该字段需要指定该芯片默认支持的连接脚本;
- build_config.cflag: 指定该芯片对应的编译器所需要的基础参数,该参数通常为 YoC 默认参数。
2.5.3 solution类型组件
能够生成二进制执行程序的组件,还包含 FLASH 分区、BOOT、resource 等资源,该组件可以生成 FLASH IMAGE包、烧录FLASH。
hw_info: # 对 solution、board、chip 三个字段的改进,统称为 hw_info 字段 board_name: pangu_cpu0 # <可选项> vendor_name: t-head # <可选项> chip_name: csi_pangu # <可选项> cpu_name: CK804EF # <可选项> ld_script: configs/gcc_eflash.ld # <可选项>
对于 solution 组件,工程编译时,需要有cpu_name 与ld_script 字段,该字段可以在 solution 组件、board 组件、chip 组件中获取。当 solution、board、chip 三个组件中都存在相同字段时,按 solution 优先于 board,board 优化于 chip 规则。即:
- 当solution 中定义了 hw_info.ld_script时,工程连接时使用 solution.hw_info.ld_script,board 与 chip 的 hw_info.ld_script 无效。
- 当 solution 的hw_info.ld_script未定义时,根据 hw_info.board_name找到对应的 board 组件,连接脚本取 board 组件的、hw_info.ld_script 值,当 board 组件的hw_info.ld_script 不存在时,根据 board 组件的 hw_info.chip_name 到对应的芯片组件,取芯片组件的hw_info.ld_script 对应的文件作为连接脚本。
- 根据以上优先规则,获取到 ld_script 后,如果对应的文件不存时,编译错误,无需要再按优化顺序取下一个 ld_script 文件。
2.5.4 common类型组件
不符合 solution 、board、chip 三种类型的组件,统称为 common 组件,common 组件通常为独立的第三方软件包,也可以是针对具体芯片的专用软件包。
2.6 组件编译选项作用域
- common 组件的编译选项 cflag、cxxflag、asmflag 为私有定义,只对该组件有效。
- solution/chip/board 组件的编译选项 cflag、cxxflag、asmflag 为全局定义,对整个工程有效。