#peripheral #embassy #pac #no-alloc

no-std assign-resources

宏,用于将 Peripherals 结构体的字段分割到新的结构体中

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嵌入式开发

Download history 58/week @ 2024-04-14 73/week @ 2024-04-21 3/week @ 2024-04-28 5/week @ 2024-05-12 25/week @ 2024-05-19 16/week @ 2024-05-26 6/week @ 2024-06-02 8/week @ 2024-06-09 6/week @ 2024-06-16 10/week @ 2024-06-23 15/week @ 2024-06-30 21/week @ 2024-07-07 20/week @ 2024-07-14 47/week @ 2024-07-21 75/week @ 2024-07-28

每月 163次下载

MIT/Apache

8KB

assign-resources

此软件包包含一个宏,用于帮助从结构体(如嵌入式 PAC 和 HAL 提供的 Peripherals 结构体)分配和分割资源,将其分配到许多较小的结构体中,这些结构体可以传递给其他任务或函数。

以下示例可以最好地解释。在此,我们定义了名为 UsbResourcesLedResources 的新结构体,每个结构体都包含一些 IO 引脚和一个外设,并生成一个新的 split_resources!() 宏。当调用时,该宏从 p: Peripherals 中取出 PA12PA11USB,并使用它们创建字段 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
}

无运行时依赖