Rust生态在嵌入式单片机方面也越来越完善了,所以浅尝用Rust开发来开发STM32。
开发板准备: STM32F103C8T6
在 macOS 下用 Rust 开发并烧写 STM32,可以按照以下步骤进行操作:
需要提前安装STM32相关的工具
在终端中安装 Rust:
bashcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
添加 ARM Cortex-M 目标架构:
bashrustup target add thumbv7em-none-eabihf
安装
brew install probe-rs-tools
cargo-generate
和 probe-rs
用于生成项目模板:
bashcargo install cargo-generate
安装目标平台:
bashrustup target add thumbv7m-none-eabi
用于调试和烧写 STM32(弃用):
bashcargo install probe-rs
STM32 的编译需要交叉编译工具链,安装 ARM 工具链:
bashbrew install --cask gcc-arm-embedded
烧录程序所需 OpenOCD和stlink:
bashbrew install open-ocd stlink
使用社区提供的模板快速生成项目:
cargo-generate
生成项目:
bashcargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
stm32_rust_demo
。Cargo.toml
根据 STM32 芯片选择对应的 HAL 库,使用 stm32f1
系列:
toml
[dependencies]
cortex-m = "0.7.6" # 使用最新版本
cortex-m-rt = "0.7.3" # 和 HAL 匹配的版本
cortex-m-semihosting = "0.3.3"
panic-halt = "0.2.0"
stm32f1xx-hal = { version = "0.10", features = ["stm32f103", "rt"] }
# Uncomment for the panic example.
# panic-itm = "0.4.1"
# Uncomment for the allocator example.
# alloc-cortex-m = "0.4.0"
[[bin]]
name = "stm32_rust_demo"
test = false
bench = false
[profile.release]
codegen-units = 1 # better optimizations
debug = true # symbols are nice, and they don't increase the size on Flash
lto = true # better optimizations
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8T6"
rustflags = [
"-C", "link-arg=-Tlink.x"
]
[build]
target = "thumbv7m-none-eabi"
在项目中包含 memory.x
文件,配置内存布局。例如,STM32F401 的内存布局如下:
xMEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 64K RAM : ORIGIN = 0x20000000, LENGTH = 20K }
示例代码,点亮 STM32 板上的 LED:
rust#![no_std]
#![no_main]
use cortex_m_rt::entry;
use panic_halt as _; // 在发生 panic 时暂停
use stm32f4xx_hal::{
pac,
prelude::*,
};
#[entry]
fn main() -> ! {
let peripherals = pac::Peripherals::take().unwrap();
let gpioa = peripherals.GPIOA.split();
// 设置 GPIOA5 为推挽输出模式
let mut led = gpioa.pa5.into_push_pull_output();
loop {
led.set_high(); // 点亮 LED
cortex_m::asm::delay(8_000_000); // 延迟
led.set_low(); // 关闭 LED
cortex_m::asm::delay(8_000_000); // 延迟
}
}
在项目目录下运行:
bashcargo build --release
然后不出意外应该能看到target下有一个thumbv7m-none-eabi目录,thumbv7m-none-eabi目录下还有一个release目录,release目录下有一个可执行文件stm32_rust_demo。
probe-rs
查看调试器执行以下命令查看是否正常识别:
probe-rs list
如果能看到以下结果则说明连接没问题:
The following debug probes were found: [0]: CMSIS_DAP -- 2e3c:f000:8D210C000040112513951D07 (CMSIS-DAP)
修改根目录下的openocd.cfg文件
# 设置调试器为cmsis-dap source [find interface/cmsis-dap.cfg] # 设置调试器所用接口为SWD transport select swd # 定义Flash大小为64K set FLASH_SIZE 0x20000 # 设置芯片 source [find target/stm32f1x.cfg]
慢速法是指需要开启两个终端,通过arm-none-eabi-gdb来烧录,但是有第一次烧录成功,后续均无法烧录。 1. 启动 OpenOCD:
在项目的根目录下执行:
从前面的probe-rs list
得到调试器类型CMSIS_DAP,所以执行
bashopenocd -f interface/cmsis-dap.cfg -f openocd.cfg
不出意外可以看到:
Open On-Chip Debugger 0.12.0 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Warn : Interface already configured, ignoring Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e3c:0xf000, serial=8D210C000040112513951D07 Info : CMSIS-DAP: SWD supported Info : CMSIS-DAP: SWO-UART supported Info : CMSIS-DAP: Atomic commands supported Info : CMSIS-DAP: Test domain timer supported Info : CMSIS-DAP: FW Version = 2.3.6 Info : CMSIS-DAP: Interface Initialised (SWD) Info : SWCLK/TCK = 0 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1 Info : CMSIS-DAP: Interface ready Info : clock speed 1000 kHz Info : SWD DPIDR 0x1ba01477 Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints Info : starting gdb server for stm32f1x.cpu on 3333 Info : Listening on port 3333 for gdb connections
若是调试器为ST-Link,则需要调整openocd.cfg和openOCD命令
2. 启动终端使用 arm-none-eabi-gdb 来与 OpenOCD 交互:
arm-none-eabi-gdb target/thumbv7m-none-eabi/release/stm32_rust_demo
target extended-remote :3333
不出意外可以看到:
Remote debugging using :3333 0x08000dea in ?? ()
4. 在gdb模式下,再执行烧录命令:
load
不出意外可以看到:
Loading section .vector_table, size 0x130 lma 0x8000000 Loading section .text, size 0x134 lma 0x8000130 Loading section .rodata, size 0x2c lma 0x8000264 Start address 0x08000130, load size 656 Transfer rate: 1 KB/sec, 218 bytes/write.
5.重置设备并启动程序:
monitor reset
6.退出gdb模式:
quit
需要再次确认,再输入y
7.退出OpenOCD模式:
快捷键Ctrl+C或者Command+C
注意 当前此种方法不能进行第二次烧录,原因未知。
一键烧录命令:
openocd -f openocd.cfg -c "tcl_port disabled" -c "gdb_port disabled" -c "program ./target/thumbv7m-none-eabi/release/stm32_rust_demo" -c reset -c shutdown
本文作者:phae
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!