5 个版本 (3 个重大更新)
0.4.1 | 2023年12月8日 |
---|---|
0.4.0 | 2023年12月2日 |
0.3.0 | 2023年11月25日 |
0.2.0 | 2023年11月25日 |
0.1.0 | 2023年11月22日 |
#1528 在 嵌入式开发
每月 163次下载
8KB
assign-resources
此软件包包含一个宏,用于帮助从结构体(如嵌入式 PAC 和 HAL 提供的 Peripherals
结构体)分配和分割资源,将其分配到许多较小的结构体中,这些结构体可以传递给其他任务或函数。
以下示例可以最好地解释。在此,我们定义了名为 UsbResources
和 LedResources
的新结构体,每个结构体都包含一些 IO 引脚和一个外设,并生成一个新的 split_resources!()
宏。当调用时,该宏从 p: Peripherals
中取出 PA12
、PA11
和 USB
,并使用它们创建字段 usb: UsbResources
,并在返回的对象中类似地创建字段 leds: LedResources
。然后我们可以将这些新结构体移动到我们的任务中,通过名称访问资源。
我们还可以使用类型别名标记一些资源,以便函数签名也可以引用该类型。
use assign_resources::assign_resources;
use embassy_stm32::peripherals;
assign_resources! {
usb: UsbResources {
dp: PA12,
dm: PA11,
usb: USB,
}
leds: LedResources {
r: PA2,
g: PA3,
b: PA4,
tim2: TIM2 = PWMTimer,
}
}
#[embassy_executor::task]
async fn usb_task(r: UsbResources) {
// use r.dp, r.dm, r.usb
}
async fn setup_leds<'a>(r: LedResources) -> SimplePWM<'a, PWMTimer> {
// setup three channel PWM (one for each color)
}
#[embassy_executor::task]
async fn led_task(rgb_pwm: SimplePWM<'a, PWMTimer>) {
// use rgb_pwm
}
#[embassy_executor::main]
async fn main(spawner: embassy_executor::Spawner) {
let p = embassy_stm32::init(Default::default());
let r = split_resources!(p);
let rgb_pwm = setup_leds(r.leds);
spawner.spawn(usb_task(r.usb)).unwrap();
spawner.spawn(led_task(rgb_pwm)).unwrap();
// can still use p.PA0, p.PA1, etc
}
这有几个优点:您只需在一个地方写入特定的引脚名称,例如 PA12
,之后就可以通过名称引用它们,对于每个任务只有一个参数,而不是可能有很多参数,并且不需要编写大量代码来分割资源。如果您针对多种不同的硬件,可以使用 #[cfg]
在一个地方更改引脚分配。
在库中的定义
以下代码将放在库文件中,即 lib.rs
use assign_resources::assign_resources;
use embassy_stm32::peripherals;
assign_resources! {
usb: UsbResources {
dp: PA12,
dm: PA11,
usb: USB_OTG_FS,
}
leds: LedResources {
r: PA2,
g: PA3,
b: PA4,
tim2: TIM2,
}
}
并且资源可以从外部访问,例如在 my_bin.rs
// import `AssignedResources`, the `split_resources` macro and all custom resources structs from the library
use my_library::{AssignedResources, LedResources, UsbResources, split_resources};
#[embassy_executor::task]
async fn usb_task(r: UsbResources) {
// use r.dp, r.dm, r.usb
}
#[embassy_executor::task]
async fn led_task(r: LedResources) {
// use r.r, r.g, r.b, r.tim2
}
#[embassy_executor::main]
async fn main(spawner: embassy_executor::Spawner) {
let p = embassy_stm32::init(Default::default());
let r = split_resources!(p);
spawner.spawn(usb_task(r.usb)).unwrap();
spawner.spawn(led_task(r.leds)).unwrap();
// can still use p.PA0, p.PA1, etc
}