瑞萨单片机william hill官网
直播中

jf_50393217

4年用户 200经验值
擅长:可编程逻辑 嵌入式技术
私信 关注

【瑞萨RA4系列开发板体验】4. 将RA4M2工程移植到 GN + Ninja构建系统,使用VSCode进行后续开发

一、为什么我喜欢用GN + Ninja来完成单片机项目的构建工作

自从2020年12月接触OpenHarmony后,就开始对GN + Ninja的构建系统非常感兴趣。然后自己尝试着借鉴OpenHarmony的构建系统做了纯GN + Ninja实现的mcu构建系统,并借鉴了buildroot的envsetup.sh脚本,制作了简化构建命令和切换开发板的脚本。

为什么我会坚持用GN + Ninja 作为构建系统呢?主要是 GN + Ninja 构建系统有以下几个优点:

  1. 超快的构建和编译速度(吊打makefile、scons,比CMake快一点点)
  2. GN配置文件可读性更强,配置也灵活
  3. 编译配置通过命令可以直接查询,也可以在生成的Ninja构建工程里验证。
  4. 组件依赖可以查询,依赖层级通过各组件的BUILD.gn文件直接看到
  5. 使用相对路径,项目灵活性高
  6. 配置好组件后,移植新板子的工作比makefile简单

GN + Ninja 构建系统的缺点

  1. 严重缺乏中文教程和文档(需要自行阅读英文文档和help,上手难度较高)
  2. 跨平台支持并不是非常好(win下的路径和命令格式都和Linux有区别)

口说无凭,我们可以看一下实际的效果

全新编译大约260个文件的(已清理过编译产物),包含腾讯TinyOS内核以及LVGL的项目,耗时仅需要5.12秒。在配置比较老的机子(例如6年前的I5处理器),也可以做到30秒内完成全新编译。开启ccache后,几乎任意电脑都可以在0.5秒内完成。

time.png

该工程大致组件和资源占用情况如图

psize.png

如何查看工程的编译参数和依赖(已添加注释)

$ mdesc
// 目标配置和工具链
Target //hardware/board/ra4m2_dev:ra4m2_dev
type: executable
toolchain: //build/toolchain:arm_none_eabi_gcc

// 这里省略了一些没用的信息

// 使用到的build目录的config内容
configs (in order applying, try also --tree)
  //build/config:compiler
  //build/config/Renesas:ra4m2
  //build/config/Renesas:default

// 编译产物最终路径和名称
outputs
  //out/ra4m2_dev/bin/ra4m2_dev

// 汇编文件编译选项
asmflags
  -mcpu=cortex-m33
  -mthumb
  -mfloat-abi=hard
  -mfpu=fpv5-sp-d16
  -g
  -x
  assembler-with-cpp

// C源码文件编译选项
cflags
  -mcpu=cortex-m33
  -mthumb
  -mfloat-abi=hard
  -mfpu=fpv5-sp-d16
  -g
  -O2
  -fmessage-length=0
  -fsigned-char
  -ffunction-sections
  -fdata-sections
  -fdiagnostics-color=always
  -fno-builtin
  -fno-strict-aliasing
  -Wunused
  -Wuninitialized

cflags_c
  -MP
  -MD
  -std=gnu99

cflags_cc
  -std=c++11

// 公共宏定义
defines
  LV_CONF_INCLUDE_SIMPLE
  D_RA_CORE=CM33
  D_RENESAS_RA_

// 公共头文件目录
include_dirs
  //applications/dummy/
  //drivers/include/
  //components/lvgl/v8.3/
  //components/cli/include/
  //hardware/board/ra4m2_dev/
  //hardware/chip/ra4m2/ra/fsp/inc/
  //hardware/chip/ra4m2/ra/fsp/inc/api/
  //hardware/chip/ra4m2/ra/fsp/inc/instances/
  //hardware/chip/ra4m2/ra/arm/CMSIS_5/CMSIS/Core/Include/
  //hardware/board/ra4m2_dev/src/
  //hardware/board/ra4m2_dev/ra_cfg/fsp_cfg/
  //hardware/board/ra4m2_dev/ra_cfg/fsp_cfg/bsp/
  //hardware/board/ra4m2_dev/ra_gen/

// 链接选项
ldflags
  -mcpu=cortex-m33
  -mthumb
  -mfloat-abi=hard
  -mfpu=fpv5-sp-d16
  -g
  -O2
  -T
  ../../hardware/chip/ra4m2/ra/fsp.ld
  --specs=rdimon.specs
  -nostartfiles
  -Xlinker
  --gc-sections

// 依赖树
Direct dependencies (try also "--all", "--tree", or even "--all --tree")
  //hardware/board/ra4m2_dev:bsp
  //hardware/chip/ra4m2:ra4m2_sdk

二、GN + Ninja 构建流程

  1. 通过命令行指定的product参数加载板级配置文件BUILD.gn和product.gni(hardware/board/${product}目录下)
  2. 使用product.gni的配置,配置工具链(product.gni负责传递参数,build目录的配置文件进行相关配置)
  3. 使用BUILD.gn的配置,生成依赖树,并检查按依赖顺序依次检查目标的c文件,生成ninja配置
  4. 调用ninja命令开始构建并完成编译构建工作
2.1 新建product目录(板级支持)并编写BUILD.gn和product.gni配置文件

board.png

BUILD.gn文件的配置内容

# Executable for board   --------------------------------------------------
#
# Executable target configuration.
#
# Setting up configeration fot chip and board.
executable("ra4m2_dev") {
  # Common deps for executable target.
  # --------------------------------
  deps = [
    ":bsp",
    "//hardware/chip/${chip}:${chip}_sdk",
  ]

  # 开启RTOS内核支持,因目前未适配暂时不开启
  # deps += [ "//kernel/TinyOS:kernel" ]
  
  # 如果需要依赖工具链自带的库,用下面的写法,自定义库需要使用相对路径
  # libs = [ "printf" ]
}

# 板级配置目录
# --------------------------------
source_set("bsp") {
  sources = [
    "ra_gen/common_data.c",
    "ra_gen/hal_data.c",
    "ra_gen/main.c",
    "ra_gen/pin_data.c",
    "ra_gen/vector_data.c",
    "src/hal_entry.c",
  ]
}

product.gni文件配置内容

declare_args() {
  # 工具链名称(指向build/toolchain/arm_none_eabi_gcc.gni)
  # --------------------------------
  compiler = "arm_none_eabi_gcc"

  # gcc,检测工具链用
  # --------------------------------
  gcc = "arm-none-eabi-gcc"

  # 芯片型号
  # --------------------------------
  chip = "ra4m2"

  # 厂商
  # --------------------------------
  vendor = "Renesas"

  # 应用
  # --------------------------------
  app = "dummy"

  # RTOS内核
  # --------------------------------
  kernel = "None"

  # bin类型
  # --------------------------------
  build_type = "release"

  # ccache缓存是否开启
  # --------------------------------
  ccache = true
}

然后板级支持这边是搞定了,接下来搞芯片级支持目录

2.2 新建chip目录(芯片级支持)并编写BUILD.gn配置文件

chip.png

新建hardware/chip/ra4m2目录,并拷贝示范代码(e2 studio生成的)里的ra目录到该目录下。然后编写BUILD.gn文件。
路径为hardware/chip/ra4m2/BUILD.gn

文件内容为(可以在e2 studio 里清理构建后重新构建一次,拷贝需要编译的c文件列表)

source_set("ra4m2_sdk") {
  sources = [
    "ra/fsp/src/bsp/cmsis/Device/RENESAS/Source/startup.c",
    "ra/fsp/src/bsp/cmsis/Device/RENESAS/Source/system.c",
    "ra/fsp/src/bsp/mcu/all/bsp_clocks.c",
    "ra/fsp/src/bsp/mcu/all/bsp_common.c",
    "ra/fsp/src/bsp/mcu/all/bsp_delay.c",
    "ra/fsp/src/bsp/mcu/all/bsp_group_irq.c",
    "ra/fsp/src/bsp/mcu/all/bsp_guard.c",
    "ra/fsp/src/bsp/mcu/all/bsp_io.c",
    "ra/fsp/src/bsp/mcu/all/bsp_irq.c",
    "ra/fsp/src/bsp/mcu/all/bsp_register_protection.c",
    "ra/fsp/src/bsp/mcu/all/bsp_rom_registers.c",
    "ra/fsp/src/bsp/mcu/all/bsp_sbrk.c",
    "ra/fsp/src/bsp/mcu/all/bsp_security.c",
    "ra/fsp/src/r_ioport/r_ioport.c",
  ]
}

接下来把示范代码(e2 studio生成的)里的 script/fsp.ld 和 Debug/memory_regions.ld 拷贝到 hardware/chip/ra4m2/ra目录下

然后修改hardware/chip/ra4m2/ra/fsp.ld文件的第5行,将memory_regions.ld的相对路径补全,否则链接时会失败。

/*
                  Linker File for Renesas FSP
*/

INCLUDE ../../hardware/chip/ra4m2/ra/memory_regions.ld

然后板级配置就完成了。

2.3 新建build目录里的芯片支持

创建目录和文件,配置文件的路径是build/config/Renesas/BUILD.gn(默认会去build/config/{vendor}/ 路径查找位置,vendor 参数由板级支持的product.gni文件提供)

build/config/Renesas/BUILD.gn的具体配置,可以从e2 studio 的示范代码里,查看makefile挖出来。主要是需要设置芯片类型,浮点支持,以及链接脚本,公共头文件等内容。

config("default") {
  defines = [
    "D_RA_CORE=CM33",
    "D_RENESAS_RA_",
  ]
  cflags = []
  cflags += [
    "-fmessage-length=0",
    "-fsigned-char",
    "-ffunction-sections",
    "-fdata-sections",
    "-fdiagnostics-color=always",

    # "-fno-common",
    "-fno-builtin",
    "-fno-strict-aliasing",
  ]
  cflags += [
    "-Wunused",
    "-Wuninitialized",
  ]
  ldflags = [
    "-nostartfiles",
    "-Xlinker",
    "--gc-sections",
  ]
  asmflags = [
    "-x",
    "assembler-with-cpp",
  ]
}

config("ra4m2") {
  cflags = [
    "-mcpu=cortex-m33",
    "-mthumb",
    "-mfloat-abi=hard",
    "-mfpu=fpv5-sp-d16",
  ]
  asmflags = cflags
  cflags += [
    "-g",
    "-O2",
  ]
  asmflags += [ "-g" ]
  cflags_c = [ "-std=gnu99" ]
  cflags_cc = [ "-std=c++11" ]
  ldflags = cflags
  ldflags += [
    "-T",
    "../../hardware/chip/${chip}/ra/fsp.ld",
    "--specs=rdimon.specs",
  ]
  include_dirs = [
    "//hardware/chip/${chip}/ra/fsp/inc",
    "//hardware/chip/${chip}/ra/fsp/inc/api",
    "//hardware/chip/${chip}/ra/fsp/inc/instances",
    "//hardware/chip/${chip}/ra/arm/CMSIS_5/CMSIS/Core/Include",
    "//hardware/chip/${chip}/ra/fsp/inc/api",
    "//hardware/board/${product}/src",
    "//hardware/board/${product}/ra_cfg/fsp_cfg",
    "//hardware/board/${product}/ra_cfg/fsp_cfg/bsp",
    "//hardware/board/${product}/ra_gen",
  ]
}

添加完毕后,就可以愉快的编译啦。

编译测试

在命令行进入 git clone 下来的目录,运行以下指令加载环境
source build/envsetup.sh
若之前有配置好产品目标,则按上一次配置目标配置环境,并显示相关信息。

image.png

接下来运行 lunch 选择产品,ra4m2_dev

image.png

选择产品后会输出相关信息,并检查gn、ninja、工具链是否安装,对应路径(没安装的需要自行手动安装)

然后运行mbuild就可以开始编译了,因为文件非常少,2秒左右就完成了(ccache 命中缓存仅需 0.5秒以内)。

image.png

查看编译产物的目录,可以看到成功生成了bin、elf等文件

image.png

使用psize命令查看资源汇总使用情况,也和e2 studio 示范项目的资源使用情况差不多(flash部分的组件占用信息分析错误,需要再调整map分析代码)

image.png


开源项目链接地址: 死龙的MCU游乐场

回帖(1)

华仔stm32

2023-4-22 06:13:10
这个非常好的项目呀,openharmony好象是这个构建的,就是上手有点难,劝退N多新手呀。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分