#gpio-pin #raspberry-pi #rpi #pigpio #pi #raspberry #pigpiod

程序+库 apigpio

通过 pigpiod 访问 Raspberry PI GPIO;安全、异步、Tokio

4 个版本 (2 个稳定版)

1.0.1 2022年11月3日
0.1.1 2020年5月1日
0.1.0 2020年5月1日

#567硬件支持

GPL-3.0-or-later

89KB
1.5K SLoC

Raspberry PI GPIO 访问库,基于 pigpiod。

此库是 C 语言 pigpio_if2 库的纯 Rust 实现,提供与 pigpiod 通信的异步接口。apigpio 使用 Rust 异步框架 Tokio。

目前我们只提供 pigpio 功能的一部分:原始 GPIO 访问和通知,以及波形生成。当然,欢迎贡献。

主入口点是 [Connection::new()],然后是对 Connection 和其解引用目标 ConnectionCore 的方法调用。

您需要阅读 pigpio 项目中的 pigpio_if2 文档

考虑使用 rppal

您应该考虑是否希望使用此库,或者改用优秀的 rppal 库。

apigpo 的优点

  • 访问基于 DMA 的 wavefile 生成。

  • 接口与 pigpio 自身的接口非常相似:这可以简化将现有的 rpi 代码迁移到 Rust,并且可能使基于 C 或 Python pigpio 访问的在线信息更容易使用。

  • 您可以将 pigpiod 转发到更快的或更方便的计算机上,并在那里运行您的程序(例如,在开发期间)。

  • 当多个进程同时更改 GPIO 引脚的 模式 时,操作正确且无竞态条件,前提是所有内容都使用 pigpiod。 (对 GPIO 级别 的并发多进程更改对任何库都很好,包括 rppal。)

rppal 的优点

  • I2C、PWM、SPI、UART 支持。RPI 型号信息等。

  • 接口更 Rust-like,具有更好的类型安全性等。例如,您不会忘记设置 GPIO 引脚的模式。

  • 开销较少,因为 GPIO 访问直接在您的 Rust 程序内进行,而不需要进行系统调用,而不是通过与单独的守护进程交谈。

  • 基于中断而不是 pigpiod 的轮询进行 GPIO 变更通知。

  • 无需处理异步 Rust。

  • 无需安排守护进程运行,覆盖 pigpiod 的默认设置,使其不对外开放全球互联网(!),确保您的系统启动顺序正确,等等。

在单个项目中同时使用这两个库是完全可能的。我自己就是这样做的。但请注意以下说明

同时设置 RPI GPIO 引脚模式

Broadcom SOC 提供了一种方法,可以以不干扰其他同时进行的类似操作的方式,提升或降低单个 GPIO 引脚输出(或一组输出)。

然而,此接口仅用于设置输出引脚的 级别。对于模式、上拉/下拉等,只有包含多个引脚信息的 mmio 寄存器,通过读取寄存器、调整控制特定引脚的位并写回信息来更改。

如果在 rpi 上有多个演员同时这样做,即使是针对不同的引脚,他们也可能意外地撤销彼此的更改。

为此,pigpiod 是一个单一演员:它将自行序列化更新。所以如果你的所有程序都使用 pigpiod(通过 apigpio 或通过其他编程语言的库与 pigpiod 通信),你就可以放心了。

即使在单个 Rust 程序中结合 rppalapigpio,也涉及多个演员,因为 apigpiod 的工作全部由 pigpiod 完成。

如果你要混合使用,确保正确性的最简单方法是启动时有一个单独的任务设置所有 GPIO 模式。然后所有后续的更新都将是无害的空操作。(当然,如果需要运行时更改模式,这不适用。)

但避免此问题的最简单方法是只有一个程序使用单个(如果适用,线程安全)库 - 例如,rppal

安全性和正确性

apigpio 完全使用安全 Rust。因此,你应在 Rust 程序中不会遇到内存损坏。

然而,由于 pigpiod 本身的工作方式,可能会出现一些意外。

首先:pigpiod 资源是全局的。不同程序与 pigpiod 通信之间没有隔离,也没有自动清理。例如,特别是

一次只能由一个程序方便地使用 wave_* 函数,因为 pigpiod 只有一个当前正在构建的波形和一个当前正在传输的波形。波形在程序退出时不会被删除 - 但在启动时使用 wave_clear 是一种惯例,以便在下次运行时清理一切。

其次:pigpiod 本身有一些危险特性。这些通常在 pigpio 文档中讨论。目前通过 apigpio 可用的此类唯一功能是结合波形删除能力的 *SYNC* 波形链功能。这些类型的特性仅通过 apigpiod 供 unsafe 调用者使用(尽管它们是在安全 Rust 中实现的)。

Cargo 功能

版本历史

1.0.1

  • 修复了 1.0.0 版本的更改日志版本文档(哎呀)。

1.0.0

  • 破坏性更改:更新到 Tokio 1。
  • 重大更新:将 Subscription 修改为包含 postage::watch::Receiver 而不是 Tokio 版本。这允许它实现 Stream
  • 重大更新:将类型别名 Pin 重命名为 PPin
  • 文档质量提升。
  • 许可从 AGPLv3+ 降至 GPLv3+。

0.1.1

文档和元数据变更。

0.1.0

首次公开发布。

依赖项

~5–14MB
~158K SLoC