🥬STM32嵌入式Rust通讯示例
STM32 | Rust
条件
安装了 Rust 工具链的电脑。我只运行 Linux,但以下可能也可以在 MacOS 上运行,甚至可能在 Windows 上运行。
带有 STM32F103 微控制器的电路板。这种控制器最常见的开发板可能是“BluePills”。
一个编程器,STM芯片最便宜的编程器之一是ST-Link V2 Clone,编程器本身是一个克隆,通常包含“CS32”芯片而不是 STM32。
设置
首先,让我们确保我们有一个最新的编译器和 cargo:
> rustup update
然后我们将为运行 thumbv7m-none-eabi ARM 内核的 STM32F1 安装交叉工具链:
> rustup target install thumbv7m-none-eabi
目前,我们使用货物闪存对微控制器进行编程。我们可以通过 cargo 轻松地安装这个工具:
> cargo install cargo-flash
最后我们在我们选择的目录中创建一个新的 Rust 项目
> cargo init rusty-blink
在我们编写任何代码之前,我们配置项目,以便它默认为我们的 thumbv7m-none-eabi 目标编译并使用正确的链接器脚本(稍后会详细介绍)。我们通过在我们的项目根目录中创建一个文件 .cargo/config 来做到这一点。
# .cargo/config
[build]
# Always compile for the instruction set of the STM32F1
target = "thumbv7m-none-eabi"
# use the Tlink.x scrip from the cortex-m-rt crate
rustflags = [ "-C", "link-arg=-Tlink.x"]
接下来我们需要的是链接器脚本,它告诉链接器芯片的内存布局。它必须位于项目根目录中,称为 memory.x。对于 STM32F103C8,如下所示:
准备好了,让我们开始 Cargo。
闪烁
当然,您需要一个 Cargo.toml 文件来配置您的项目。您的项目文件夹中已经存在一个,但我们需要添加一些依赖项和配置。
# Cargo.toml
[package]
edition = "2018"
name = "blinky-rust"
version = "0.1.0"
[profile.release]
opt-level = 'z' # turn on maximum optimizations. We only have 64kB
lto = true # Link-time-optimizations for further size reduction
[dependencies]
cortex-m = "^0.6.3" # Access to the generic ARM peripherals
cortex-m-rt = "^0.6.12" # Startup code for the ARM Core
embedded-hal = "^0.2.4" # Access to generic embedded functions (`set_high`)
panic-halt = "^0.2.0" # Panic handler
# Access to the stm32f103 HAL.
[dependencies.stm32f1xx-hal]
# Bluepill contains a 64kB flash variant which is called "medium density"
features = ["stm32f103", "rt", "medium"]
version = "^0.6.1"
最后:这是一个简单的闪烁程序!不要害怕,因为我添加了解释性注释,它看起来才那么长。
use cortex_m_rt::entry; // The runtime
use embedded_hal::digital::v2::OutputPin; // the `set_high/low`function
use stm32f1xx_hal::{delay::Delay, pac, prelude::*}; // STM32F1 specific functions
#[allow(unused_imports)]
use panic_halt; // When a panic occurs, stop the microcontroller
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let cp = cortex_m::Peripherals::take().unwrap();
let mut rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze(&mut flash.acr);
let mut delay = Delay::new(cp.SYST, clocks);
loop {
led.set_high().ok();
delay.delay_ms(1_000_u16);
led.set_low().ok();
delay.delay_ms(1_000_u16);
}
}
编译后,
> cargo build --release
Compiling semver-parser v0.7.0
Compiling typenum v1.12.0
[...]
Compiling cortex-m-rt-macros v0.1.8
Compiling stm32f1xx-hal v0.6.1
Compiling blinky-rust v0.1.0 (/home/xxx/xxx/Rust/embedded/rusty-blink)
Finished release [optimized] target(s) in 34.63s
对于 blink 示例,您可以省略 --release,但是当您编译一个更复杂的程序时,您将很快耗尽设备内存而没有启用优化。
我生成的程序占用 864 字节的内存(2,8kB 没有 LTO)。 要检查这一点,您必须将编译器输出(elf 文件)转换为十六进制。例如,您可以使用 arm-none-eabi-objcopy -O binary target/thumbv7m-none-eabi/release/blinky-rust blinky-rust.bin,然后使用 ls。
现在您已准备好使用 cargo flash 来刷新控制器。它应该会自动检测您的 ST-Link 并使用它来对微控制器进行编程。您只需指定目标芯片(stm32f103C8)。
您现在应该看到闪烁的板载 LED!
示例
通过 i2c 从 BME280 读取数据 | 模数转换接口传输测试 | 模数转换温度读取 | CAN总线通信 | 定时闪烁 | 动态控制GPIO | PWM控制 | 测试正交编码器接口 | 串行接口 | SPI数据传输 | 定时中断 | USB串口通信
源代码
Last updated