Ohhnews

分类导航

$ cd ..
foojay原文

Pi4J V5.0.0开发中:API大幅精简并新增RISC-V支持

#pi4j#java#物联网#risc-v#开源

Pi4J 是什么?

Pi4J 是一个开源 Java 库,可让你的 Java 应用访问 Raspberry Pi 及其他单板计算机的硬件引脚。借助它,你可以完全用 Java 代码实现 LED 闪烁、读取按钮,或者通过 GPIO、PWM、I2C、SPI 和串口与传感器、显示屏和电机控制器通信,而无需编写任何 C 代码。该项目始于十多年前,现隶属于 Commonhaus Foundation,由一支小型志愿者团队维护。

自 V2 起,Pi4J 采用插件架构;借助 FFM API(Foreign Function & Memory,自 Java 22 起成为正式特性),FFM 插件可直接与 Linux 内核通信,而不再依赖早期版本中的原生 C 库。这一变化为其他开发板和架构(如 RISC-V)打开了大门,也为下文所述的清理工作创造了条件。在核心库之上,Pi4J Drivers 为常见传感器和组件提供开箱即用的代码,甚至还有一个 Quarkus 扩展。

本文最初发表于 Pi4J 网站,概述了下一个主版本即将带来的变化。

迈向 V5.0.0

自 2026 年 6 月发布 4.0.2 版本以来,Pi4J 核心仓库的 main 分支已切换到 5.0.0-SNAPSHOT,此后发生了很多变化:约 300 次提交和 80 多个已合并的拉取请求!本文概述了正在发生的变化以及这些变化由谁推动。

V5.0.0 尚未确定发布日期。 仍有若干 issues 和拉取请求在进行中,我们希望在发布前把 API 做对,因为 V5 正是清理那些无法在次要版本中改动的内容的时机。如果你想试用,快照构建会针对 main 上的每次变更自动发布。

更精简的核心

V5 最大的主题是清理。Pi4J 经过多年发展,许多代码已不再使用、存在重复,或让事情变得不必要地复杂。以下是部分变更:

  • 移除 Platforms(#650),同时移除平台自动检测选项(#688)。
  • 移除 Providers(#782),将插件转变为 Context 的工厂。对于旧有的、曾在文档中重点介绍的 IO 实例创建方式,仅保留最小化的存根(#790)。
  • 移除 Properties 和基于名称的 IO 创建方式(#652、#674),同时移除 binding 和 group 存根(#653)、PWM 预设(#693)、已弃用的 DeferredDelay(#640),以及其他未使用的元数据和类型(#706、#792)。
  • 移除旧的 Raspberry Pi 插件实现和从未使用的模拟 GPIO 实现(#664、#665)。FFM 插件是未来的方向。
  • 内部运行时合并到 DefaultContext(#660),并且不再暴露对 IO 注册表的写访问权限(#658)。
  • 配置类不再依赖 context(#711 等),使其更接近普通 DTO;IO 实例也正在摆脱对 Context 的依赖(#769、#791)。
  • 移除中间基类,例如 GpioBase 和 provider 基类(#776、#778)。

创建 IO 实例的明确方式

多年来,创建 IO 实例的方式层出不穷。V5 确定了一种规范做法(#704、#728):使用 <IOTYPE>.newConfigBuilder(),并将配置传给 context.create(...)。其他创建路径已被弃用(注解中标明了版本)或标记为内部使用,剩余的内部调用也已移除(#733、#735、#738)。设备现在会在创建时注册(#734)。

关闭流程也已简化:令人困惑的 close() 与 shutdownInternal() 组合被单一的 close() 方法取代(#768),并修复了多个与关闭顺序和健壮性相关的问题(#677、#678、#755、#780)。

回退到 Mock

一个长期存在的请求(#619)现在可以实现了:有真实硬件时在真实硬件上运行,在其他系统(例如你的开发 PC)上则自动回退到 Mock(#715)。Mock provider 的优先级现在更低,因此不再优先于真实 provider。Mock 驱动本身也被重构为合适的测试框架,其中包括一个 GPIO Mock 驱动(#651)。

新增与改进的 IO 功能

  • 并行端口(Parallel port):新增 ParallelPort IO 类型,可将多个 GPIO 作为一个值同时读取或写入,并可在运行时控制方向(#727、#740、#765、#785)。事件支持正在 #788 中开发。
  • PWM:频率和占空比现在都是 double 值,因此可以使用 1.5 Hz 或 33.3% 的占空比(#644、#646);FFM PWM 实现经过重构和优化(#701),文档也有所改进(#759)。
  • I2C:实现现在只需提供 writeThenRead,其他方法的默认实现都构建在其之上(#744、#746)。read() 现在返回无符号值(#753),并且移除了功能有限的 FILE 实现(#762)。
  • SPI:支持分块传输(#666)。
  • 数字输出:FFM 实现中支持初始状态(#663),并将 blink、pulse 等移到 DigitalOutputOperations 辅助类中(#749)。
  • GPIO:重构 FFM GPIO 代码以减少重复(#698)。

更多开发板:RISC-V 与更好的检测

  • RISC-V 支持(#697):FFM provider 现在会请求操作系统链接器查找原生库,而不再按架构使用硬编码路径。详见 RISC-V 支持落地 Pi4J V5。
  • 面向非 Raspberry Pi 开发板的 LineHelper(#694),基于在 Banana Pi 和 NVIDIA Jetson Nano 上的实验。
  • 通过修订码进行开发板检测(#682):按照 Raspberry Pi 的建议,将 Raspberry Pi 修订码解析为内存大小、处理器和开发板类型,因此现有开发板的新修订版无需修改代码即可识别。现在还支持 16GB Compute Module 5(#673)。
  • 更友好的 FFM 启动体验:每个 provider 单独注册,因此缺少某个 Linux 用户组只会禁用相关 provider,权限提示信息会建议正确的 usermod -aG 命令(#757、#758)。构建和测试中也已处理更新的内核版本(#662、#760)。

构建、发布与文档

  • Java 25 和 Maven 4(#612)。
  • 使用 JReleaser 从 main 自动发布(#685),符合 Commonhaus 的发布要求,并采用与 Pi4J Drivers 相同的方式,另有多项修复以确保快照确实会发布(#770、#771、#772)。
  • module-info 文件被 Automatic-Module-Name 取代(#775)。FFM 插件是否应再次获得具名模块,仍在 #795 中讨论。
  • 改进所有公共方法的 JavaDoc(#667、#668)。
  • 更新冒烟测试,以适配 smoke test PCB(#676、#783)。
  • 架构图:现在每个拉取请求都会收到一条评论,显示它更改了哪些组件,依据是项目的 groma.md 架构图(#786)。

仍在进行中

在 V5.0.0 发布之前,还有一些主题尚未完成,例如:

  • 并行端口事件(#788、#789)。
  • 使用 FFM 插件进行硬件检测(#645、#642)。
  • 进一步清理配置(#794、#705、#714、#731),并移除 Describable/Identity 复合结构(#730)。
  • 从 IO 实例中移除剩余的 Context 依赖(#764)。
  • 为已打开的 IO 提供 CRaC checkpoint/restore 支持(#797、#798)。
  • 1-Wire 支持(#429、#435)、模拟引脚(#699),以及 FFM 插件中的软件 PWM(#556)。
  • FFM DigitalInput 消抖可能存在的问题(#796)。

由于 V5 包含破坏性 API 变更,我们还会在发布前更新 Pi4J 网站上的文档和示例。非常欢迎反馈!请在你的项目中使用快照,并在 issues 或讨论区中告诉我们哪些功能正常、哪些功能出现问题。## 致谢

向所有为即将发布的 V5 贡献代码、评审、想法和测试的人致以最诚挚的感谢:

你可以在 GitHub 的 提交历史 中查看所有更改。