【沁恒微CH32V307评估板试用体验】探索Rust编程语言的嵌入式开发——基于CH32V307【1】 - RISC-V MCU技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

朱工 关注 私信
[文章]

【沁恒微CH32V307评估板试用体验】探索Rust编程语言的嵌入式开发——基于CH32V307【1】

1 总述
Rust语言的运行效率高、开发效率好、适用范围广。作为一门编译型语言,它直接编译输出到汇编代码,通常公认裸机的Rust语言性能在C语言级别,拥有较高的运行效率。Rust语言的开发效率很高,文档完善、编译器提示有帮助,能节省软件开发所需的时间。它能应用在多个平台和指令集中,这包括裸机平台;处理核、操作系统厂家还可以提供自己的编译目标,无需厂家自己重新开发、提供工具链。
本着学习至上的精神,开始学习,并在开发板编写并运行了最简单的Rust程序代码;并通过对Rust-EmbeddedDiscovery Book()进行CH32V307的移植与翻译;
2 Rust开发环境的搭建安装
2.1 安装RustupCargo
windows系统中,从官网下载rustup-init.exe,由于默认的msvc需要Visual Studio,所以本机采用mingw的版本,只需要安装MinGWgcc编译器即可,此部分略过;
然后在rustup-init.exe运行选项中,选择x86_64-pc-windows-gnutoolchain可以选择stable/nightlyprofile可以选择default/completePATH环境变量可以选择修改或者不修改,然后选择安装即可。
1 rust安装选项设置.png
21  rust安装选项设置
如果选择不将%USERPROFILE%.cargobin加入PATH环境变量中,则每次在启动命令提示符cmd的时候,都需要执行一次set PATH=%PATH%;%USERPROFILE%.cargobin,这样才能调用cargorustc等命令。使用rustc -V可以查看版本号。
安装配置完毕,写个hello worldcmd窗口中输入
cargo new hello_world
cd hello_world
cargo build
cargo run
可以看到生成了HelloWorld”;
2 rust hello_world项目的创建、编译和运行.png
22  rust hello_world项目的创建、编译和运行
自动生成的hello_worldsrcmain.rs代码如下:
fn main() {
    println!("Hello, world!");
}
2.2 安装Rustriscv32target
cargorust安装好之后,需要安装适用于CH32V307CPU内核:riscv32imac)的rust库,在此之前需要修改cargo的镜像源,使其从国内镜像源下载,网速更快;
# 放到 `$HOME/.cargo/config` 文件中
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"

# 替换成你偏好的镜像源
replace-with = 'tuna'
#replace-with = 'ustc'

# 清华大学
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

# 中国科学技术大学
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"

# 上海交通大学
[source.sjtu]
registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index"

# rustcc社区
[source.rustcc]
registry = "git://crates.rustcc.cn/crates.io-index"
然后依次输入如下命令:
        rustup target list
        rustup target add riscv32imac-unknown-none-elf
        Set PATH=%PATH%;%PATH_TO_RISCV32-UNKNOWN-ELF-GCC%;%PATH_TO_MINGW_GCC%
        cargo install cargo-binutils
        rustup component add llvm-tools-preview
        cargo install cargo-generate
其中%PATH_TO_RISCV64-UNKNOWN-ELF-GCC%是系统安装的编译riscv64-unknown-elf-gcc的目录路径,%PATH_TO_MINGW_GCC%是系统安装的MinGW-gcc编译器的目录路径。在linux或者msys2系统中,则改为export PATH=$PATH:$PATH_TO_RISCV64-UNKNOWN-ELF-GCC
3 Rust安装riscv32系列工具.png
23  rust安装riscv32系列工具
至此rust用于riscv32的开发环境全部搭建完毕;

2.3 测试Rust-riscv32开发环境的简易例程
直接采用cargo复制官方的riscv-rust-quickstart例程模板,执行命令
cargo generate --git https://github.com/riscv-rust/riscv-rust-quickstart
4 复制riscv-rust-quickstart例程.png
24  复制riscv-rust-quickstart例程
由于该例程模板是针对Hifive系列开发板的,因此需要做少量修改,
srcmain.rs修改如下:
#![no_std]
#![no_main]

extern crate panic_halt;

// use hifive1::hal::prelude::*;
// use hifive1::hal::DeviceResources;
use riscv_rt::entry;

#[entry]
fn main() -> ! {
    let _y;
    let x = 42;
    _y = x;

    // infinite loop; just so we don't leave this stack frame
    loop {}
}
.cargoconfig修改为:
[target.riscv32imac-unknown-none-elf]
runner = "riscv-none-embed-gdb -q -x gdb_init"
rustflags = [
  "-C", "link-arg=-Tmemory.x",
  "-C", "link-arg=-Tlink.x",
]

[build]
target = "riscv32imac-unknown-none-elf"
在目录下创建memory.x,将CH32V307的芯片存储布局的FlashRAM等起始地址和大小确定:
MEMORY
{
  /* NOTE 1 K = 1 KiBi = 1024 bytes */
  /* TODO Adjust these memory regions to match your device memory layout */
  /* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
  FLASH : ORIGIN = 0x00000000, LENGTH = 256K
  RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
REGION_ALIAS("REGION_TEXT", FLASH);
REGION_ALIAS("REGION_RODATA", FLASH);
REGION_ALIAS("REGION_DATA", RAM);
REGION_ALIAS("REGION_BSS", RAM);
REGION_ALIAS("REGION_HEAP", RAM);
REGION_ALIAS("REGION_STACK", RAM);
然后执行 cargo build,即可完成例程的编译构建,最后在riscv-rust-quickstarttargetriscv32imac-unknown-none-elfdebug目录下生成了elf可执行文件。
为了调试,必须使用OpenOCD作为调试服务器,将gdb的调试命令转换为WCH-Link调试器的序列,因此在新的命令提示符窗口,参照MounRiver Studio调用OpenOCD的命令行,执行如下命令:
D:DevToolsMounRiverMounRiver_Studiotoolchain/OpenOCD/bin/openocd.exe -c "gdb_port 3333" -c "telnet_port 4444" -c "tcl_port 6666" -f D:DevToolsMounRiverMounRiver_Studiotoolchain/OpenOCD/bin/wch-riscv.cfg -c "echo "Started by CMD""


5  riscv-rust-quickstart例程的OpenOCD命令.png
25  riscv-rust-quickstart例程的OpenOCD命令
然后用gdb调试,命令如下:
riscv-none-embed-gdb riscv-rust-quickstart
并在gdb中执行
target remote 127.0.0.1:3333
load
b main
c
print _y
n
print _y
可以看到,在执行了_y = x; 这条代码之后,_y的值从初始值242变成了42,符合代码的预期,例程成功完成;
6  riscv-rust-quickstart例程的gdb调试截图.png
26  riscv-rust-quickstart例程的gdb调试截图

回帖(1)

james

2022-7-22 17:32:45
高手,最近也打算学习学习rust开发嵌入式的

更多回帖

×
发帖