Skip to content

Nuclei Studio NPK Introduction

Huaqi Fang edited this page Aug 20, 2024 · 21 revisions

For >= Nuclei Studio 2022.04

目前仍处于初步阶段,后续可能会根据使用情况以及反馈调整NPK方案中的部分规则。

Nuclei Studio NPK(Nuclei PacKage)功能是芯来科技研发推出的RISC-V嵌入式软件包解决方案, 采用此方案可以方便处理器和SoC子系统客户快速集成和发布软件解决方案到Nuclei Studio集成开发环境当中, 并提供Project Wizard功能,方便开发者快速创建Nuclei RISC-V C/C++ Project.

Nuclei Studio版本日志

  • 2024.06 版本正式发布,主要是修复了2023.10/2024.02版本中存在的若干问题,并且引入了Terapines ZCC工具链支持,完善Profiling/Coverage技术,DLink调试器支持
  • 2023.10版本即将于2023.11.06发布,这个版本内建的GCC版本从gcc 10升级到gcc 13,同时编译器前缀 从 riscv-nuclei-elf- 改为 riscv64-unknown-elf-, 并且增加大量npk新的语法,以支持和适配多工具链和project wizard菜单优化,nuclei sdk 0.5.0将需要在 2023.10上使用。
  • 2022.04版本即将于2022.04.01发布,支持在线软件包托管服务,以及NPK Wizard向导,方便快捷创建软件包。
  • 开源了NPK Checker用于NPK软件包的校验,欢迎使用
  • 上线了 Nuclei Studio以及其他Nuclei Toolchain/Qemu/OpenOCD工具相关的文档,参见 https://doc.nucleisys.com/nuclei_tools/ide/index.html

NPK方案的一些视频介绍

更新日志

更新日期 更新说明
2022.1.7 描述不同的软件包在创建工程时安装位置
2022.1.21 choice类型的configuration增加了cmodel和tune的key, 仅推荐定义CORE选项的时候使用, Nuclei SDK 0.3.5 release使用上这个feature, 该npk更新依赖于Nuclei Studio 2022.01版本支持
2022.3.31 - 在debug configuration字段增加launch和executable变量,方便用户重命名生成的debug launch文件
- 增加Bundle Package类型, 这些新特性需要在 2022.04版本的IDE中支持
2022.8.31 - 增加tool类型,需要2022.08版本的IDE中支持

NPK介绍

npk.yml

NPK是一种采用Yaml语言描述的配置文件,文件名为npk.yml。该描述文件用于描述软件包内部的代码组织 结构,依赖关系,编译链接选项以及可配置项。NPK主要有以下几种类型,如下:

  • 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, 表示第三方工具,可以是Windows/Linux的工具,方便安装到IDE中集成使用

NPK描述文件npk.yml一般如下所示(目前仍是非常初始阶段,后期描述可能会变更,请注意):

## 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
description: Describe this package      # <MUST> 一句话描述清楚包的主要特性与功能, English only, 20字符以内
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
category: baremetal application         # <OPTIONAL> 包分类,按照上面的包类型进行二次分类,主要是针对mwp进行分类
keywords:                               # <MUST> 包关键字,主要用于索引与搜索
  - baremetal
license: Apache-2.0                     # <OPTIONAL> 对应包代码所用的许可证
                                        # 可选列表 GPL, GPLv2, MIT, Apache License v2, BSD等
owner: nuclei                           # <MUST>    组件包的拥有者,Dependencies查找匹配时需要用到
contributors:                           # <OPTIONAL> 组件包的代码贡献者列表
    - author_name, author_email
homepage:                               # <OPTIONAL> 组件包的主页, 如果有的话,必须是链接

## Package Information
packinfo:                               # <MUST> Only for bsp/ssp type, optional for other types
                                        # 用于描述更详细的软件包的一些信息
  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作用不一样, 用来显示具体的SoC或者Board名称
                                        # 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> 如果依赖存在的话,这个name必须定义
    owner: nuclei                       # <OPTIONAL> if not defined, it will use the owner definiton above.
                                        # 用于依赖特定所有者的package, owner/name:version, 最终查找的包按照这样来找的
      version: 1.0.2                    # <OPTIONAL> when defined empty, use default as version number
                                        # 并且会自动查找当前路径下所有的npk.yml文件,并作为完整软件包中一部分

## 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信息,不建议随意使用, 
                                        # 可选参数有 nuclei-200-series, nuclei-300-series, nuclei-600-series, nuclei-600-series
                                        # 或者为空
        cmodel:                         # <OPTIONAL> 仅用于表示RISC-V CORE中的CMODEL信息,不建议随意使用,
                                        # 可选参数有 medany/medlow, 其中RV64只能用medany
        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>待拷贝的文件或者文件夹,这里是指所有的目录或者文件
    - path: ["Source/", "Include/", "demosoc.svd"]  # <MUST>待拷贝的文件或者文件夹的路径列表
    - 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编译选项,留空表示没有任何选项
    asmflags:                           # <OPTIONAL> ASM编译选项,留空表示没有任何选项
    cxxflags:                           # <OPTIONAL> CXX编译选项,留空表示没有任何选项
    common_defines:                     # <OPTIONAL> 通用的宏定义
      - defines: __RISCV_FEATURE_DSP=1
        condition: $(${dsp_present} == 1)
      - defines: DOWNLOAD_MODE_STRING=\"flashxip\"
    cdefines:                           # <OPTIONAL> C的宏定义
    asmdefines:                         # <OPTIONAL> ASM的宏定义
    cxxdefines:                         # <OPTIONAL> CXX的宏定义
    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> 选择的工具
    executable: openocd_proxy # <OPTIONAL> 修改executable的路径, 默认就是原来的名称不修改
    launch: cmlink   # <OPTIONAL> 默认为debug, 如果加了launch,就改为对应的launch_type名称
    description: Nuclei OpenOCD         # <MUST> For bsp type
    svd: gd32vf103.svd                  # <OPTIONAL> 可选的SVD文件
    configs:
      - key: config                     # openocd配置文件
        value: "openocd_gd32vf103.cfg"

  - type: qemu                          # 仅支持demosoc,其余SoC不适用
    description: Nuclei QEMU
    svd:
    configs:
       - key: nuclei_core               # Nuclei RISC-V Core
         value: ${nuclei_core}
       - 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: gd32vf103_rvstar

针对 tool类型的npk.yml, 这是比较特殊的类型,文件格式如下所示

name: tool-cmlink
owner: XinShengTech
# os 可以为如下名称
## windows 代表windows 64位
## linux 代表linux 64位
## 后续可能会有其他版本,需要注意扩展性
## 开发者可以上传相同名称的tool-cmlink,但是os不同的包
## 用户在npk包下载的时候,根据当前环境下载合适环境的版本
os: windows
version: 1.0.0
description: CM-IoT CM-Link Proxy Tool
details: CM-IoT CM-Link Proxy Tool
type: tool
keywords:
  - tool
  - cmiot
license: Apache-2.0
homepage: 

## IDE环境变量设置
## 默认变量  tool-cmlink-1.0.0 与 tool-cmlink-1.0.0-rvprof_path
## 额外需要定义变量: tool-cmlink 和 tool-cmlink-rvprof_path 这两个变量需要检查系统中是否已经定义,没有定义则直接定义
##     有定义则按版本号规则进行版本号优先更新,并且定义一个 tool-cmlink-version变量 记录当前组件包在系统中安装的多版本的最高版本号。
##     tool-cmlink 和 tool-cmlink-rvprof_path 也是最高版本号里面的变量
## 每个包存在一个包路径,引用为npk名称-版本号,例如${tool-cmlink-1.0.0}, 
## 其他变量的引用为npk名称-版本号-变量名,例如 ${tool-cmlink-1.0.0-rvprof_path}
## tool-cmlink & tool-cmlink-rvprof_path 均是绝对路径
environment:
  - key: rvprof_path
    # 这里的rvprof_path是绝对路径
    value: bin/cmlink_gdbserver
    description: proxy location
    # 当变量的system值为true时,额外新增一个不带版本号的变量,取最高版本的该变量,例如${tool-cmlink-system_proxy}
    system: true

NPK软件包

Nuclei Studio支持导入包含npk.yml的NPK软件包,软件包目前以zip包的形式存在。

一个合法的NPK软件包如下所示:

  1. 一个zip包中必须包含至少1个npk文件
  2. 包类型的判定:如果包内存在多个类型的npk文件,npk类型判定条件如下
    1. sdk > ssp > bsp > osp > mwp > csp > app
    2. 如果判定出包的类型存在多个相同的npk,则该包不合法,不允许导入,并提示
  3. 该类型的包不允许存在多个该类型的npk文件
  4. 如果是sdk类型的包,则必须包含至少一个ssp和依赖于该sspbsp文件,以及至少一个app类型的文件,允许存在其他类型的包
  5. 如果是其他类型的包,则里面包含的其他npk,必须显式依赖于该包
  6. bdp类型仅能与app类型共存,如果存在bdp类型,则1 bdp + n * app是合法的且n > 1
  7. bdp类型仅用于描述包的类型,方便批量导入一组app软件包, 并且导入的时候检查出包依赖不满足,仅做提示,但不影响导入。

NPK in Nuclei SDK

目前Nuclei SDK已经采用NPK的方式对Nuclei SDK进行了支持,参见 nuclei sdk latest commits.

如下是Nuclei SDK中的NPK文件列表:

# 以下是app类型的npk, 每个application目录下均有一个npk.yml文件用于描述该应用的软件配置信息
./application/baremetal/benchmark/coremark/npk.yml
./application/baremetal/benchmark/dhrystone/npk.yml
./application/baremetal/benchmark/whetstone/npk.yml
./application/baremetal/demo_dsp/npk.yml
./application/baremetal/demo_eclic/npk.yml
./application/baremetal/demo_nice/npk.yml
./application/baremetal/demo_timer/npk.yml
./application/baremetal/helloworld/npk.yml
./application/freertos/demo/npk.yml
./application/rtthread/demo/npk.yml
./application/rtthread/msh/npk.yml
./application/ucosii/demo/npk.yml
# 以下是csp类型的npk, 也就是我们的NMSIS软件,用于描述NMSIS软件包的基本信息
./NMSIS/npk.yml
# 以下是sdk类型的npk, 用于描述Nuclei SDK的基本信息
./npk.yml
# 以下是osp类型的npk, 每个RTOS一个描述文件,描述了RTOS软件包的基本信息
./OS/FreeRTOS/npk.yml
./OS/RTThread/npk.yml
./OS/UCOSII/npk.yml
# 以下是分别是demosoc和gd32vf103的ssp和bsp类型的npk
# 在ssp和bsp类型的npk中提供的描述信息会比较多,请仔细查阅使用
# 如果采用Nuclei SDK的框架移植了SoC,则只需要参考这两个提供的示例npk来创建自己的npk文件
# 如果是我们的子系统客户,在最新的提供出去的SDK中则会提供初步可用的ssp和bsp的npk.yml描述文件,
# 客户后续需要需要再发布,只需要修改里面一些关于SoC和板级的描述信息即可
./SoC/demosoc/Common/npk.yml                          # ssp类型
./SoC/demosoc/Board/nuclei_fpga_eval/npk.yml          # bsp类型
./SoC/gd32vf103/Common/npk.yml                        # ssp类型
./SoC/gd32vf103/Board/gd32vf103c_longan_nano/npk.yml  # bsp类型
./SoC/gd32vf103/Board/gd32vf103c_t_display/npk.yml    # bsp类型
./SoC/gd32vf103/Board/gd32vf103v_eval/npk.yml         # bsp类型
./SoC/gd32vf103/Board/gd32vf103v_rvstar/npk.yml       # bsp类型

如何适配NPK

采用Nuclei SDK框架的场景

如果处理器或者子系统客户采用了Nuclei SDK的框架来开发自己的SDK,则相对会比较容易一些。 只需要参考demosoc或者gd32vf103的支持包中的npk.yml描述文件来编写自己的描述文件即可。

关于如何适配Nuclei SDK,参见 https://doc.nucleisys.com/nuclei_sdk/contribute.html#port-your-nuclei-soc-into-nuclei-sdk

下面进行举例说明:

这里以Nuclei SDK 0.3.7版本为例进行举例说明。

假设你的公司名称为GreenTech, 你的SoC名称为 gt25nv, 适配的开发板为gt25nv_devkit, 采用了我们的n309处理器(rv32imafdc)配置, 并且配置了dsp特性, 并且提供了ilm, flash,flashxip三种下载方式。

并且你之前的SoC代码目录组织结构如下:

<Nuclei-SDK>/SoC/gt25nv/ # 这里SoC下面创建了目录名为gt25nv的目录
|-- Board  # BSP支持包
|   `-- gt25nv_devkit
|       |-- Include # 里面必须提供 nuclei_sdk_hal.h 文件
|       |-- Source
|       |-- npk.yml # bsp类型的npk,描述gt25nv_devkit包
|       `-- openocd_gt25nv.cfg # openocd配置文件
|-- Common # SSP支持包
|   |-- Include
|   |   |-- xxxx.h   # 省略了其他外设头文件
|   |   |-- gt25nv.h # <Device>.h # 必须提供这个文件
|   |   |-- nuclei_sdk_soc.h # 必须提供这个文件
|   |   `-- system_gt25nv.h  # system_<Device.h>
|   |-- Source
|   |   |-- Drivers # 驱动目录
|   |   |-- GCC     # 中断和异常的处理代码
|   |   |-- Stubs   # libc桩函数
|   |   |-- gt25nv_common.c # 一些common用到的函数
|   |   `-- system_gt25nv.c # system_<Device>.c
|   |-- gt25nv.svd # gt25nv的SVD描述文件,方便在IDE中查看寄存器
|   `-- npk.yml # ssp类型的npk,描述gt25nv SoC包
`-- build.mk # Nuclei SDK Build System适配的SoC用makefile

适配ssp的npk.yml

请参考 SoC/demosoc/Common/npk.yml

主要需要修改以下字段:

  • Package Base Information 部分

    ## Package Base Information
    name: ssp-nsdk_gtn25nv  # 必须修改,并且不要和其他package重名,如果是适配nuclei sdk框架,
                            # 建议命令规则为 `ssp-nsdk_yoursoc`, 对于该示例,则建议命名为`ssp-nsdk-gt25nv`
    owner: greentech # 必须修改,修改为公司名称,请不要有任何空格, 注意大小写
    version: 1.0.0 # 建议定义一个版本号,采用SEMVER2.0规则,纯数字
    description: GreenTech GT25NV SoC Support Package # 必须修改为对应的npk描述信息,控制在25字符内
    type: ssp # 不要修改,这个npk就是ssp类型
    keywords: # 按需修改
      - soc
      - risc-v
      - nuclei
    license: Apache-2.0 # 按需修改
    homepage: https://your_website.link # 必须修改为对应SoC产品的官方网站
    
    packinfo:
      core_vendor: Nuclei # 不要修改
      vendor: GreenTech   # 必须修改为对应的公司名称,不要包含任何空格
      name: GT25NV SoC    # 必须修改,修改为SoC的名称,且控制在20字符内
      doc: # 必须修改,下面链接修改为对应的网站或者文件(pdf)相对路径
        website: https://your_website.link       # Website
        datasheet: https://your_datasheet.link   # SoC datasheet
        usermanual: https://your_usermanual.link # User Manual
        extra:
          - uri: # file path or web link
            description: # description
  • Package Dependencies 部分

    ## Package Dependency
    dependencies:
      - name: csp-nsdk_nmsis # 必须保留,这里需要依赖 nuclei/csp-nsdk_nmsis这个npk
        version:      # 可以不填,默认会使用Nuclei SDK中安装的最新的版本,
                      # 如果对版本有特殊要求,可以填写,目前这一块处理还没有做的很完善
        owner: nuclei # 必须填写,这里所依赖的包的owner是nuclei, 如不填写,则默认和该npk owner一致
      - name: sdk-nuclei_sdk
          version:    # 如上version
          owner: nuclei # 必须填写,这里所依赖的包的owner是nuclei, 如不填写,则默认和该npk owner一致
  • Package Configurations部分

    ## Package Configurations
    configuration:
      nuclei_core: # 建议保留使用这个名称,减少后续修改工作量
        default_value: n309  # 必须修改为下面nuclei_core->choices中的某一个name字段内容
        type: choice # 保持不变
        global: true # 保持不变
        description: Nuclei RISC-V Core # 建议控制在15字符内
        choices:
          - name: n309 # 这里采用的是n309的core,修改为n307
            arch: rv32imafdc # arch修改为rv32imafdc
            abi: ilp32d # abi修改为 ilp32d
            tune: nuclei-300-series # 不同系列的tune选项,这里选择300系列
            cmodel: medlow # 32位建议medlow, 64位建议medany
            description: N309 Core(ARCH=rv32imafdc, ABI=ilp32d) # 描述信息对应修改
      nuclei_archext:  # 必须保留,由于配置的处理包含了DSP特性,这里需要提供一个配置项
        default_value: [p] # 默认选中DSP特性,也就是P扩展
        type: multicheckbox
        global: true
        description: Nuclei ARCH Extensions
        choices:
          - name: b
            description: Bitmanip Extension
          - name: p
            description: Packed SIMD Extension
          - name: v
            description: Vector Extension
      stdclib: # 建议保留, 用来选择不同版本的C库
          default_value: newlib_nano
          type: choice
          global: true
          description: Standard C Library
          choices:
          - name: newlib_full
              description: newlib with full feature
          - name: newlib_fast
              description: newlib nano with printf/scanf float
          - name: newlib_small
              description: newlib nano with printf float
          - name: newlib_nano
              description: newlib nano without printf/scanf float
          - name: libncrt_fast
              description: nuclei c runtime library, optimized for speed
          - name: libncrt_balanced
              description: nuclei c runtime library, balanced, full feature
          - name: libncrt_small
              description: nuclei c runtime library, optimized for size, full feature
          - name: libncrt_nano
              description: nuclei c runtime library, optimized for size, no float support
          - name: libncrt_pico
              description: nuclei c runtime library, optimized for size, no long/long long support
          - name: nostd
              description: no std c library will be used, and don't search the standard system directories for header files
          - name: nospec
              description: no std c library will be used, not pass any --specs options
  • Source Code Management部分

    ## Source Code Management
    codemanage:
      installdir: gt25nv # 必须修改,这里修改为和SoC包中名称一致
      copyfiles:         # 需要拷贝的文件或者文件夹列表,相对路径,相对于该ssp的npk.yml的路径
                         # 如果不需要拷贝目录下所有文件用于编译,请自行控制路径
        - path: ["Source/*.c", "Source/Drivers/*.c", "Source/GCC/", "Include/", "gt25nv.svd"]
        - path: ["Source/Stubs/newlib"]
          condition: $( startswith(${stdclib}, "newlib") )
        - path: ["Source/Stubs/libncrt"]
          condition: $( startswith(${stdclib}, "libncrt") )
      incdirs: # 需要用到的头文件相对路径
        - path: ["Include/"]
  • Set Configuration部分

    ## Set Configuration for other packages
    setconfig:
      - config: nmsislibarch
        value: ${nuclei_core.arch}$(join(${nuclei_archext},''))  # 根据arch和选中的扩展来选择对应的nmsis里面算法库
  • Debug Configuration 部分

    ## Debug Configuration for this SoC
    debugconfig:
      - type: openocd # 保持不变
        description: Nuclei OpenOCD # 保持不变
        svd: gt25nv.svd # 修改为对应的svd文件,如果不存在,则留空
      - type: jlink # 如果支持Jlink则可以带上
        description: Segger Jlink
        svd: gt25nv.svd
    # 由于目前QEMU仅支持Nuclei DemoSoC和GD32VF103,所以请不要适用qemu字段
  • Build Configuration 部分

    ## Build Configuration
    buildconfig:
      - type: gcc # 保持不变
        description: Nuclei GNU Toolchain # 保持不变
        cross_prefix: riscv-nuclei-elf- # 保持不变
        common_flags: # flags need to be combined together across all packages
                      # 通用链接选项
                      # 如果没有特殊的编译选项需要统一设置的,可以保持不变
          - flags: -g -fno-common -ffunction-sections -fdata-sections
          - flags: -march=${nuclei_core.arch}$(join(${nuclei_archext},'')) -mabi=${nuclei_core.abi}
          - flags: -mtune=${nuclei_core.tune}
            condition: $( ${nuclei_core.tune} != "" )
          - flags: -mcmodel=${nuclei_core.cmodel}
          # 根据configuration字段的stdclib的选择,选择不同的C Library配置
          - 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: -nostdinc
            condition: $( ${stdclib} == "nostd" )
          - flags:
            condition: $( ${stdclib} == "nospec" )
        ldflags: # 链接选项, 建议如下保持不变
          - flags: -nostartfiles
          - flags: -lstdc++
            condition: $( startswith(${stdclib}, "newlib") )
          - flags: -Wl,--gc-sections -Wl,--check-sections
          - flags: -u _isatty -u _write -u _sbrk -u _read -u _close -u _fstat -u _lseek
            condition: $( startswith(${stdclib}, "newlib") )
        cflags: # C编译相关的选项
        asmflags: # ASM编译相关的选项
        cxxflags: # C++编译相关的选项
        common_defines: # 通用的宏定义,不需要补上-D, Nuclei Studio会自动补全
          - defines:
        # 下面选项是设置Nuclei Studio工程选项里面的C/C++ Build -> Settings -> Build Steps
        prebuild_steps: # could be override by app/bsp type
          command:
          description:
        postbuild_steps: # could be override by app/bsp type
          command:
          description:

适配bsp部分的npk.yml

请参考 SoC/demosoc/Board/nuclei_fpga_eval/npk.yml

主要修改以下字段:

  • Package Base Information部分

    ## Package Base Information
    name: bsp-nsdk_gt25nv_devkit # 必须修改,如果采用nuclei-sdk框架,建议命名规则为 bsp-nsdk_<soc>_<board>
    owner: greentech # 必须修改,这里修改为公司名称,不要有空格, 注意大小写
    description: GreenTech GT25NV DevKit BSP # 必须修改,请修改为合理的描述信息,控制在25字符内
    type: bsp # 保持不变,这里就是bsp类型
    keywords: # 按需修改
      - board
      - risc-v
      - nuclei
    license: Apache-2.0 # 按需修改
    homepage: https://yourboard.homepage # 必须修改,修改为对应开发板的官网
    
    packinfo:
      vendor: GreenTech # 必须修改,这里修改为开发板的提供商名称,不要有空格,注意大小写
      name: GreenTech GT25NV DevKit # 必须修改为开发板的名称,控制在20字符以内
      doc: # 必须修改为满足你开发板需求的链接或者路径
        website: https://yourboard.link # Website
        sch: https://your_sch.pdf # Circuit diagram
        usermanual: https://your_board_usermanual.link # User Manual
        extra: # 按需补充额外的文档或者视频链接,以及对应的说明
          - uri: https://your_uri.link # file path or web link
            description: your description # description
  • Package Dependency 部分

    ## Package Dependency
    dependencies:
      - name: ssp-nsdk_gt25nv # 这里修改需要依赖的ssp的名称,针对本示例为ssp-nsdk_gt25nv
        version: # 如果不需要特定版本,可以不填
        owner: #如不填写,则默认和该npk owner一致, 因为这里依赖的就是本npk相同的owner,因此可以不填
  • Package Configuration 部分

    ## Package Configurations
    configuration:
      download_mode: # 建议保留不变,如果也需要提供不同的链接脚本来控制
        default_value: ilm # 如需修改,这里默认选项必须是download_mode->choices中某个name字段内容
        type: choice
        global: true
        description: Download/Run Mode # 按需修改,如果这里的描述信息不够清楚的话,建议控制在15字符内
        choices: # 按需增删修改
          - name: ilm
            description: ILM download mode, program will be download into ilm/ram and run directly in ilm/ram, program lost when poweroff
          - name: flash
            description: FLASH download mode, program will be download into flash, when running, program will be copied to ilm/ram and run in ilm/ram
          - name: flashxip
            description: FLASHXIP download mode, program will to be download into flash and run directly in Flash
  • Source Code Management 部分

    ## Source Code Management
    codemanage:
      installdir: gt25nv_devkit # 必须修改,建议和SoC目录中名称保持一致
      copyfiles: # 必须修改,设置待拷贝的文件或者文件夹
        - path: ["Source/", "Include/", "openocd_gt25nv.cfg"]
      incdirs:   # 必须修改,设置需要加入头文件的路径
        - path: ["Include/"]
  • Set Configuration 部分

    ## Set Configuration for other packages
    setconfig: # 如果没有特殊需要设置其他package中定义的configuration则不需要定义该字段
  • Debug Configuration 部分

    ## Debug Configuration for this board
    debugconfig:
      - type: openocd # 保持不变
        description: Nuclei OpenOCD # 保持不变
        configs:      # 这里是按照Key-Value形式提供的
          - key: config # 必须提供,且不可修改为其他内容
            value: "openocd_gt25nv.cfg" # 必须修改,且必须提供,用于表示openocd配置文件的路径
                                        # 这里的路径填写相对于该npk.yml的相对路径即可
      # 假设支持JLink, 这里就写上对应的JLink的配置
      - type: jlink
        description: Segger Jlink
        configs:
           - key: device_name
             value: # if leave empty, it will try riscv_arch conversion, otherwise it will directly using this value
           - key: riscv_arch
             value: ${nuclei_core.arch} # arch to device name conversion happened in IDE, eg. rv32imac -> N305
           - key: interface
             value: jtag # jtag or cjtag
           - key: speed
             value: auto  # auto, adaptive, fixed value(KHz) such as 1000
  • Build Configuration部分

    buildconfig:
      - type: gcc # 保持不变
        linkscript: # 下面提供对应的链接脚本,这里使用到了前面定义的download_mode变量
          - script: "Source/GCC/gcc_gt25nv_${download_mode}.ld"  # 这里需要注意文件必须真实存在,且符合这里的命名规则
        common_flags: # 如果有额外的通用编译选项,请在这下面flags中提供
          - flags:
        common_defines: # 如果有额外的通用宏定义选项,请在defines中提供
          - defines: DOWNLOAD_MODE=DOWNLOAD_MODE_$(upper(${download_mode})) # 建议提供
          - defines: DOWNLOAD_MODE_STRING=\"$(upper(${download_mode}))\" # 必须提供
          - defines: VECTOR_TABLE_REMAPPED # 按需提供,这里是如果download_mode选择为flash,则定义该宏
            condition: $( ${download_mode} == "flash" ) # 关于VECTOR_TABLE_REMAPPED定义请参见Nuclei SDK文档

在构建了上面提到的sspbsp后,可以将整个SoC/gt25nv目录打包成zip包即可导入到IDE中, 前提是必须先导入Nuclei SDK对应版本的package。

如果测试稳定,没有问题也可以给rvmcu社区贡献软件包, 这样的话,开发者就可以直接通过IDE上在线下载软件包使用。

如果是我们子系统的客户,NPK功能发布以后提供的SDK里面就带上了npk.yml文件,可以直接把SDK直接打包成zip, 导入到IDE中即可,但是如果IDE中已经导入了nuclei sdk package,则会提示是否覆盖的信息,点覆盖即可。

完全自己创建的SDK场景

针对该场景,建议构建出一个自己的SDK,里面至少包含一个sdk, 一个ssp,一个bsp以及若干app的npk类型。

需要注意的是,这里npk.yml中的name字段内容需要保持唯一性,请仔细确认检查。

其中sdk文件只能有一个,ssp,bspapp可以有若干,如果不想拆分很细, 可以将csp部分和ssp整合在一起,而ospmwp可以和ssp或者bsp整合在一起。

如果整个SDK构建完毕后,只需要将整个SDK打包成zip文件,然后即可导入到IDE中使用,也可以创建基于该SDK的示例app。

如何在Nuclei Studio中使用NPK

假设你是我们的评估客户或者gd32vf103用户,需要使用到nuclei sdk中提供的demosoc或者g32vf103支持包, 则请下载最新的0.3.7以及后续版本的代码zip包,参见 https://github.com/Nuclei-Software/nuclei-sdk/releases/

下载zip包完毕后,假设文件名为 nuclei-sdk-0.3.7.zip, 打开我们Nuclei Studio 2022.04版本后 在菜单栏选择 RV-Tools -> SDK Manage,在弹出的窗体中进行包的导入,请不要导入非NPK类型的包。

  • 如果有自己适配好的SoC包和SoC的Examples,则只需要将自己的SoC包和Examples一起打包成zip,导入进来即可
  • 如果是SoC子系统客户,直接可以把完整的SDK打包,导入即可使用

在导入完毕后,点击File -> New -> New Nuclei RISC-V C/C++ Project后会弹出如下窗体, 选择对应的SoC和开发板即可进入下一个页面选择可以创建的示例工程。

输入Project Name,选择对应的示例工程后,选择其他的选项,即可创建好对应的示例工程, 工程的创建全部是按照前面npk文件中描述的信息,进行对应的创建。如下图所示:

右键选中工程后,即可Clean Project或者是Build Project,在Properties里面可以进行工程的配置。

在Launch Bar区域可以选择预先创建的openocd调试配置,进行调试和程序的下载工作。

关于Nuclei Studio进一步的使用,请参见Nuclei Studio安装目录下的用户手册。