电子产业一站式赋能平台

PCB联盟网

搜索
查看: 158|回复: 0
收起左侧

HPM6E00 EVK 在 Linux 系统下的工具链(C/Rust)

[复制链接]

732

主题

732

帖子

3482

积分

四级会员

Rank: 4

积分
3482
发表于 2024-8-17 11:08:00 | 显示全部楼层 |阅读模式

wj1fnmfqklc6409850612.jpg

wj1fnmfqklc6409850612.jpg

6月底听到先楫出了带 EthcerCAT ESC 的MCU,Rust 嵌入式群里的大神也第一时间做了 Rust 和 Embassy 的支持,心心念念了一个月,终于下决心购买了。
官方提供的是 Windows 的 SDK,我主要用 Linux ,所以先折腾一下工具链。
CPU 特性
HPM6E00 系列 MCU 使用的是 Andes D45 的 IP Core,数据手册上的内核特性是这样的

fvn5svefxdy6409850712.png

fvn5svefxdy6409850712.png

标准 GNU 工具链
GNU 工具链从这里 https://github.com/hpmicro/riscv-gnu-toolchain 或者这里 https://github.com/riscv-collab/riscv-gnu-toolchain  clone 下来,

pgqiggnhkqb6409850812.png

pgqiggnhkqb6409850812.png

先楫的库跟上游库只是落后了 9 个 commits,没有任何自己的修改,我就直接从 risc-collab 上 clone 了。
仓库 README 里有描述要先安装哪些编译依赖,因为我的系统中都安装过了,就不需要执行这一步。读者可以根据自己的情况选择安装。

qnnziuvsua06409850912.png

qnnziuvsua06409850912.png

进入仓库目录
第一个方案
  • git cone https://github.com/riscv-collab/riscv-gnu-toolchain.gitcd riscv-gnu-toolchaingit checkout 2024.04.12 -b 2024_04_12./configure --prefix=$(dirname $PWD)/local --with-arch=rv32gc --with-abi=ilp32dmake # 不需要 make install这里 rv32gc 里的 'g' 指的是'i', 'm', 'a', 'f', 'd', 'zicsr', 'zifencei',解释在这里 https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html。
    若不使用 --with-arch=rv32gc ,则默认生成的工具链以 riscv64 前缀,而 hpm_sdk 工具链需要寻找 riscv32 前缀的工具链,所以必须要添加此参数。
    使用 make 是单线程构建,可以使用 make -j4 或者 make -j`nproc` 来启用多核编译,但是多核编译极耗内存,要看自己的内存情况来启用,别玩崩了。

    0ju33csptwm6409851012.png

    0ju33csptwm6409851012.png

    编译完成之后会在此目录的上一级建立 local 目录,保存了工具链的资料。将工具链目录(***/local/bin)加入 PATH 之后,可以执行
  • riscv32-unknown-elf-gcc --help=target# 或者riscv32-unknown-elf-gcc --target-help得到如下输出
  • The following options are target specific:  -mabi=                                ilp32d  -malign-data=                         xlen  -march=                               rv32imafdc_zicsr_zifencei  -mbig-endian                          [disabled]  -mbranch-cost=N                       3  -mcmodel=                             medlow  -mcpu=PROCESSOR  -mcsr-check                           [disabled]  -mdiv                                 [enabled]  -mexplicit-relocs                     [enabled]  -mfdiv                                [enabled]  -minline-atomics                      [enabled]  -misa-spec=                           20191213  -mlittle-endian                       [enabled]  -mplt                                 [enabled]  -mpreferred-stack-boundary=           0  -mrelax                               [enabled]  -mriscv-attribute                     [enabled]  -msave-restore                        [disabled]  -mshorten-memrefs                     [enabled]  -msmall-data-limit=N                  8  -mstack-protector-guard-offset=  -mstack-protector-guard-reg=  -mstack-protector-guard=              global  -mstrict-align                        [enabled]  -mtune=PROCESSOR                      rocket
      Supported ABIs (for use with the -mabi= option):    ilp32 ilp32d ilp32e ilp32f lp64 lp64d lp64f
      Known code models (for use with the -mcmodel= option):    medany medlow
      Supported ISA specs (for use with the -misa-spec= option):    2.2 20190608 20191213
      Known data alignment choices (for use with the -malign-data= option):    natural xlen
      Valid arguments to -mstack-protector-guard=:    global tls
      Known valid arguments for -mcpu= option:    sifive-e20 sifive-e21 sifive-e24 sifive-e31 sifive-e34 sifive-e76 sifive-s21 sifive-s51 sifive-s54 sifive-s76 sifive-u54 sifive-u74 thead-c906
      Known valid arguments for -mtune= option:    rocket sifive-3-series sifive-5-series sifive-7-series thead-c906 size sifive-e20 sifive-e21 sifive-e24 sifive-e31 sifive-e34 sifive-e76 sifive-s21 sifive-s51 sifive-s54 sifive-s76 sifive-u54 sifive-u74 thead-c906
    这里的结果是仅支持 rv32gc 目标, ilp32d abi 的工具链。为了开发 HPM6E00 已足够。
    编译 Hello World
    准备 hpm-sdk: https://github.com/hpmicro/hpm_sdk
    我习惯使用 pipenv 准备 python 环境,进入 hpm_sdk 目录,执行
  • pipenv shellpip install -r scripts/requirements.txt进入 建立目录 hpm_sdk/samples/hello_world/build 并进入,执行
  • cmake -DBOARD=hpm6e00evk -DRV_ARCH=rv32gc -DRV_ABI=ilp32d ..make # 或者 make -j`nproc`# 如果愿意并且安装了 ninja ,可以执行cmake -GNinja -DBOARD=hpm6e00evk -DRV_ARCH=rv32gc -DRV_ABI=ilp32d ..ninja

    orpfe3r0enj6409851112.png

    orpfe3r0enj6409851112.png

    这里使用 -DRV_ABI=ilp32d -DRV_ARCH=rv32gc 是因为在
    hpm_sdk/cmake/application.cmake 中默认使用了 ilp32 / rv32imac 的架构,我们现在使用的工具链不支持

    xgqbqa1z0006409851213.png

    xgqbqa1z0006409851213.png

    编译OpenOCD
    准备 openocd: https://github.com/hpmicro/riscv-openocd
    如果没有安装 libftdi,需要先安装,如
  • sudo apt install libftdi-dev # 其他系统自己换成对应的包管理方式即可
  • git clone https://github.com/hpmicro/riscv-openocd.gitcd riscv-openocd./bootstrap./configure --prefix $(dirname $PWD)/local --enable-ftdi --enable-cmsis-dap-v2 --enable-cmsis-dap# 或者 ./configure --prefix $(dirname $PWD)/local --enable-ftdi --enable-ftdi-lscan1 --enable-ti-icdi --enable-xds110 --enable-cmsis-dap-v2 --enable-cmsis-dapmake -j`nproc`make install此时,openocd 会被安装到 riscv-openocd 的上一级目录的 local 下,如果riscv-openocd 与 riscv-gnu-toolchain 在一起的话,toolchain 和 openocd 也会被安装在同一个 local 下,这样就不需要多指定一个 PATH 路径了。
    在命令行设置或者创建一个 shell 脚本来设置环境变量:
  • HPMICRO_ROOT=$EMBEDDED_ROOT/hpmicroexport HPM_SDK_BASE=$HPMICRO_ROOT/hpm_sdkexport PATH=$HPMICRO_ROOT/local/bin:$PATHexport OPENOCD_SCRIPTS=$HPMICRO_ROOT/hpm_sdk/boards/openocdexport GNURISCV_TOOLCHAIN_PATH=$HPMICRO_ROOT/local具体路径,需要按照实际的路径设置。
    接入开发板的USB,kernel 会有如下显示

    ajonh004nab6409851313.png

    ajonh004nab6409851313.png

    执行如下命令
  • openocd -f probes/ft2232.cfg -f soc/hpm6e80-dual-core.cfg -f boards/hpm6e00evk.cfg正确的输出如下

    fp2hlwou4lr6409851413.png

    fp2hlwou4lr6409851413.png

    进入到刚才的编译目录 hpm_sdk/samples/hello_world/build/
    执行 riscv32-unknown-elf-gdb
  • target extended-remote :3333file output/demo.elfloadb mainc我这里串口程序使用的是
  • picocom -b 115200 /dev/ttyUSB1

    up2hqfhldqf6409851513.png

    up2hqfhldqf6409851513.png

    这里有一个事情要注意,hpm_sdk 的例程默认使用了加载到内存地址空间( 起始地址 0x0000_0000,如果因为某些原因烧写了程序在 flash 地址 (0x8000_0000),会导致 openocd 加载成功之后也不能正确执行。
    这种情况,需要擦除掉 flash 区域才可以,例如使用如下 openocd 指令(在 gdb 下)
  • mon flash erase_sector bank_id first_sector_num (last_sector_num|'last')也可以通过
  • cmake -GNinja -DBOARD=hpm6e00evk -DHPM_BUILD_TYPE=flash_xip ..来使编译工具链把程序链接到 flash 区域
    GNU Toolchain - Multilib

    可以生成 multilib 方式,将支持的多种不同架构的。对于开发 HPM6E00 不是必需。如果想用此工具链支持多种 riscv 开发的话,可以使用此选项。

    只需要在 riscv-gnu-toolchain 目录下执行的 configure 一句更改为
  • ./configure --prefix $(dirname $PWD)/local --with-arch=rv32gc --with-abi=ilp32d --with-multilib-generator="rv32imac-ilp32--;rv32imafdc-ilp32d--",再进行如前所述的编译过程即可。注意,如果之前编译过,请执行
  • make clean否则不会进行编译。
    相应的,在编译 hello world 例程时,只需要
  • cmake -GNinja -DBOARD=hpm6e00evk ..即可,就会使用配置默认的 rv32imac 架构来进行编译(即,不支持硬件 float )。
    Andes / NDS Toolchain
    提供的仓库地址在这里:https://github.com/andestech/nds-gnu-toolchain
  • git clone https://github.com/andestech/nds-gnu-toolchain.git -b ast-v5_3_1-release-v5cd nds-gnu-toolchain./build_elf_toolchain.sh# 有时下载的文件不能通过 checksum,可以删除之后再执行# 可以通过 gcc/contrib/build_elf_toolchain.sh 检验是否是因为下载文件不通过而编译失败./nds32le-elf-newlib-v5/bin/riscv32-elf-gcc --target-help在之前的环境变量的基础上做如下修改
  • export GNURISCV_TOOLCHAIN_PATH=$HPMICRO_ROOT/nds-gnu-toolchain/nds32le-elf-newlib-v5export HPM_SDK_TOOLCHAIN_VARIANT=nds-gcc回到 hpm_sdk/samples/hello_world/build 下,删除所有文件,重新执行
  • cmake -GNinja -DBOARD=hpm6e00evk ..可以检查 CMake 是否正确找到了对应的版本:

    rjxozotrqv16409851613.png

    rjxozotrqv16409851613.png

    其他执行如前所述。
    Rust 工具链
    首先要感谢 andelf / 王 Mono 大神的付出,对 HPM 全系列产品做了 Rust 支持!
    目前 Rust 的 RV32 对应的 target有
  • riscv32i-unknown-none-elfriscv32im-unknown-none-elfriscv32imac-unknown-none-elfriscv32imafc-unknown-none-elfriscv32imc-unknown-none-elf也就是说,现在没有 target 支持 hard double float 指令扩展。或许以后找时间自己建立一个支持 riscv32gc 的 target 吧。
    这里我选择了 riscv32imafc-unknown-none-elf,可以通过
  • rustup target add riscv32imafc-unknown-none-elf来安装此工具链。
    按照 https://github.com/hpmicro-rs/hpm-hal.git 的说明文档,目前需要指定一个特定的 nightly 版本才可以:
  • rustup default nightly-2024-06-12通过执行
  • cargo install probe-rs-tools --git https://github.com/hpmicro-rs/probe-rs --branch hpmicro --locked来安装 probe-rs 调试器工具。或者使用之前的 openocd 也是可以的。
  • git clone https://github.com/hpmicro-rs/hpm-hal.gitcd hpm-hal/examples/hpm6e00evk在 hpm-hal/examples/hpm6e00evk/.cargo/config.yaml 文件里,默认指定使用 gdb / openocd 来运行程序,而且文件里使用的是 riscv64- 为前缀的工具链,为了与 hpm_sdk 使用的 riscv32- 前缀的工具链兼容,这里需要修改。
    或者安装了 probe-rs,可以把 gdb / openocd 的一行注释掉,取消注释下面的 probe-rs 行,这样
  • cargo run --bin blinky即可以在开发板上运行 rust 程序了。

    bsyr5tf0weu6409851713.png

    bsyr5tf0weu6409851713.png

    这里再提一遍,因为 rust 程序是链接到 flash 上的而 hpm-sdk 是默认链接到 ram 上的,所以如果在从 flash 方式切换到 ram 方式的话,就需要擦除 flash 再加载 ram。这里我重复提及,是因为自己在这上面半天时间。

    注意:如果想第一时间收到 KiCad 内容推送,请点击下方的名片,按关注,再设为星标。
    常用合集汇总:
  • 和 Dr Peter 一起学 KiCad
    KiCad 8 探秘合集
    KiCad 使用经验分享KiCad 设计项目(Made with KiCad)常见问题与解决方法KiCad 开发笔记插件应用
    发布记录
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表