使用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接口实现,该接口默认允许多个进程同时操作:
- 提前将对应GPIO导出到用户空间:
echo 64 > /sys/class/gpio/export,设置为输入模式:echo in > /sys/class/gpio/gpio64/direction,设置上升沿触发:echo rising > /sys/class/gpio/gpio64/edge - 应用1直接读取
/sys/class/gpio/gpio64/value文件获取当前电平 - 应用2用poll/epoll监听
/sys/class/gpio/gpio64/value文件的POLLPRI事件即可捕获上升沿
注意:sysfs GPIO接口已被内核官方标记为废弃,后续新版本内核可能会移除该能力,仅建议临时调试时使用。
内容的提问来源于stack exchange,提问作者mukesh
相关产品推荐
相关产品推荐

