将仿制药用于嵌入式HAL结构
我正在为STM32微控制器编写一个嵌入式程序。我希望能够存储代表按钮的GPIO引脚,以一个不错的合并结构。
由于嵌入式式嵌入式用仿制药编码“引脚”结构的状态,因此每个GPIO都有不同的锈类型,但是对于我的情况(按钮),它们都实现了embedded_hal :: digital :: v2 :: v2 :: inputpin特性。
我可以明确指定每个成员的类型,但是在进行配置时,我还必须为每个按钮编写PIN和端口,即:
let mut middle = gpioa
.pa6
.into_pull_up_input(&mut gpioa.moder, &mut gpioa.pupdr);
这意味着指定结构中的类型会导致冗余,并且如果我需要更改一个PIN在硬件中,我需要在多个地方以代码更改它。
存储这些销钉的规范方法是什么?当然,我不能像在嵌入式上下文中那样使用特质对象。
目前,我有以下内容:
use embedded_hal::digital::v2::InputPin;
struct Buttons<M, R, L, U, D>
where
M: InputPin,
R: InputPin,
L: InputPin,
U: InputPin,
D: InputPin,
{
middle: M,
right: R,
left: L,
up: U,
down: D
}
但是这似乎是潜在的代码气味。
另外,如果我想将此按钮结构存储在另一个结构中,则除非我明确指定(并因此写两次)PIN类型,否则仿制药的数量很可能很大。
是否有更好的方法可以有效?
I am writing an embedded program for an STM32 microcontroller. I would like to be able to store the GPIO pins that represent buttons in a nice, consolidated struct.
Because embedded-hal encodes the state of a "Pin" struct with generics, each GPIO has a different Rust type, however for my case (buttons) they all implement the embedded_hal::digital::v2::InputPin trait.
I could explicitly specify the type for each member, however I also have to write the pin and port for each button when doing configuration, i.e.:
let mut middle = gpioa
.pa6
.into_pull_up_input(&mut gpioa.moder, &mut gpioa.pupdr);
This means that specifying the type in the struct would cause redundancy, and if ever I need to change a pin in hardware, I will need to change it in code in more than one place.
What is the canonical way to store these pins? Of course I cannot use trait objects as it is in an embedded context.
At the moment I have the following:
use embedded_hal::digital::v2::InputPin;
struct Buttons<M, R, L, U, D>
where
M: InputPin,
R: InputPin,
L: InputPin,
U: InputPin,
D: InputPin,
{
middle: M,
right: R,
left: L,
up: U,
down: D
}
However this seems like a potential code smell.
Also, if I want to store this button struct inside another struct, the number of generics will most likely be very big in this parent struct unless I explicitly specify (and therefore write twice) the pin type.
Is there a better way to do this which is also efficient?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
into_dynamic< /代码>
。它删除了一些类型信息,即引脚,但类型中仍然包含端口。
atsamd-hal
有DynPin
,这会完全删除所有类型信息。您需要这样的东西,但我对 ST HAL 不太熟悉。You could use
into_dynamic
. It removes some type information, namely the pin, but still has the port in the type.atsamd-hal
hasDynPin
, which does fully remove all type information. Something like this is what you need, but I'm not as familiar with the ST HALs.您可以使用关联类型将单个类型封装在单个类型中:
然后,要实例化
按钮
您将使用单个类型,该类型使用inputpins
特质。You can encapsulate the 5 types within a single one using associated types as such:
Then to instantiate the
Buttons
you would use a single type that implements all of your necessary types using theInputPins
trait.给定一些全部实现
InputPin
的结构,您可以构造一个也实现
InputPin
的枚举:然后,您可以在任何地方使用
Pin
枚举,而无需泛型。由于这可能会变得麻烦且重复,因此有一个方便的 crate 可以为您完成此操作:enum_dispatch。它甚至声称比手写代码有更好的性能。
Given some structs that all implement
InputPin
,you can construct an enum that also implements
InputPin
:Then, you can use the
Pin
enum everywhere without generics.As this can become cumbersome and repetitive, there is a handy crate to do it for you: enum_dispatch. It even claims to result in better performance than the handwritten code.