1 个不稳定版本
0.1.0 | 2024年1月11日 |
---|
#1997 在 嵌入式开发
23,637 每月下载量
用于 67 个 crate(9 个直接使用)
43KB
610 行
embassy-time-driver
该 crate 包含添加对新的硬件平台支持所需的 embassy-time
驱动 trait。
如果您想使用已制作的驱动程序与 embassy-time
,则应依赖于主要的 embassy-time
crate,而不是此 crate。
如果您正在编写驱动程序,则应仅依赖于此 crate,而不是主要的 embassy-time
crate。这样,如果驱动程序 trait 没有破坏性更改,则驱动程序将继续在新的 embassy-time
主要版本中工作,而无需更新。
工作原理
embassy-time
由在构建时指定的全局“时间驱动程序”支持。一个程序中只能有一个活动驱动程序。
所有方法和结构体都透明地调用活动驱动程序。这使得库可以在无需泛型参数的情况下以驱动程序无关的方式使用 embassy-time
。
lib.rs
:
实现驱动程序
- 定义一个结构体
MyDriver
- 为它实现
Driver
- 使用
time_driver_impl
将其注册为全局驱动程序。
如果您的驱动程序具有单个可设置的滴答率,请启用相应的 tick-hz-*
功能,这将防止用户自行配置(或选择错误的配置)。
如果您的驱动程序支持少量可设置的滴答率,公开您自己的 cargo 功能,并使每个功能启用相应的 embassy-time-driver/tick-*
。
否则,不要启用任何 tick-hz-*
功能,让用户通过在 embassy-time
上启用功能来自行配置滴答率。
链接详情
与常规的“特性 + 泛型参数”方法不同,从大使馆到驱动程序的调用是通过 extern
函数完成的。
embassy
内部定义驱动程序函数为 extern "Rust" { fn _embassy_time_now() -> u64; }
并调用它们。驱动程序包定义函数为 #[no_mangle] fn _embassy_time_now() -> u64
。链接器将解析从 embassy
包的调用以调用驱动程序包。
如果包树中没有或多个驱动程序,则链接将失败。
这种方法对于像时间管理这样基础的东西有几个关键优势
- 时间驱动程序无处不在,易于使用,无需通过泛型参数来传递实现。这对于库来说特别有帮助。
- 这意味着比较
Instant
总是有意义:如果有多个驱动程序活动,可以将驱动程序 A 的Instant
与驱动程序 B 的Instant
进行比较,这将产生错误的结果。
示例
use embassy_time_driver::{Driver, AlarmHandle};
struct MyDriver{} // not public!
impl Driver for MyDriver {
fn now(&self) -> u64 {
todo!()
}
unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
todo!()
}
fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
todo!()
}
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
todo!()
}
}
embassy_time_driver::time_driver_impl!(static DRIVER: MyDriver = MyDriver{});
功能标志
依赖关系
~175KB