我想在Rust中为STM32F1xx制作"Blinky".

我可以通过地址访问STM32的"寄存器",如C中所示:

*(uint32_t*)(0x40021000 + 0x018) |= 0x10;
*(uint32_t*)(0x40011000 + 0x004) |= 0x33;
*(uint32_t*)(0x40011000 + 0x004) &= ~0xCC;
*(uint32_t*)(0x40011000 + 0x10) |= 0x300;

while(1) {}

这会将一些位写入RCC_APB2ENR寄存器,以启用端口C的时钟,配置管脚并启用我的发现上的LED.

我需要用Rust重新编写它,生成const和fns,并开始编写漂亮的Rust代码.在 rust 迹斑斑的情况下,FFI是否可以调用C代码?我能用asm!宏实现这一点吗?

推荐答案

在C语言中,当访问硬件寄存器时,应该将指针声明为volatile,这样编译器就可以完全按照编程的方式进行访问.否则,它可能会对它们重新排序,或消除对同一寄存器的重复访问.

由于Rust 1.9(得益于这个RFC),您可以使用core::ptr::read_volatilecore::ptr::write_volatile来读取和写入这样的内存.

如果你有一个旧版本的Rust ,它们可以作为volatile_readvolatile_storecore::intrinsics,但这是永久不稳定的,因此需要一个夜间版本的Rust 访问它们.

Rust相关问答推荐

程序退出后只写入指定管道的数据

PyReadonlyArray2到Vec T<>

为什么幻影数据不能自动推断?

为什么复印是豆荚的一个重要特征?

在使用#[NO_STD]时,如何在Rust中收到紧急消息?

为什么我们需要std::thread::scope,如果我们可以使用thread.join()在函数的生命周期内删除引用?

更合理的方法来设计样条线函数器?

为什么不';t(&;mut-iter).take(n)取得iter的所有权?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

.to_owned()、.clone() 和取消引用 (*) 之间有区别吗?

tokio::spawn 有和没有异步块

Rust 中多个 & 符号的内存表示

返回迭代器考虑静态生命周期类型

我可以禁用发布模式的开发依赖功能吗?

push 方法是否取得所有权?

bcrypt 有长度限制吗?

在 Rust 中,Weak 如何知道内部值何时被删除?

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

C++ 中的 CRTP 是一种表达其他语言中特征和/或 ADT 的方法吗?

在 Rust 中组合特征的不同方法是否等效?