RUST:第二篇 RUST在嵌入式中的编程(STM32)
究极懒狗,这个本来应该是一年前就要写的。
前言
说实话,并不看好rust在嵌入式领域的未来,嵌入式里面C/C++的地位是不可撼动的,但是rust的确是一个很有意思的语言,所以还是想尝试一下。rust的优势在于安全性,但是在嵌入式领域,安全性并不是最重要的,最重要的是性能和资源占用,所以rust在嵌入式领域的未来并不是很乐观。仅仅为了一点安全性的提升,带来的牺牲是巨大的。搞嵌入式的人真正想要的应该是go。
环境准备
写这篇文章的当前时间节点的最新的版本(版本仅供参考):
软件
- VSCode 1.86.1
- rustc/cargo 1.76.0
- arm-none-eabi-gcc 13.2.1
- openocd 0.12.0
硬件
- STM32L431RCT6(板子是随便找的)
- ST-LINK V2
VSCode插件
- rust-analyzer:使用VSCode开发Rust必备
- cortex-debug:调试、debug嵌入式程序
- crates:提升编辑Cargo.toml的体验,辅助包管理
软件安装
VSCode
略
rustc/cargo
打开rust官网,下载Windows: rust-init.exe
或者Linux: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
一路回车就行了。
换源
rustup源,添加两个环境变量(Linux bash):
1 | export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static |
cargo换源,在~/.cargo/config.toml
文件中添加:
1 | [source.crates-io] |
编译调试工具
可以在ARM官网下载
OpenOCD下载
这里放一个windows的zip
Ubuntu下可以使用命令
1 | sudo apt install gcc-arm-none-eabi |
背景知识
在配置完开发环境之后,我们缓一缓,简单了解一下使用Rust开发嵌入式工程的一些背景知识。
和C语言不同,Rust官方提供了一套标准的硬件抽象层embedded-hal,几乎所有的MCU厂家都会基于这套hal来开发自己的sdk。
各个厂商的相关SDK命名都遵循xxx-rs的方式,比如stm32就是stm32-rs,ESP是esp-rs,rp2040是rp-rs。如果我们想要找相关的SDK,就去对应的github组下面去找就好了。
在正式开发中,我们不会直接和embedded-hal打交道,而是使用各个厂家MCU对应的上层hal实现。我们使用的MCU是stm32l4,因此,直接去stm32-rs下面搜索stm32l4,就能看到对应的hal库stm32h7xx-hal了。当然也可以去crates.io搜索,一样的。使用对应的hal库也非常简单,在Cargo.toml的[dependencies]下面添加一行(PS:直接引用git会好点,至少代码是最新的)
stm32l4xx-hal = { git = “https://github.com/stm32-rs/stm32l4xx-hal”, features = [“stm32l431”, “rt”]}
rustup安装工具链
1 | rustup target add thumbv7em-none-eabihf # 找一下自己的板子对应的target |
项目初始化
1 | cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart |
这个模板工程是rust团队编写的qemu版本的,需要修改一下。
打开.cargo/config文件,修改里面的build如下,STM32L4对应的Cortex-M4:
1 | [build] |
然后cargo build
就可以了。这样就可以在STM32L4上运行了。但是在此之前,再写一个点亮LED的例子。
点亮LED
首先是Cargo.toml文件,添加依赖:
1 | [dependencies] |
memory.x文件,这个文件是链接脚本,用来告诉编译器程序的内存布局,这个是STM32L431的默认配置,其他芯片可以自行修改:
1 | MEMORY |
openocd.cfg文件,这个文件是openocd的配置文件,用来告诉openocd如何连接到目标板,这个是ST-LINK V2的默认配置,其他调试器可以自行修改:
1 | source [find interface/stlink.cfg] |
main.rs文件,这个文件是程序的入口,这个是点亮LED的例子:
//不解释,看代码,效果就是1s翻转一次,LED在GPIOA的12脚
1 |
|
现在cargo build
编译文件
使用openocd烧录,openocd -f openocd.cfg -c "program target/thumbv7em-none-eabi/debug/stm32-demo3 verify reset exit"
注意替换文件名,就可以看到LED在1s内翻转一次了。
debug的话,使用cortex-debug插件,配置好.vscode/launch.json
文件:
1 | "device": "stm32l431", |
修改这三个地方。按F5就可以开始调试了。
没毛病,完结。
完整的工程在这里github。