2.4. Nuclei Studio NPK 介绍
在芯来RISC-V嵌入式软件开发里面引入组件(Package)的理念,主要是借鉴于npm包管理,开发出方便开发者开发,使用,分发设计好的软件组件,可以大大加快软件的迭代速度。
组件包主要由以下文件组成:
组件描述文件(基于YAML语言):
npk.yml
组件相关代码以及说明文档
组件包会以zip包形式存在,组件包在导入使用时,需要被IDE或者其他工具进行包完整性以及可用性检查,才予以导入。
Note
我们提供了一个开源的NPK软件包检查工具,参见 https://github.com/Nuclei-Software/npk-checker
最好的NPK软件包参考项目可以参见 Nuclei SDK 以及其他线上的软件包(搜索 npk.yml 文件) https://www.rvmcu.com/nucleistudio-npk.html
组件包后期会提供签名机制,在发布前先签名,然后导入软件包会验证签名,确保导入的开发包是合法身份发布,不导入不可信的开发包。
2.4.1. 组件描述文件(npk.yml)
组件主要分为以下几大类型,分别是:
csp: Core Support Package, 例如NMSIS
ssp: SoC Support Package, 例如gd32vf103的SoC的支持包
bsp: Board Support Package,例如rvstar开发板板级支持的代码包
osp: RTOS Support Package, 例如各类RTOS支持包
app: Application Package,例如各类上层应用
mwp: Middleware Package,各类第三方中间件,例如语音识别,算法库之类的
sdk: Software Development Kit,一组预设定好的软件开发包,一般情况下里面会包含了CSP, SSP, BSP, APP类型的包,OSP和MWP类型的包可选加入
bdp: Bundle Package, 一组package,目前仅对app有效
以下是比较特殊的类型,主要用于工具包和模版包
tool: Tool Package,各类工具组件包,可放入其他需要引用或参考的文件
tpp: Template Package, 模板类型,可以用于创建csp/ssp/bsp/osp/app/mwp/sdk的模板工程,该类型比较特殊,描述文件名称为 npk_template.yml
2.4.1.1. 描述文件通用定义
组件描述文件示例以及详细说明参见如下:
Package Base Information
--------------------------
name: your_package_name # <MUST> 组件包名称ID,不要有空格,符合C语言命名规范,英文名称,唯一名称ID,用于dependency管理
# name命名规则:唯一性,全英文,不支持特殊字符
# csp类型package: csp-xxxx
# ssp类型package: ssp-xxxx
# bsp类型package: bsp-xxxx
# osp类型package: osp-xxxx
# app类型package: app-xxxx
# mwp类型package: mwp-xxxx
# sdk类型package: sdk-xxxx
# tpp类型package: tpp-xxxx
# tool类型package: tool-xxxx
description: 简要描述软件包的功能 # <MUST> 一句话描述清楚包的主要特性与功能, English only, 20字符以内
details: 详细描述软件包的功能 # <MUST> 描述清楚包的主要特性与功能, English only
version: 1.2.3 # <OPTIONAL> 可选,如不填,默认为空,建议采用SEMVER2.0版本号管理,只能数字打头, 例如1.2.3
# <MUST> 针对sdk类型的package必须包含一个version tag
type: ssp # <MUST> 包类型, 可选类型有csp, ssp, bsp, osp, app, mwp, sdk, tpp, tool
os: win64 # <MUST> OS类型,例如win32、win64、lin64、lin32,但目前组件包上传页面只支持win64和lin64,该字段只存在tool类型package
category: # <OPTIONAL> 包分类,按照上面的包类型进行二次分类,主要是针对package进行分类
keywords: # <MUST> 包关键字,主要用于索引与搜索
- soc
- risc-v
- nuclei
license: Apache-2.0 # <OPTIONAL> 对应包代码所用的许可证,可选列表 GPL, GPLv2, MIT, Apache License v2, BSP等
owner: nuclei # <MUST> 组件包的拥有者,便于后期进行权限查找匹配
# 后期在整合到网站以后,用户在发布新的开发包的时候,需要先注册一个唯一的owner名称
# 然后申请一个package name,确保name可用的情况下才可以发布新的该name的包,同时限制单用户发布的包个数。
contributors: # <OPTIONAL> 组件包的代码贡献者列表
- author_name, author_email
homepage: # <OPTIONAL> 组件包的主页, 如果有的话,必须是链接
## Package Information
-----------------------
packinfo: # <MUST> Only for bsp/ssp type, optional for other types 用于描述SoC层面的一些信息
core_vendor: Nuclei # <MUST> only for ssp, 处理器内核的供应商英文名称,如果是基于芯来的处理器内核,这里填写Nuclei
vendor: Nuclei # <MUST> For ssp/bsp, <OPTIONAL> for others
# For ssp, SoC或者芯片的供应商英文名称,填写对应的厂商的名称,例如 GigaDevice
# For bsp, 表示板子的提供商英文名称
# For others, OPTIONAL, 表示该package提供商
name: demosoc # <MUST> 这里name和package name作用不一样, 用来显示具体的包名称
# For ssp, 表示本组件包中SoC的具体英文名称,可以是一个系列名称,例如GD32VF103
# For bsp, 板子的名称
# For others, 表示该package显示名称,中英文均可,不写的话,默认使用根字段name
doc: # <OPTIONAL>, 不填的话,这里为空,不做展示
website: # <OPTIONAL>, Package对应的网站
sch: # <OPTIONAL> only for bsp, 表示板子的电路图
datasheet: # <OPTIONAL>, package datasheet 本地地址或者是网址
usermanual: # <OPTIONAL>, Package User Manual
extra: # <OPTIONAL>, 额外的一些资料,列表形式(URI + DESCRIPTION)
- uri: # <OPTIONAL>, file path or web link
description: # <MUST> when uri is defined, description for file
## Package Dependency
----------------------
dependencies: # <OPTIONAL> 列出依赖的组件包列表 owner/name:version
- name: csp-nsdk_nmsis # <MUST> when defined # 1. 针对sdk类型的包,内部有一个隐形的依赖,依赖有且仅有一个bsp类型的包,
owner: nuclei # <OPTIONAL> if not defined, it will use the owner definiton above. 用于依赖特定所有者的package, owner/name:version, 最终查找的包按照这样来找的
version: # <OPTIONAL> when defined empty, use default as version number # 并且会自动查找当前路径下所有的npk.yml文件,并作为sdk包中一部分
# 2. 除了sdk类型的包之外的其他的包,如果不是放在sdk包下面的目录,则依赖于
# sdk,则需要显式加上dependency
# 3. bsp类型的package肯定会依赖一个ssp类型的package
# 4. 依赖包也可以带上版本号,支持版本号条件比对, 如果不带版本号,则优先选择不带版本号的包,其次最新的包
# 参考 https://docs.platformio.org/en/latest/librarymanager/config.html#version
# https://docs.npmjs.com/about-semantic-versioning
# 1.2.3 - an exact version number. Use only this exact version
# ^1.2.3 - any compatible version (exact version for 1.x.x versions
# ~1.2.3 - any version with the same major and minor versions, and an equal or greater patch version
# >1.2.3 - any version greater than 1.2.3. >=, <, and <= are also possible
# >0.1.0,!=0.2.0,<0.3.0 - any version greater than 0.1.0, not equal to 0.2.0 and less than 0.3.0
# 例如 version: master, version: 1.2.3, version: >0.1.0
# 依赖关系处理规则
# 1. sdk,app类型的包可以依赖多个ssp、bsp类型的包,但是最终只会根据project wizard选择具体使用到package
# 2. app/bsp/ssp/csp/osp/mwp类型的包可以依赖sdk,如果依赖了sdk类型的包,则表述该包隶属于sdk下
# 3. bsp类型的包只能依赖一个ssp/csp类型的包,ssp类型的包只能依赖一个csp类型的包
# 4. sdk类型的包可以依赖多个app/bsp/ssp/csp/osp/mwp类型,但是这种依赖只是建立从属关系,表示该sdk包含了这些包
# 5. 一个sdk类型的包不可以依赖另一个sdk包,但是app/bsp/ssp/csp/osp/mwp却可以依赖多个sdk类型的包
## Package Configurations
--------------------------
configuration: # <OPTIONAL> 关于包配置的一些选项,用于Project Wizard创建以及内部参数设置
# 其中sdk类型暂不支持configuration参数定义
# configuration定义的配置可以互相覆盖
# 覆盖规则为 app > mwp > osp > bsp > ssp > csp
nuclei_core: # <OPTIONAL> 一个配置选项,类型为choice
default: n307fd # <MUST> 如果这个配置定义了,针对choice类型,默认值选择必须是choices里面列举的
type: choice # <MUST> 配置类型,可选有choice, list, checkbox, multicheckbox,text
global: true # <OPTIONAL> 可选为true或者false,默认为true
description: Nuclei RISC-V Core # <MUST> 该配置项的描述,20字以内
choices: # <MUST> 当配置项type == choice时
- name: n201 # <MUST> item中必须包含name和description
arch: rv32iac # <OPTIONAL> 仅用于表示RISC-V CORE中的ARCH信息,不建议随意使用
abi: ilp32 # <OPTIONAL> 仅用于表示RISC-V CORE中的ABI信息,不建议随意使用
tune: # <OPTIONAL> 仅用于表示RISC-V CORE中的TUNE信息,不建议随意使用
info: # <OPTIONAL> 用于自定义key-value数据的访问,例如 ${nuclei_core.info.key1} 返回的是 value1
- name: key1 # <MUST> key in pair with value, 字符串类型,不包含任意空格
value: value1 # <MUST> value in pair with key,字符串类型
- name: key2 # <MUST>
value: value2 # <MUST>
description: N201 Core(ARCH=rv32iac, ABI=ilp32) # <MUST> 描述这个item具体含义
# 除了name, description之外,可能会定义其他items, 名称不定
# 例如在这里就定义了 arch和abi
- name: n201e # 另一个item
arch: rv32eac
abi: ilp32e
description: N201E Core(ARCH=rv32eac, ABI=ilp32e)
extra_flags: # <OPTIONAL> 一个配置选项, 当前这个为text类型
value: # <MUST>, 仅接受英文字符串
description: Extra compiler flags # <MUST> 该配置项的描述,30字以内
dsp_present: # <OPTIONAL> 一个配置选项, 当前这个为checkbox类型
default: 0 # <MUST>, 默认为0,可选0或者1
type: checkbox # <MUST>, 配置类型,当前为checkbox
global: true # <OPTIONAL> 可选为true或者false,默认为true
description: P-Extension(DSP) Present # <MUST> 该配置项的描述,30字以内
libraries: # <OPTIONAL> 一个配置选项,当前这个为multicheckbox类型
default: [dsp, nn] # <MUST> 默认值, 为choices里面的组合
type: multicheckbox # <MUST>, 配置类型,当前为multicheckbox
global: true # <OPTIONAL> 可选为true或者false,默认为true
description: Libraries Used # <MUST> 该配置项的描述,30字以内
choices: # <MUST> 当配置项type == multicheckbox时
- name: dsp # <MUST> item中必须包含name和description
description: DSP Library # <MUST> 描述这个item具体含义
# 除了name, description之外,可能会定义其他items, 名称不定
- name: nn
description: NN Library
- name: ai
description: AI Library
## Source Code Management
-------------------------
codemanage: # <MUST> 这个为必选项
installdir: demosoc # <MUST> 希望代码安装的目录名称,仅限英文,满足C语言命名格式
# 针对sdk类型的package,会被安装到<sdk_installdir>, 如果installdir未定义,默认为SDK,如果没有任何sdk类型的package被引用,sdk_installdir也被默认设置为SDK
# 针对csp类型的package,会被安装到<sdk_installdir>/<csp_installdir>目录下,TBD
# 针对ssp类型的package,会被安装到<sdk_installdir>/SoC/<ssp_installdir>/Common下面
# 针对bsp类型的package,会被安装到<sdk_installdir>/SoC/<ssp_installdir>/Board/<bsp_installdir>下面,如果不依赖于任何ssp类型,则安装到<sdk_installdir>/BSP/<bsp_installdir>
# 针对osp类型的package,会被安装到<sdk_installdir>/OS/<osp_installdir>下面
# 针对app类型的package,会被安装到<app_installdir>/目录下, 如果installdir未定义,默认为application
# 针对mwp类型的package,会被安装到<sdk_installdir>/Components/<mwp_installdir>目录下
copyfiles: # <MUST>待拷贝的文件或者文件夹,支持glob pattern匹配,这里是指所有的目录或者文件
- path: ["Source/", "Include/", "demosoc.svd"] # <MUST>待拷贝的文件或者文件夹的路径列表,支持glob pattern匹配
- path: ["DSP_Source", "DSP_Include"]
condition: $( ${dsp_present} == 1 ) # <OPTIONAL> 这里的if 是一个固定的标识符,如果出现则表示要做判定,判定的方式如下
# 如dsp_present是在configuration里面定义的,根据wizard或者其他package选定而定
incdirs: # <OPTIONAL> 需要加入头文件目录列表
- path: ["Include/"] # <OPTIONAL> 需要加入头文件的目录
libdirs: # <OPTIONAL> 可选的lib库所在目录
- path:
ldlibs: # <OPTIONAL> 可选的需要链接的库
- libs:
## Set Configuration for other packages
----------------------------------------
setconfig: # <OPTIONAL> 这个用于设置其他Package的选项
# 以下选项是覆盖关系,规则app > mwp > osp > bsp > ssp > csp
- config: nmsislibarch
value : ${nuclei_core.arch}p # <OPTIONAL> 直接设置Configuration里面的选项
condition: $( ${dsp_present} == 1 ) # <OPTIONAL> 根据这里dsp_present来判断是否设置nmsislibarch值
- config: nmsislibarch
value: ${nuclei_core.arch}
condition: $( ${dsp_present} == 0 )
## Build Configuration
-----------------------
buildconfig: # <OPTIONAL> 编译选项的配置
# 目前编译选项会将package中定义的所有的拼接在一起或者覆盖
# 以下选项是覆盖方式,app > mwp > osp > bsp > ssp > csp
# type是一个特殊字段,用于标识特定的编译器, 目前支持gcc
# cross_prefix, prebuild_steps, postbuild_steps, description
# 其余选项是拼接的
- type: gcc # <OPTIONAL> 目前只有gcc,预留其他接口
description: Nuclei GNU Toolchain # <MUST> For ssp
cross_prefix: riscv-nuclei-elf- # <OPTIONAL> 如果不写或者留空,就自动按照系统里面提供的工具链来定
common_flags: # <OPTIONAL> 通用的编译选项,将会添加到cflags, asmflags, cxxflags上
- flags: -g -fno-common -ffunction-sections -fdata-sections
- flags: -march=${nuclei_core.arch} -mabi=${nuclei_core.abi} -mcmodel=medany
ldflags: # <OPTIONAL> 链接选项列表,留空表示没有任何选项
- flags: -nostartfiles --specs=nosys.specs
- flags: --specs=nano.specs
condition: $(${newlib} != "normal")
- flags: -u _printf_float
condition: $(${newlib} != "nano_with_printfloat")
- flags: -u _isatty -u _write -u _sbrk -u _read -u _close -u _fstat -u _lseek
linkscript: # <MUST> 链接脚本的定义,必须在bsp/ssp中定义
- script: "Source/GCC/gcc_demosoc_${.download}.ld"
condition: $(check pattern) # <OPTIONAL> 进行条件判断
cflags: # <OPTIONAL> C编译选项,留空表示没有任何选项
- flags: -O3
asmflags: # <OPTIONAL> ASM编译选项,留空表示没有任何选项
- flags: -O2
cxxflags: # <OPTIONAL> CXX编译选项,留空表示没有任何选项
- flags: -O1
common_defines: # <OPTIONAL> 通用的宏定义
- defines: __RISCV_FEATURE_DSP=1
condition: $(${dsp_present} == 1)
- defines: DOWNLOAD_MODE_STRING=\"flashxip\"
cdefines: # <OPTIONAL> C的宏定义
- defines: __RISCV_FEATURE_DSP=1
condition: $(${dsp_present} == 1)
- defines: DOWNLOAD_MODE_STRING=\"flashxip\"
asmdefines: # <OPTIONAL> ASM的宏定义
- defines: __RISCV_FEATURE_DSP=1
condition: $(${dsp_present} == 1)
- defines: DOWNLOAD_MODE_STRING=\"flashxip\"
cxxdefines: # <OPTIONAL> CXX的宏定义
- defines: __RISCV_FEATURE_DSP=1
condition: $(${dsp_present} == 1)
- defines: DOWNLOAD_MODE_STRING=\"flashxip\"
prebuild_steps: # <OPTIONAL> 编译前执行的命令
command: # <OPTIONAL> 执行的命令行
description: # <OPTIONAL> 执行的命令的描述
postbuild_steps: # <OPTIONAL> 编译完成后执行的命令
command: # <OPTIONAL> 执行的命令行
description: # <OPTIONAL> 执行的命令的描述
## Debug Configuration
------------------------
debugconfig: # <MUST> For bsp type, optional for app/ssp type
# 目前Debug选项会将package中定义的所有的拼接在一起或者覆盖
# type是一个特殊的字段,用于描述特定的调试器,目前支持openocd, qemu
# 以下字段是覆盖关系:app > mwp > osp > bsp > ssp > csp
# description, svd
# configs字段下面的key, value是合并关系,如果对应的key存在就覆盖,覆盖规则同上,如果不存在就合并
- type: openocd # <MUST> 选择的工具
description: Nuclei OpenOCD # <MUST> For bsp type
svd: gd32vf103.svd # <OPTIONAL> 可选的SVD文件
configs:
- key: config # openocd配置文件
value: "openocd_gd32vf103.cfg"
- type: qemu
description: Nuclei QEMU
svd:
configs:
- key: nuclei_core # Nuclei RISC-V Core
value: ${nuclei_core}
condition: # condition set nuclei_core key
- key: download_mode # Download mode
value: ${download_mode}
- key: riscv_arch # RISCV ARCH
value: ${nuclei_core.arch}
- key: riscv_abi # RISCV ABI
value: ${nuclei_core.abi}
- key: machine # QEMU Machine
value: gd32vf103v_rvstar
##Extended variable
## Only works on tool类型
## 每个包存在一个包路径,引用为npk名称-版本号,例如${tool-cmlink-1.0.0},
## 其他变量的引用为npk名称-版本号-变量名,例如 ${tool-cmlink-1.0.0-proxy}
environment: # 扩展变量
- key: proxy # 变量名,
value: bin/cmlink_gdbserver.exe # 实际引用结果为 npk文件父路径+value,例如C:\Users\jj\nuclei-pack-npk\NPKs\XinShengTech\Tool_Package\tool-cmlink\1.0.0\cmlink\bin\cmlink_gdbserver.exe
description: proxy location
system: true # 默认为fasle,当system为true时,该变量引用时直接使用变量名,例如${proxy}
## Template File Management
## Only works on tpp类型,该类型比较特殊,描述文件为npk_template.yml,是基于npk.yml做的扩展
templatemanage:
installdir: ${soc}
files:
build.mk.ftl: build.mk
Common/npk.yml.ftl: Common/npk.yml
Common/demosoc.svd.ftl: Common/${soc}.svd
Common/Source/demosoc_common.c: Common/Source/${soc}_common.c
Common/Source/system_demosoc.c.ftl: Common/Source/system_${soc}.c
Common/Source/Drivers/demosoc_uart.c.ftl: Common/Source/Drivers/${soc}_uart.c
Common/Source/GCC/intexc_demosoc.S.ftl: Common/Source/GCC/intexc_${soc}.S
Common/Source/GCC/startup_demosoc.S.ftl: Common/Source/GCC/startup_${soc}.S
Common/Source/Stubs: Common/Source/Stubs
Common/Include/demosoc.h.ftl: Common/Include/${soc}.h
Common/Include/demosoc_uart.h.ftl: Common/Include/${soc}_uart.h
Common/Include/nuclei_sdk_soc.h.ftl: Common/Include/nuclei_sdk_soc.h
Common/Include/system_demosoc.h.ftl: Common/Include/system_${soc}.h
Board/nuclei_fpga_eval/openocd_demosoc.cfg: Board/${board}/openocd_${soc}.cfg
Board/nuclei_fpga_eval/npk.yml.ftl: Board/${board}/npk.yml
Board/nuclei_fpga_eval/Source/GCC/gcc_demosoc_ilm.ld.ftl.ftl: Board/${board}/Source/GCC/gcc_${soc}_ilm.ld
Board/nuclei_fpga_eval/Source/GCC/gcc_demosoc_flash.ld.ftl: Board/${board}/Source/GCC/gcc_${soc}_flash.ld
Board/nuclei_fpga_eval/Source/GCC/gcc_demosoc_flashxip.ld.ftl: Board/${board}/Source/GCC/gcc_${soc}_flashxip.ld
Board/nuclei_fpga_eval/Include/board_nuclei_fpga_eval.h.ftl: Board/${board}/Include/board_${board}.h
Board/nuclei_fpga_eval/Include/nuclei_sdk_hal.h.ftl: Board/${board}/Include/nuclei_sdk_hal.h
2.4.1.2. 内容约定
为了保证 npk.yml
文件的可读性与简约性,对 npk.yml
文件的存储制定如下约定:
各字段的存储顺序请保持与模板一致,数据与DICT 按读入时顺序保存
各字段建议适当加上注释,尤其是那种需要解释的地方
MUST 类型的字段需要按照上述注释描述的规则进行检查,如果不合规请报错提示,并不予导入
缩进建议采用2个空格字符
针对一些 OPTIONAL 的字段可以留空或者不写该字段
一级字段之间增加一行空行,二级及以下字段不使用空行,第一部分基础信息一级字段间不使用空行
字符串建议不使用引号,除特殊语法需要
所有的`description`字段建议控制在20字符以内,方便排版展示,仅限英文
关于yaml里面多行的约定如下: https://yaml-multiline.info/
2.4.1.3. 包导入规则
下面定义合法的包导入规则:
- 如果存在导入包中存在一些依赖的包(带版本匹配),并没有被导入,则不允许导入,并提示缺乏依赖的包,请导入该包。
后续包管理联网了,则可以提示是否从网上下载依赖的包,或者手动导入zip包
- 如果删除包,并且该包被其他包依赖,则提示哪些包依赖于该包,询问是否删除,如果删除以后,则在包管理中显示缺少的包
后续包管理联网了,支持点击按钮下载缺失的包,或者手动导入zip包
如果导入相同版本的包,则提示该包已经存在,是否替换
如果导入不同版本的包,则提示已经存在其他版本的包,是否继续导入
导入的包,按照定义的类型分类显示,显示包的版本,包的name,owner,description, homepage, license
2.4.1.4. zip包内容规范
下面定义合法的zip包的内容规则:
一个zip包中必须包含至少1个npk文件
- 包类型的判定:如果包内存在多个类型的npk文件,npk类型判定条件如下
sdk > ssp > bsp > osp > mwp > csp > app
如果判定出包的类型存在多个相同的npk,则该包不合法,不允许导入,并提示
该类型的包不允许存在多个该类型的npk文件
如果是
sdk
类型的包,则必须包含至少一个ssp
和依赖于该ssp
的bsp
文件,以及至少一个app
类型的文件,允许存在其他类型的包如果是其他类型的包,则里面包含的其他npk,必须显式依赖于该包
2.4.1.5. 包依赖关系处理
包依赖关系的处理涉及到如何能够将包拆分并形成合理的依赖关系,便于包的独立维护。这里对不同类型的包的依赖处理进行详细的分析。
依赖通过 dependencies
字段下的依赖列表来控制,支持依赖特定owner的某个name,某个version版本的包,查找规则为 owner/name:version
,如果owner未定义,则默认为该npk文件中定义的owner,如果 version
未定义,则优先在同组件包查找,否则取最新的包。
2.4.1.5.1. csp Core Support Package依赖
csp类型的包是处理器内核CORE支持的软件包,目前针对Nuclei RISC-V内核,我们主要推广NMSIS这样的开源软件支持包。
一般情况下,csp类型的包是非常底层的包,这里不支持依赖 ssp/bsp/mwp/rtos/app
这样的类型的包。但是可以依赖sdk类型的包,表示该包属于依赖的sdk包的环境中。
2.4.1.5.2. ssp SoC Support Package依赖
ssp类型的包是SoC或者芯片的支持的软件包,例如 gd32vf103
, demosoc
这样SoC的支持软件包。
ssp软件包仅可以依赖 csp/mwp/osp
这样的软件包,如果依赖了这三种类型的软件包,则表示在工程创建的时候或者是代码引入的时候,这三类软件包需要导入代码。 而如果依赖sdk类型的软件包,则表示该ssp类型的包属于依赖的sdk类型的软件包的环境。
理论上用户可以创建一个ssp软件包,不依赖任何 csp/mwp/rtos
的软件包,也不属于sdk类型的软件包。 osp 类型软件包仅可以依赖一个。
2.4.1.5.3. bsp Board Support Package依赖
bsp类型的包是针对基于某款SoC/芯片做的开发板而推出的软件支持包,例如 gd32vf103-rvstar
这款开发板的bsp软件包。
bsp软件包仅可以依赖 ssp/csp/mwp/osp
这样的软件包, 如果依赖了这几种类型的软件包,则表示在工程创建的时候或者是代码引入的时候,这类软件包需要导入代码。 而如果依赖sdk类型的软件包,则表示该ssp类型的包属于依赖的sdk类型的软件包的环境。
理论上用户可以创建一个bsp软件包,不依赖任何软件包。 osp 类型软件包仅可以依赖一个。
2.4.1.5.4. osp OS Support Package依赖
osp类型的包是指特定的RTOS的软件支持包,例如freertos,ucosii之类的。
osp类型的包仅可以依赖 ssp/csp/mwp
类型的软件包,如果依赖了这几种类型的软件包,则表示在工程创建的时候或者是代码引入的时候,这类软件包需要导入代码。 而如果依赖sdk类型的软件包,则表示该ssp类型的包属于依赖的sdk类型的软件包的环境。
2.4.1.5.5. mwp Middleware Support Package依赖
mwp类型的软件包是指中间件类型的软件包,例如某个语音算法的库,某种物联网连接库如 mqtt
, coap
之类。
mwp类型的包仅可以依赖 bsp/ssp/csp/mwp/osp
类型的软件包,但是不建议直接依赖 bsp/ssp
,在创建middleware的时候尽量保证其通用性,可以很好被集成到其他的软件中。
2.4.1.5.6. sdk Software Development Kit Package依赖
sdk类型的软件包是一类非常特殊的软件包,本身并不会有额外的代码引入,而是通过依赖其他类型的软件包而组织的一个特殊的包。如果是sdk类型的软件包,导入是会强制检查软件包目录下所有的 npk.yml
文件以查找其他的软件包并引入该SDK依赖中,无需 npk.yml
文件显示进行依赖,这种依赖关系并不会直接导致创建工程时的代码的导入,更多的是软件包的集合。
一个sdk类型的软件包可能会依赖多个ssp,多个bsp,多个csp,多个app,多个mwp和多个osp。更详细的内容请参见[构建SDK开发包](#构建SDK开发包)
对于属于sdk类型的软件包的其他软件包里面的依赖,优先使用都属于统一sdk软件包内部的软件包。例如:
sdk-nuclei-sdk是一个sdk类型的软件包,内部包含了csp-nsdk_nmsis, bsp-nsdk_nuclei_fpga_eval, ssp-nsdk_demosoc, ssp-nsdk_gd32vf103, osp-nsdk_freertos, osp-nsdk_ucosii这些软件包
而外部也有csp-nsdk_nmsis,osp-nsdk_freertos这类的软件包,在工程创建阶段,在版本匹配满足的情况下,优先使用内部的csp-nsdk_nmsis和osp-nsdk_freertos,只有在版本匹配不满足要求的情况下,才会使用
在工程创建完成后,用户可以手动升级特定的包到其他版本。
2.4.2. 模块说明
从上述描述文件中可以看出,一个标准的 npk.yml
实际是上由几个大块组成的,而在实现应用中,我们并不一定会完全用到,一个合规的 npk.yml
文件,只要拥有基本的信息,就是可以正常给Nuclei Studio使用。
2.4.2.1. Package Base Information
这一块分信息,是NPK的基础的信息,很多关键的信息在这部分内容中需要描述清楚。其中着重说明几个字段。
name
必填,NPK的名称ID,不要有空格,符合C语言命名规范,英文名称,是唯一名称ID。
version
选填,如不填,默认为空,建议采用SEMVER2.0版本号管理,只能数字打头, 例如1.2.3
type
必填, 可选类型值有csp, ssp, bsp, osp, app, mwp, sdk, tpp, tool
os
选填,标明该NPK适用于什么类型的Nuclei Studio,目前我们发行的Nuclei Studio有win64和lin64两个版本。OS类型可以填win32、win64、lin64、lin32,但目前组件包上传页面只支持win64和lin64,该字段只存在tool类型package
owner
必填,组件包的拥有者,该ID一般为认证开发者ID,便于后期进行权限查找匹配。如果该NPK仅作本地测试,可以随意。
2.4.2.1.1. Package Information
packinfo 这一块分信息,主要是对NPK做一些说明,包括一些文档等信息,最终在Nuclei Studio中使用该NPK时,这部分信息,会在New Project的导引中显示。
2.4.2.1.2. Package Dependency
dependencies 描述的是NPK的依赖关系,为了实现NPK的复用性,减少NPK的维护成本,我们在设计时,是允许NPK实现依赖关系,一个NPK可以依赖0个以上的NPK,所以在这里dependencies是以组对象出现,每个依赖对象内需要明确NPK的 name owner version
2.4.2.2. Package Configurations
Configuration 字段是个非常特殊的字段,主要用于提供一些可配置项,以满足在工程创建时的交互场景。
不同包里面的configuration字段的下的二级字段名称可以一样,如果使用一样的名称则具备一样的含义,如果定义了一样的名称则按照如下的规则进行覆盖。
覆盖规则为:app > mwp > osp > bsp > ssp > csp
Configuration 对象组会包含多个对象,而每个对象有固定的结构。
XXX(变量名)
变量名可以随意,简合c++的命名规范即可。在后面部分会以${XXX}或${XXX.XX}的方式引用。
default
默认值,可选项。
type
这个变量的类型,为了支持更丰富的UI体验,我们在NPK中定义了很多的UI组件类型,具体请参看后面章节。
global
标明此字段是否在工程创建时显示在引导页面中。
tips
对该变量的说明信息,主要用于UI的tips事件。
hints
对该变量的说明信息,如值的示例等,主要用于UI的hints事件。
description
此变量的NPK中的说明描述。
UI组件信息
支持的类型有choice, list, checkbox, multicheckbox, text等,具体信息参见
2.4.2.3. Source Code Management
codemanage 描述的是跟模板工程有关的内容,大多的时候,我们的NPK会包括很多复杂的功能,需要创建某个一个具体的工程的时候,我们又只需要一些具体的文件,同时需要配置这些文件的信息。codemanage 就是将这些信息描述出来,它包含以下关键字:
custom
默认为false, 当为true时,这个installdir就表示直接安装的目录
srcroot
默认为 .
, 表示当前 npk.yml
所在目录,可以是相对路径, 例如 ../
, ../bsp
等;需要注意的是,设置了这个以后,对应的copyfiles/incdirs/libdirs的路径的根目录均受到影响,就会使用新设置的和这个路径
installdir
希望代码安装的目录名称,仅限英文,满足C语言命名格式
针对sdk类型的package,会被安装到
<sdk_installdir>
, 如果installdir未定义,默认为SDK,如果没有任何sdk类型的package被引用,sdk_installdir也被默认设置为SDK针对csp类型的package,会被安装到
<sdk_installdir>/<csp_installdir>
目录下,TBD针对ssp类型的package,会被安装到
<sdk_installdir>/SoC/<ssp_installdir>/Common
下面针对bsp类型的package,会被安装到
<sdk_installdir>/SoC/<ssp_installdir>/Board/<bsp_installdir>
下面,如果不依赖于任何ssp类型,则安装到<sdk_installdir>/BSP/<bsp_installdir>
针对osp类型的package,会被安装到
<sdk_installdir>/OS/<osp_installdir>
下面针对app类型的package,会被安装到
<app_installdir>/
目录下, 如果installdir未定义,默认为application针对mwp类型的package,会被安装到
<sdk_installdir>/Components/<mwp_installdir>
目录下
Note
2023.05.26 新增 copyfiles/incdirs/libdirs
均支持 ../../
这样的相对上级目录,但是安装或者设置路径的时候,均设置到 <installdir>
下面
例如: path: ["../common/"]
就拷贝上一级目录的 common
, 并放在 <installdir>/common
下面,
如果下面有 common
这个目录,则创建 R1L_common
, 如果是 ../../common
, 则创建 R2L_common
,
这种方案不考虑了,直接创建同名目录,同名文件直接覆盖,建议采用 srcroot: ..
来解决问题对应的 incdirs/libdirs
如果遇到这种相对路径,也需要以最终安装到路径以及文件名为准
copyfiles
待拷贝的文件或者文件夹,这里是指所有的目录或者文件,支持 ../
、 *
、 *.*
,给结合srcroot一起使用,
incdirs
必填,加入头文件目录列表,Nuclei Studio会进行补全,最终的路径是相对于工程根目录的路径。
libdirs
可选,lib库所在目录,Nuclei Studio会进行补全,最终的路径是相对于工程根目录的路径。
ldlibs
可选的需要链接的库,Nuclei Studio会进行补全,最终的路径是相对于工程根目录的路径。
2.4.2.4. Set Configuration for other packages
setconfig 用来设置NPK的其他选项,遵循覆盖规则app > mwp > osp > bsp > ssp > csp。
setconfig 是一个对象组,可以无限扩展,每个对象中有三个字段来描述一个对象。
config
变量名,遵循C++命名规范,一般变量XXX,在其它部分以${XXX}的方式引用
该变量名不唯一,可以通过条件进行判定生效,也遵循覆盖规则app > mwp > osp > bsp > ssp > csp,进行自动覆盖。
value
变量的值
condition
变量的条件,只有条件生效时,该变量的该值才会生效
2.4.2.5. Build Configuration
设置工程的编译工具和编译选项的配置,它的关键字包含以下几个固定字段。
type
支持的编译工具的类型,值一般为gcc、clang、common。目前只支持gcc、clang两种,因为编译选项的配置有一些是相同的,为了提高代码的复用性,我们又添加common类型。
description
对此编译工具的说明。
toolchain_name
重要字段,编译工具名字。
cross_prefix
重要字段,编译工具的前缀。
unflags
在buildconfig section中的 common_flags/cflags/asmflags/ldflags/cxxflags
中生效,用于删掉之前已经定义的flags。
undefines
在buildconfig section中的 common_defines/cdefines/asmdefines/cxxdefines
中生效,用于删掉之前已经定义的defines。(字符串完全匹配,则生效)
common_flags
用的编译选项,将会添加到cflags, asmflags, cxxflags上,留空表示没有任何选项。
ldflags
链接选项列表,留空表示没有任何选项。
linkscript
链接脚本的定义,必须在bsp/ssp中定义,留空表示没有任何选项。
cflags
C编译选项,留空表示没有任何选项。
asmflags
ASM编译选项,留空表示没有任何选项。
cxxflags
CXX编译选项,留空表示没有任何选项。
common_defines
通用的宏定义,留空表示没有任何选项。
cdefines
C的宏定义,留空表示没有任何选项。
asmdefines
ASM的宏定义,留空表示没有任何选项。
cxxdefines
CXX的宏定义,留空表示没有任何选项。
prebuild_steps
command
编译前执行的命令,留空表示没有任何选项。
description
编译前执行的命令的说明,留空表示没有任何选项。
postbuild_steps
command
编译后执行的命令,留空表示没有任何选项。
description
编译后执行的命令的说明,留空表示没有任何选项。
2.4.2.6. Debug Configuration
设置工程的Debug类型及相关参数的配置,它的关键字包含以下几个固定字段,可以不用配,如果配置了,在工程生成的时候,Nuclei Studio会根据这里面的内容,生成了个launch文件,同时可以根据相关内容进行工程的Debug。
type
Debug类型,目前支持GDB Custom 、GDB SEGGER J-Link、 GDB OpenOCD、 GDB Nuclei QEMU、 Nuclei RVProf
description
对支持的Custom Jlink OpenOCD Qemu RVProf的说明
configs
对应的Debug类型的参数,所有的参数,都是以key-value的方式出现,因为每中Debug类型所需参数不同,对应的情况也不同,更详细的说明如下。
debugconfig:
- type: openocd
description: Nuclei OpenOCD
configs:
- key: XXXX
value: xxxx
2.4.2.6.1. GDB Custom的Debug参数
Name |
Reset Value |
Description |
doStartGdbCLient |
true |
Start locally |
doStartGdbServer |
true |
Start GDB session |
gdbClientOtherCommands |
gdb Client Other Commands |
|
gdbClientOtherOptions |
gdb Client Other Options |
|
gdbMode |
Commands |
支持的类型,目前支持Commands、Generial、Dlink |
gdbServerConnectionAddress |
gdb Server Connection Address |
|
gdbServerExecutable |
gdb Server Executable |
|
serverCheckFlag |
Started by GNU MCU Eclipse |
server Check Flag |
gdbServerGdbPortNumber |
3333 |
gdb Server Gdb Port Number |
gdbServerOther |
Config options |
|
DEBUG_NAME |
${cross_prefix}gdb${cross_suffix} |
Executable path |
ipAddress |
localhost |
Host name or lP address |
portNumber |
3333 |
|
UPDATE_THREADLIST_ON_SUSPEND |
false |
Force thread list update on suspend |
otherInitCommands |
Initialization Commands |
|
loadImage |
true |
Load executable |
imageFileName |
use File For lmage name |
|
imageOffset |
Executable offset (hex): |
|
useFileForImage |
false |
Use file for Image |
useProjBinaryForImage |
true |
|
loadSymbols |
true |
Load symbols |
symbolsFileName |
||
symbolsOffset |
Symbols offset (hex) |
|
useProjBinaryForSymbols |
true |
Use project binany |
useFileForSymbols |
false |
Use file for Symbols |
doDebugInRam |
true |
Debug in RAM |
otherRunCommands |
Run/Restart Commands |
|
setPcRegister |
false |
Set program counter at (hex) |
pcRegister |
||
setResume |
false |
|
setStopAt |
true |
Set breakpoint at |
stopAt |
main |
|
doContinue |
true |
Continue |
svdPath |
svd file path |
2.4.2.6.2. GDB SEGGER J-Link的Debug参数
Name |
Reset Value |
Description |
doStartGdbServer |
true |
Start the j-Link GDB server locally |
doConnectToRunning |
false |
Connect to running target |
gdbServerExecutable |
Executable path |
|
doGdbServerAllocateConsole |
true |
Allocate console for the GDB server |
doGdbServerInitRegs |
true |
do Gdb Server Init Regs |
doGdbServerLocalOnly |
true |
do Gdb Server Local Only |
doGdbServerSilent |
false |
do Gdb Server Silent |
doGdbServerVerifyDownload |
true |
do Gdb Server Verify Download |
doStartGdbServer |
true |
Start the j-Link GDB server locally |
gdbClientOtherCommands |
set mem inaccessible-by-default off |
gdb Client Other Commands |
gdbServerConnection |
usb |
gdb Server Connection |
gdbServerConnectionAddress |
gdb Server Connection Address |
|
gdbServerDebugInterface |
jtag |
gdb Server Debug Interface |
gdbServerDeviceEndianness |
little |
gdb Server Device Endianness |
gdbServerDeviceName |
gdb Server Device Name |
|
gdbServerLog |
gdb Server Log path |
|
gdbServerGdbPortNumber |
2331 |
gdb Server Gdb Port Number |
gdbServerSwoPortNumber |
2332 |
gdb Server SwoPort Number |
gdbServerTelnetPortNumber |
2333 |
gdb Server Telnet PortNumber |
gdbServerOther |
gdb ServerO ther |
|
DEBUG_NAME |
${cross_prefix}gdb${cross_suffix} |
Executable path |
gdbClientOtherOptions |
gdb Client Other Options |
|
ipAddress |
localhost |
|
portNumber |
2331 |
|
gdbServerDeviceSpeed |
auto |
gdb Server Device Speed |
doFirstReset |
false |
Initial Reset and Halt |
firstResetType |
||
firstResetSpeed |
1000 |
|
enableFlashBreakpoints |
true |
Enable flash breakpoints |
doGdbServerAllocateSemihostingConsole |
true |
Allocate console for semihosting and SWO |
enableSemihosting |
true |
Enable semihosting console routed to |
enableSemihostingIoclientTelnet |
true |
Telnet |
enableSemihostingIoclientGdbClient |
false |
GDB client |
enableSwo |
true |
Enable SWO |
swoEnableTargetCpuFreq |
0 |
SWO Cpu freq |
swoEnableTargetSwoFreq |
0 |
SWO freq |
swoEnableTargetPortMask |
0x1 |
SWO Port mask |
otherInitCommands |
other Init Commands |
|
jtagDevice |
GNU MCU J-Link |
|
loadImage |
true |
Load executable |
imageFileName |
||
imageOffset |
||
useFileForImage |
false |
|
useProjBinaryForImage |
true |
|
loadSymbols |
true |
Load symbols |
symbolsFileName |
||
symbolsOffset |
||
useFileForSymbols |
false |
|
useProjBinaryForSymbols |
true |
|
doDebugInRam |
true |
Debug in RAM |
doSecondReset |
true |
Pre-run/Restart reset |
secondResetType |
Type (always executed at Restart) |
|
otherRunCommands |
||
setPcRegister |
false |
Set program counter |
pcRegister |
Set program counter at (hex) |
|
setStopAt |
true |
Set breakpoint |
stopAt |
main |
Set breakpoint at |
doContinue |
true |
Continue |
svdPath |
svd file path |
2.4.2.6.3. GDB OpenOCD的Debug参数
Name |
Reset Value |
Description |
doStartGdbServer |
true |
Start OpenocD locally |
gdbServerExecutable |
Executable path: |
|
gdbServerGdbPortNumber |
3333 |
GDB port |
gdbServerTelnetPortNumber |
4444 |
Telnet port |
gdbServerTclPortNumber |
6666 |
Tcl port |
gdbClientOtherOptions |
gdb Client Other Options |
|
gdbServerOther |
Config options |
|
doGdbServerAllocateConsole |
true |
do GdbServer Allocate Console |
doGdbServerAllocateTelnetConsole |
false |
do Gdb Server Allocate Telnet Console |
gdbServerConnectionAddress |
gdb Server Connection Address |
|
doStartGdbCLient |
true |
do Start Gdb CLient |
DEBUG_NAME |
${cross_prefix}gdb${cross_suffix} |
|
gdbClientOtherCommands |
Commands |
|
ipAddress |
localhost |
Host name or lp address |
portNumber |
3333 |
Port number |
UPDATE_THREADLIST_ON_SUSPEND |
false |
Force thread list update on suspend |
doFirstReset |
false |
Initial Reset and Halt |
firstResetType |
init |
|
otherInitCommands |
||
enableSemihosting |
false |
Enable semihosting console routed to |
loadImage |
true |
Load executable |
useFileForImage |
false |
|
imageFileName |
||
imageOffset |
||
symbolsFileName |
||
symbolsOffset |
||
loadSymbols |
true |
Load symbols |
useFileForSymbols |
false |
|
useProjBinaryForImage |
true |
|
useProjBinaryForSymbols |
true |
|
useRemoteTarget |
true |
|
doDebugInRam |
true |
Debug in RAM |
doSecondReset |
true |
Pre-run/Restart reset |
secondResetType |
halt |
Type (always executed at Restart) |
otherRunCommands |
||
setPcRegister |
false |
Set program counter |
pcRegister |
Set program counter at (hex) |
|
setStopAt |
true |
Set breakpoint |
stopAt |
main |
Set breakpoint at |
doContinue |
true |
Continue |
svdPath |
svd file path |
2.4.2.6.4. GDB Nuclei QEMU的参数
Name |
Reset Value |
Description |
doStartGdbServer |
true |
Start OpenocD locally |
gdbServerExecutable |
Executable path: |
|
gdbMachineBit |
Machine Bit: |
|
gdbServerBoardName |
Board name; |
|
gdbCoreName |
Nuclei RisC-V Core: |
|
gdbServerSMPCount |
1 |
Nuclei SMP Count: |
gdbDownloadName |
Download: |
|
gdbServerOther |
-serial stdio -nodefaults -S |
More options: |
otherExtensions |
other Extensions |
|
gdbServerGdbPortNumber |
1234 |
GDB port: |
isGdbServerVerbose |
false |
Extra verbose |
enableSemihosting |
true |
Enable Arm semihosting |
disableGraphics |
true |
Do not open graphic windows |
doGdbServerAllocateConsole |
true |
Allocate console for QEMU |
DEBUG_NAME |
${cross_prefix}gdb${cross_suffix} |
Executable name |
gdbClientOtherOptions |
Other options |
|
gdbClientOtherCommands |
Commands |
|
ipAddress |
localhost |
Host name or lp address |
portNumber |
1234 |
Port number |
doFirstReset |
false |
Initial Reset and Halt |
otherInitCommands |
||
loadSymbols |
true |
Load symbols |
symbolsFileName |
||
symbolsOffset |
||
useFileForSymbols |
false |
|
useProjBinaryForSymbols |
true |
|
useRemoteTarget |
true |
|
loadImage |
true |
Load executable |
useFileForImage |
false |
|
imageFileName |
||
imageOffset |
||
useProjBinaryForImage |
true |
|
doDebugInRam |
false |
Debug in RAM |
otherRunCommands |
||
doSecondReset |
true |
Pre-run/Restart reset |
setPcRegister |
false |
Set program counter |
pcRegister |
Set program counter at (hex) |
|
setStopAt |
true |
Set breakpoint |
stopAt |
main |
Set breakpoint at |
doContinue |
true |
Continue |
svdPath |
svd file path |
2.4.2.6.5. Nulcei RVProf的参数
Name |
Reset Value |
Description |
cycleModelExecutable |
${cycelmodel_path}/${cycelmodel_executable} |
cycleModel Executable |
cycleModelExecutableTimeOut |
20 |
cycleModelExecutable TimeOut |
cycleModelExecutableProcessorCores |
4 |
cycleModel Executable Processor Cores |
cycleModelOther |
cycleModel Other |
|
docycleModelAllocateConsole |
true |
|
docycleModelAllocateTelnetConsole |
false |
|
RVProfExecutable |
${rvprof_path}/${rvprof_executable} |
RVProf Executable |
RVProfExecutableTimeOut |
20 |
RVProf Executable TimeOut |
RVProfOther |
RVProf Other |
|
RVProfPortNumber |
5000 |
RVProfPort Number |
doRVProfAllocateConsole |
true |
|
doRVProfAllocateTelnetConsole |
false |
2.4.2.7. Extended variable
environment 是应用于tool类型的NPK包中的配置,当用户想要通过NPK来共享一个tools如cycleModel,可以使用。当定义了 environment ,Nuclei Studio会自动产生几个全局,这个变量可以在其他的NPK中以 ${xxx-1.0.0-XXX}
的方式使用。
Note
每个包存在一个包路径,引用为npk名称-版本号,例如
${tool-cyclemodel-1.0.0}
其他变量的引用为npk名称-版本号-变量名,例如
${tool-cyclemodel-1.0.0-cycelmodel_path}
,${tool-cyclemodel-1.0.0-cycelmodel_executable}
当变量的system值为true时,额外新增一个不带版本号的变量,取最高版本的该变量,例如
${tool-cyclemodel-cycelmodel_executable}
name: tool-cyclemodel
owner: nuclei
os:
version: 1.0.0
description: Nuclei Tools cyclemodel
details: Nuclei Tools cyclemodel
type: tool
keywords:
- tool
- cyclemodel
license: Apache-2.0
homepage:
## 扩展变量 tool-cyclemodel-1.0.0与 tool-cyclemodel-1.0.0-proxy
environment:
- key: cycelmodel_path
value: bin
description: cyclemodel location
system: true
- key: cycelmodel_executable
value: bin/n300_best_config_cymodel_latest
description: cyclemodel location
system: true
## 这是另一个NPK中的代码,演示了如何使用tool-cyclemodel
debugconfig:
- type: rvprof
description: Nuclei RVProf
configs:
- key: ncycm_path
value: ${tool-cyclemodel-1.0.0-cycelmodel_executable}
- key: rvprof_path
value: ${tool-rvprof-1.0.0-rvprof_executable}
2.4.2.8. templatemanage
内部使用的配置,这里不做详细说明。
2.4.3. NPK中的UI组件
NPK中提供了丰富的UI组件,这些组件的字段里面都会有default, description, global这些子字段,这些字段均具备含义。
default表示默认值,description表示该选项的含义,global表示这个选项是否在工程创建时显示(true),或者仅仅内部传参使用(false)。
Choice 单项选择框
choice_test:
default_value: ground
type: choice
description: choice_test
choices:
- name: ground
description: Ground Rules
info:
- name: app_commonflags
value: >-
-O3 -flto -fno-inline -funroll-loops -Wno-implicit -mexplicit-relocs
-fno-builtin-printf -fno-common -falign-functions=4 -falign-jumps=4 -falign-loops=4
- name: inline
description: Inline
info:
- name: app_commonflags
value: >-
-O3 -flto -finline -funroll-loops -Wno-implicit -mexplicit-relocs -fno-builtin-printf
-fno-common -falign-functions=4 -falign-jumps=4 -falign-loops=4 -finline-functions
- name: best
description: Best Effort
info:
- name: app_commonflags
value: >-
-Ofast -flto -fwhole-program -finline -funroll-loops -Wno-implicit -mexplicit-relocs
-fno-builtin-printf -fno-common -falign-functions=4 -falign-jumps=4 -falign-loops=4
-finline-functions
list 单项选择框
list_test:
default_value: rv32imac
type: list
global: true
description: list_test
value: >-
[rv32imac,rv32imafc,rv32imafdc,rv32imacb,rv32imafcb,rv32imafdcb]
checkbox 单项勾选框
checkbox_test:
default_value: 0
type: checkbox
global: true
description: checkbox_test
multicheckbox 穿梭选择框
下面提供2种写法
multicheckbox_old:
default_value: []
type: multicheckbox
global: true
description: multicheckbox_old
choices:
- name: b
description: Bitmanip Extension
- name: p
description: Packed SIMD Extension
- name: v
description: Vector Extension
multicheckbox_new:
default_value: rv32imac
type: multicheckbox
global: true
description: multicheckbox_new
param:
name: ["rv32imac","rv32imafc","rv32imafdc"]
description: ["${name} description","${name} description","${name} description"]
text 单行文本框
text_test:
value: >-
-O2 -funroll-all-loops -finline-limit=600 -ftree-dominator-opts
-fno-if-conversion2 -fselective-scheduling -fno-code-hoisting
-fno-common -funroll-loops -finline-functions -falign-functions=4
-falign-jumps=4 -falign-loops=4
type: text
description: text_test
multitext 多行文本框
multitext_test:
value: >-
-O2 -funroll-all-loops -finline-limit=600 -ftree-dominator-opts
-fno-if-conversion2 -fselective-scheduling -fno-code-hoisting
-fno-common -funroll-loops -finline-functions -falign-functions=4
-falign-jumps=4 -falign-loops=4
type: multitext
description: multitext_test
multichoice 多选下拉框
下面提供2种写法
multichoice_test1:
default_value: []
type: multichoice
global: true
description: multichoice_test1
param:
name: ["rv32imac","rv32imafc","rv32imafdc"]
description: ["${name} description","${name} description","${name} description"]
multichoice_test2:
default_value: >-
[rv32imac,rv32imafdc]
type: multichoice
global: true
description: multichoice_test2
choices:
- name: rv32imac #
description: ${name} description
- name: rv32imafc
description: ${name} description
- name: rv32imafdc
description: ${name} description
cascaderchoice 级联选择框
cascaderchoice_test:
default_value: >-
[hubei,jingzhou,shashi]
type: cascaderchoice
global: true
description: cascaderchoice test
cascader_param:
- hubei:
- wuhan
- jingzhou:
- shashi
- jianli
- hunan:
- changsha
- guangdong
switchbutton 开关
switchbutton_test:
default_value: 0
type: switchbutton
global: true
description: switchbutton test
slider 数字选择框
slider_test:
default_value: 0
type: slider
description: slider_test
param:
range: >-
[0,100,1]
spinner 数字选择框
spinner_test:
default_value: 10
type: spinner
description: spinner_test
param:
range: >-
[-100,100,2]
multispinner 多数字选择框
multispinner_test:
default_value: >-
[3,4,6,4,6,4,6,4,6,7]
type: multispinner
global: true
description: multispinner_test
param:
range: >-
[-100,100,1],[-100,100,2],[-100,100,3],[-100,100,3],[-100,100,3],[-100,100,3],[-100,100,3],[-100,100,3],[-100,100,3],[-100,100,4]
multicheckbox_v2 多项勾选框
下面提供2种写法
multicheckbox_v2_test1:
default_value: >-
[rv32imac]
type: multicheckbox_v2
global: true
description: multicheckbox_v2 test1
param:
name: ["rv32imac","rv32imafc","rv32imafdc"]
description: ["${name} description","${name} description","${name} description"]
multicheckbox_v2_test2:
default_value: >-
[rv32imac]
type: multicheckbox_v2
global: true
description: multicheckbox_v2 test2
choices:
- name: rv32imac
description: rv32imac
- name: rv32imafc
description: rv32imafc2
- name: rv32imafdc
description: rv32imafdc
multiradio 单选框
下面提供2种写法
multiradio_test1:
default_value: rv32imac
type: multiradio
global: true
description: multiradio test1
param:
name: ["rv32imac","rv32imafc","rv32imafdc"]
description: ["${name} description","${name} description","${name} description"]
multiradio_test2:
default_value: rv32imac
type: multiradio
global: true
description: multiradio test2
choices:
- name: rv32imac
description: rv32imac
- name: rv32imafc
description: rv32imafc2
- name: rv32imafdc
description: rv32imafdc
2.4.4. NPK的语法
2.4.4.1. YAML语言
NPK的描述文件npk.yml,是以YAML语言来编写,所以它支持标准的YAML语法,获取更多YAML相关的信息,可以参考:https://yaml.org/
2.4.4.2. 变量定义
NPK的描述语言中,允许用户自义定一个变量,并在有依赖关系的NPK中的任意位置使用
Note
例子NPK中定义了一个变量app_commonflags,在与该NPK有依赖关系的任意npk.yml文件内的任意位置,我们可以通过
${app_commonflags}
来使用app_commonflags的值。例子NPK中定义了一个list对象nuclei_core,在与该NPK有依赖关系的任意npk.yml文件内的任意位置,我们可以通过
${nuclei_core.arch}
来使用nuclei_core对象中的arch值;通过${nuclei_core.abi}
来使用nuclei_core对象中的abi值;通过${nuclei_core.tune}
来使用nuclei_core对象中的tune值。
configuration:
app_commonflags:
value:
type: text
description: Application Compile Flags
nuclei_core:
default_value: n201
type: choice
global: true
description: Nuclei RISC-V Core
choices:
- name: n200
arch: rv32imc
abi: ilp32
cmodel: medlow
tune: nuclei-200-series
description: N200 Core(ARCH=rv32imc, ABI=ilp32)
- name: n201
arch: rv32iac
abi: ilp32
cmodel: medlow
tune: nuclei-200-series
description: N201 Core(ARCH=rv32iac, ABI=ilp32)
## Set Configuration for other packages
setconfig:
- config: nmsislibarch
value: ${nuclei_core.arch}
## Build Configuration
buildconfig:
- type: gcc
common_flags: # flags need to be combined together across all packages
- flags: ${app_commonflags}
2.4.4.3. 关键字
为了更好的描述NPK,我们定义了一些字段,以描述出各种关系,其中大部分字段如其字面意义,这里重点介绍以下几个关键字。
condition
condition 在npk.yml中,使用很频繁,是自定义的一个关键字,用来处理逻辑关系,类似 if ,具体的使用如下。
ldflags:
- flags: --specs=nosys.specs
condition: $( ${stdclib} == "newlib_full" )
- flags: --specs=nano.specs --specs=nosys.specs -u _printf_float -u _scanf_float
condition: $( ${stdclib} == "newlib_fast" )
- flags: --specs=nano.specs --specs=nosys.specs -u _printf_float
condition: $( ${stdclib} == "newlib_small" )
- flags: --specs=nano.specs --specs=nosys.specs
condition: $( ${stdclib} == "newlib_nano" )
- flags: --specs=${stdclib}.specs
condition: $( startswith(${stdclib}, "libncrt") )
# 上述描术中flags的值,由condition决定,当在不同的场景时,flags的值会不同,
# 又因为flags是一个数组类型,所以上述例子中flags会有多个值,最终使用是,是flags的值拼接成的字符串。
dependencies
dependencies 在npk.yml中,用来描述NPK的依赖关系。
在很多的时候,NPK需要依赖特定owner的某个name,某个version版本的包,查找规则为 owner/name:version
, 如果owner未定义,则默认为该npk文件中定义的owner,如果 version 未定义,则优先在同组件包查找,否则取最新的包。如果所依赖的包找不到,则该NPK将无法使用。
Note
例子中NPK依赖了三个npk,如下:
sdk-nuclei_sdk owner、
version
未定义,则优先在同组件包查找,否则取最新的包tool-testmodel 明确了owner和version
tool-rvprof 明确了owner和version
## Package Dependency
dependencies:
- name: sdk-nuclei_sdk
version:
owner:
- name: tool-testmodel
version: 1.0.0
owner: nuclei
- name: tool-rvprof
version: 1.0.0
owner: nuclei
2.4.4.4. 自定函数
在NPK(npk.yml)中,为了更好地满足各种不同的需求,我们特意定义了一些常用的函数。
upper
将字符串变大写
${linker_script} = "test"
$(upper("${linker_script}CD")) => TESTCD
lower
将字符串变小写
${linker_script} = "test"
$(lower("${linker_script}cd")) => testcd
contains
判断字符串中是否包含另一个字符串
${linker_script} = "test"
$(contains(${linker_script}, nmsis) ) => false
join
将字符串连接数组
$(join([a,b,c,v], '') => abcv
concat
连接字符串成为新一字符串
${linker_script} = "test"
$(concat(${linker_script}, v) => testv
strip
去掉字符串两端空格
${linker_script} = " test "
$(strip(${linker_script})) => test
startswith
判断字符串是否以xxx开头
${linker_script} = "testabcd"
$(startswith(${linker_script}, test)) => true
endswith
判断字符串是否以xxx结尾
${linker_script} = "testabcd"
$(endswith(${linker_script}, test)) => false
arithop
数学运算符,支持+、- 、* 、/、% 、?(三元运算)等常用运算符,不支持++、–
$(arithop(${linker_script}+22) > 1000)
$(arithop(${linker_script}+22))
$(arithop(${linker_script}>22?1:0))
npack/npack_installdir
npack是否包含指定的npk
npack_installdir 包含的npk的路径
# a.yml
name: mwp-a
owner: nuclei
copyfiles:
- path: ["common", "abc.ld", "src/openocd.cfg", "inc"]
# b.yml
name: mwp-b
owner: nuclei
copyfiles:
- path: ["common", "111.ld", "src", "inc"]
debugconfig:
- type: openocd
description: Nuclei OpenOCD
configs:
- key: config
value: "$(npack_installdir(mwp-a))/src/openocd.cfg"
condition: $( npack(nuclei:mwp-a) )
# 这段描述,是当b.yml如果依赖a.yml时,就可以将config的值,设置为a.yml的目录下的/src/openocd.cfg
list_get
获取数组元素中指定脚标的值
${nuclei_cache}=[ic,dc,ccm]
$(list_get(${nuclei_cache},0)) -> ic
list_set
修改数组元素中指定脚标的值
${nuclei_cache}=[ic,dc,ccm]
$(list_set(${nuclei_cache},1,aa)) -> [ic,aa,ccm]
list_del
删除数组元素中指定脚标的值
${nuclei_cache}=[ic,dc,ccm]
$(list_del(${nuclei_cache},1)) -> [ic,ccm]
list_add
在数组元素指定脚标插入值
${nuclei_cache}=[ic,dc,ccm]
$(list_add(${nuclei_cache},2,aa)) -> [ic,dc,aa,ccm]
list_size
获取数组元素list的长度
${nuclei_cache}=[ic,dc,ccm]
$(list_size(${nuclei_cache})) -> 3
list_sub
从list中指定的位置开始,截取指定长度的list
${nuclei_cache}=[ic,dc,ccm]
$(list_sub(${nuclei_cache},1,2)) -> [dc]
$(list_sub(${nuclei_cache},0,2)) -> [ic,dc]
$(list_sub(${nuclei_cache},1,)) -> [dc,ccm]
$(list_sub(${nuclei_cache},,2)) -> [ic,dc]
subst
对字符串内部的指定字符串进行替换,第三个参数可为空
subst(libncrt_small,lib,) ==> ncrt_small
subst(libncrt_small,lib,ext) ==> extncrt_small