rust - 为 STM32 微控制器板使用 Rust crates
问题描述
我目前正在尝试学习 Rust(专门用于嵌入式),来自嵌入式系统的 C 和 Python 的背景。到目前为止,我一直在阅读Rust Programming Language和Rust for Embedded,并阅读了网络上的一些博客文章。
我希望我的第一个项目是一个简单的“Blinky”,其中 LED 无限闪烁。我有一个 STM32L152CDISCOVERY 板,里面有一个 STM32L152 芯片(基本上与 STM32L151 相同),它是一个 Cortex M3。
我不想从头开始实现所有东西,而是想利用现有的 crate 和 HAL。我发现了两个看起来很有希望的:stm32l1和stm32l1xx-hal。我已经尝试阅读它们中的每一个的文档以及部分源代码,但我仍然无法弄清楚如何正确使用它们。
有几个关于 Rust 和 crates 的问题:
我看到它
stm32l1xx-hal
依赖于stm32l1
. 我是否需要将两者都添加为我的Cargo.toml
文件中的依赖项?还是会产生与所有权相关的问题?这是添加它们的正确方法吗?为什么第二个是这样添加的
[dependencies.stm32l1]
?[dependencies] cortex-m-rt = "0.6.10" cortex-m-semihosting = "0.3.3" panic-halt = "0.2.0" stm32l1xx-hal = "0.1.0" [dependencies.stm32l1] version = "0.13.0" features = ["stm32l151", "rt"]
要使 LD4(连接到
PB4PB6)闪烁,我必须启用 RCC 寄存器中的 GPIOB,然后将引脚配置为推挽输出。通过检查 的文档stm32l1xx-hal
,我看到有一个RCC 结构和一个PB4 结构与方法into_push_pull_output
。但是,我仍然不明白如何使用这些结构:如何导入它们或如何获取它们的实例。
我看过代码示例,stm32l1
但没有stm32l1xx-hal
。我知道我可以这样做:
use stm32l1::{stm32l151};
...
let p = stm32l151::Peripherals::take().unwrap();
p.RCC.ahbenr.modify(|_,w| w.gpiopben().set_bit());
但是在我的源代码中stm32l1xx-hal
我看到 RCC 部分已经完成impl GpioExt for $GPIOX
,但我不知道如何获得这个“部件”功能。
任何为我指明正确方向的帮助表示赞赏。
解决方案
我从 Discord 社区获得了一些帮助。答案是(由我修改了一下):
stm32l1xx-hal
已经取决于stm32l1
这里看到的。无需导入两次。添加到 Cargo.toml 就足够了:[dependencies.stm32l1xx-hal] version = "0.1.0" default-features = false features = ["stm32l151", "rt"]
- 请注意,这
default-features = false
是可选的,但没有它,编译器会给我一个错误。
语法是等价的,但正如我上面所说,我只需要添加 HAL 一个。您可以在第一种样式中添加花括号
{}
以添加选项,例如:stm32l1xx-hal = { version = "0.1.0", features = ["stm32l151", "rt"]}
进行眨眼的正确代码(在 PB6 上,而不是 PB4,叹气)是:
#![no_main] #![no_std] use panic_halt as _; use cortex_m_rt::entry; use stm32l1xx_hal::delay::Delay; use stm32l1xx_hal::gpio::GpioExt; use stm32l1xx_hal::hal::digital::v2::OutputPin; use stm32l1xx_hal::rcc::{Config, RccExt}; use stm32l1xx_hal::stm32::Peripherals; use stm32l1xx_hal::stm32::CorePeripherals; use stm32l1xx_hal::time::MicroSeconds; #[entry] fn main() -> ! { let p = Peripherals::take().unwrap(); let cp = CorePeripherals::take().unwrap(); // Get LED pin PB6 let gpiob = p.GPIOB.split(); let mut led = gpiob.pb6.into_push_pull_output(); // Set up a delay let rcc = p.RCC.freeze(Config::default()); let mut delay = Delay::new(cp.SYST, rcc.clocks); loop { // Turn LED On led.set_high().unwrap(); delay.delay(MicroSeconds(1_000_000_u32)); // Turn LED Off led.set_low().unwrap(); delay.delay(MicroSeconds(1_000_000_u32)); } }
- 对我来说,关键是要了解该
split
方法可以从. 换句话说,HAL crate 不仅定义了新的结构,还扩展了现有结构的功能。我需要围绕 trait 设计模式。Peripherals
stm32l1xx-hal
split
stm32l1
推荐阅读
- javascript - Aframe 自定义组件更新功能未触发
- php - PHP根据2个键从数组中删除重复项和它们的总和
- excel - 每次工作表在 excel VBA 中受保护或不受保护时记录
- python - 如果使用 Python 的 Pandas 在两个日期之间的日期时间,寻找一种按日期时间分组的方法
- mongodb - 无法从函数中更新 Meteor 中的 Mongo Collection
- r - 大型生态数据集,metaMDS 不会收敛
- jquery - 在 JQuery 函数中更改 css 样式
- c# - 使用 EF Core dbcontext 运行异步选择时出错
- android - RequireNativeComponent:在 UIManager 中找不到“ToolbarAndroid”
- intune - 无法使用 intune 公司门户下载证书