12个版本 (6个破坏性更新)
0.7.1 | 2024年5月23日 |
---|---|
0.7.0 | 2024年2月20日 |
0.6.1 | 2023年11月22日 |
0.6.0 | 2023年7月18日 |
0.4.1 | 2022年11月30日 |
#42 in Unix API
每月2,019次下载
在 4 crates 中使用
345KB
6.5K SLoC
gpiocdev
一个用于通过GPIO字符设备在Linux平台上访问GPIO引脚的Rust库。
这是libgpiod的等价库,但完全用Rust编写。与libgpiod绑定不同,此库支持GPIO uAPI的两个版本,并支持Rust异步。
配套库
gpiocdev-embedded-hal 库为 embedded_hal 提供了 Requests
特性,并提供了一个简化的接口,可能对基本用例很有用。
gpiocdev-uapi 库为GPIO uAPI提供了一个更底层的安全包装,而此库为uAPI v1和v2提供了更高层次的抽象和统一接口。你几乎肯定想使用更高层次的抽象。
gpiocdev-cli 库提供了一个命令行工具,类似于libgpiod工具,用于从shell访问GPIO引脚。
gpiosim 库提供了用于测试gpiocdev的GPIO模拟器,以及可能使用它的任何应用程序。
示例用法
use gpiocdev::Request;
use gpiocdev::line::Value;
获取引脚值
// request the line
let req = Request::builder()
.on_chip("/dev/gpiochip0")
.with_line(23)
.as_input()
.request()?;
// get the value
let value = req.value(23)?;
设置引脚
// request the line and set its value
let req = Request::builder()
.on_chip("/dev/gpiochip0")
.with_line(22)
.as_output(Value::Active)
.request()?;
// do something...
// change value later
req.set_value(22, Value::Inactive)
通过名称请求引脚
let led0 = gpiocdev::find_named_line("LED0").unwrap();
let req = Request::builder()
.with_found_line(&led0)
.as_output(Value::Active)
.request()?;
// change value later
req.set_value(led0.offset, Value::Inactive)
在引脚上等待事件
// request the line
let req = Request::builder()
.on_chip("/dev/gpiochip0")
.with_line(23)
.with_edge_detection(gpiocdev::line::EdgeDetection::BothEdges)
.request()?;
// wait for line edge events
for event in req.edge_events() {
println!("{:?}", event?);
}
可以在单个请求中选择多个引脚,然后作为一个单元进行操作。
获取多个引脚
// request multiple input lines
let req = Request::builder()
.on_chip("/dev/gpiochip0")
.with_lines(&[18,23])
.as_input()
.request()?;
// get multiple line values at once
let mut values = Values::default();
req.values(&mut values)?;
设置多个引脚
// request multiple output lines
let req = Request::builder()
.on_chip("/dev/gpiochip0")
.with_lines(&[17,22])
.as_output(Value::Active)
.request()?;
// set multiple line values at once
let mut values = Values::default();
values.set(17, Value::Inactive);
values.set(12, Value::Active);
req.set_values(&values)?;
可以通过内核GPIO接口设置所有可用的引脚属性,例如上拉和防抖等。
// request the line
let req = Request::builder()
.on_chip("/dev/gpiochip0")
.with_consumer("myapp")
.with_line(23)
.as_input()
.as_active_low()
.with_bias(gpiocdev::line::Bias::PullUp)
.request()?;
// get the value
let value = req.value(23)?;
可以在示例目录中找到工作示例。
ABI 兼容性
该库与 Linux GPIO uAPI 兼容,包括 v1 和 v2 版本,支持接收线边缘事件。
gpiocdev API 为这两个 uAPI 版本提供统一的抽象,但在 v1-only 系统上尝试使用 v2 功能时将返回错误。
uAPI v2 的特定功能包括
- 一个请求中包含不同配置的线条
- 去抖动边缘检测输入线
- 一个请求中检测多条线的边缘
- 边缘事件的序列号
- 在不释放请求的情况下重新配置边缘检测
- 选择边缘事件的源时钟
可以通过功能选择兼容 uAPI 的版本,默认为 uAPI v2。如果同时构建,则库可以自动检测并使用最新版本,因此默认为 v2,如果不可用则回退到 v1。
gpiocdev 不使用较慢且已过时的 sysfs GPIO API。
异步兼容性
GPIO uAPI 的主要部分是同步的。例外的是等待来自 Request 的边缘事件和来自 Chip 的信息更改事件。通过以下功能提供对这些异步包装的支持
反应器 | 功能 | 模块 |
---|---|---|
tokio | async_tokio | gpiocdev::tokio |
async-io | async_io | gpiocdev::async_io |
此外,Chips 和 Requests 还公开了它们的底层文件描述符,可以直接与异步反应器一起使用。例如,gpiocdev-cli 的 edges 命令,可以使用 mio 反应器异步等待多个芯片上的多条线。
关于同步 uAPI 函数,除非 GPIO 线由连接到主机处理器的总线上(如 I2C 或 SPI)的扩展器提供,否则通常可以认为是非阻塞的。在这种情况下,根据应用程序的要求和异步反应器,可能需要在单独的线程上调用同步函数,以免阻塞单线程反应器。
许可
根据您的选择,许可协议为以下之一
- Apache 许可证 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确声明,否则任何有意提交以包含在您的工作中的贡献,如 Apache-2.0 许可证中定义,均将按上述方式双许可,没有任何额外的条款或条件。
依赖关系
~0.4–11MB
~131K SLoC