You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用libgpiod对同一GPIO线分别请求输入和边缘事件失败如何解决

问题根因

Linux GPIO子系统默认对同一GPIO线的用户态请求采用独占保护机制,gpiod_line_request_input、gpiod_line_request_rising_edge_events等标准请求接口默认采用独占模式,第一个请求成功的进程会持有该GPIO的使用权,后续其他进程再发起同GPIO的独占请求会直接返回-1,你遇到的错误就是该机制导致的。

libgpiod 可行解决方案
  • 方案1:使用共享请求标志(适配libgpiod >= 1.5、内核 >= 5.7版本)
    调用带flags参数的请求接口,传入GPIOD_LINE_REQUEST_FLAG_ALLOW_SHARED标志即可放开独占限制,两个应用的请求方向均为输入,符合共享要求,修改示例如下:
    应用1请求代码修改:
// 替换原来的gpiod_line_request_input调用
ret = gpiod_line_request_input_flags(gs_gpiod_line, "gpio-test", GPIOD_LINE_REQUEST_FLAG_ALLOW_SHARED);

应用2请求代码修改:

// 替换原来的gpiod_line_request_rising_edge_events调用
ret = gpiod_line_request_rising_edge_events_flags(gs_gpiod_line, "DICnt-TEST", GPIOD_LINE_REQUEST_FLAG_ALLOW_SHARED);

该方案改动最小,注意使用过程中不要修改GPIO的输入输出方向,避免影响其他共享进程的逻辑。

  • 方案2:统一GPIO服务进程(全版本兼容)
    单独开发一个服务进程,由该进程唯一持有该GPIO的操作权限,对外提供本地IPC接口(比如Unix域套接字、共享内存等),应用1查询电平、应用2订阅上升沿事件的请求都发送给服务进程,由服务进程统一处理后返回结果。该方案无内核和libgpiod版本要求,也能避免多个进程操作GPIO的逻辑冲突,更适合生产环境使用。
替代实现方式

可以使用sysfs GPIO接口实现,该接口默认允许多个进程同时操作:

  1. 提前将对应GPIO导出到用户空间:echo 64 > /sys/class/gpio/export,设置为输入模式:echo in > /sys/class/gpio/gpio64/direction,设置上升沿触发:echo rising > /sys/class/gpio/gpio64/edge
  2. 应用1直接读取/sys/class/gpio/gpio64/value文件获取当前电平
  3. 应用2用poll/epoll监听/sys/class/gpio/gpio64/value文件的POLLPRI事件即可捕获上升沿
    注意:sysfs GPIO接口已被内核官方标记为废弃,后续新版本内核可能会移除该能力,仅建议临时调试时使用。

内容的提问来源于stack exchange,提问作者mukesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:36:04