嵌入式平台读取GPIO设备是否需要先解绑pca953x驱动?
问题原因确认
你遇到的读取失败问题确实是pca953x内核驱动占用导致的:
i2cdetect输出的UU标记明确表示该I2C地址已经被内核驱动绑定,默认情况下内核不允许同一I2C设备同时被内核驱动和用户空间i2c-dev接口访问,你直接用ioctl操作I2C设备会返回EBUSY错误。- 之前ZC706平台可以正常访问,是因为该平台的内核没有加载pca953x驱动,或者设备树中没有匹配tca6416的绑定配置,所以没有内核驱动占用该I2C地址,用户空间可以直接操作。
解决方案
你可以根据使用场景选择以下两种方案:
方案1:解绑pca953x驱动(适合快速调试验证)
这就是你提到的方案,操作步骤如下:
- 确认设备标识:你的I2C总线是6,设备地址是0x20,对应的设备节点名是
6-0020 - 执行解绑命令:
echo "6-0020" > /sys/bus/i2c/drivers/pca953x/unbind
- 验证解绑结果:执行
i2cdetect -y 6,如果0x20位置的标记从UU变成20,说明解绑成功,此时你原来的C代码可以正常运行。
注意:该操作是临时生效,设备重启后会恢复绑定。如果需要永久解绑,可以修改设备树中对应tca6416节点的
status属性为disabled,或者将pca953x驱动编译为内核模块,按需加载卸载。
方案2:通过内核GPIO子系统访问(推荐生产环境使用)
pca953x驱动已经将tca6416注册为标准GPIO芯片,不需要解绑驱动,直接通过GPIO通用接口访问即可,稳定性更高,不会引发内核态和用户态的I2C访问冲突:
- 找到该GPIO芯片的基号:执行
ls /sys/class/gpio/gpiochip*,找到对应pca953x的gpiochip节点,查看base文件获取GPIO起始编号。 - 导出需要访问的GPIO引脚:比如要读0x00寄存器的第0位,假设基号是480,对应引脚号就是480,执行
echo 480 > /sys/class/gpio/export - 读取引脚值:执行
cat /sys/class/gpio/gpio480/value即可获取电平值,也可以使用libgpiod库在C代码中实现更复杂的GPIO操作。
提醒:USRP N310的tca6416通常用于射频前端的频段切换、功放控制等功能,随意修改引脚电平可能导致USRP工作异常,操作前请确认对应引脚的用途。
内容的提问来源于stack exchange,提问作者Tellrell White
相关产品推荐
相关产品推荐

