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

BananaPi BPI-CM4(Android9)下I2C/GPIO交互故障求助

解决方案:Android 9下BPI-CM4 + Termux操作I2C/GPIO

一、先搞定Root权限

所有硬件操作都需要Root,确保设备已Root,且Termux能通过su切换到Root用户(执行su后验证权限:whoami返回root)。

二、解决I2C问题

1. 加载I2C内核模块

Android下没有modprobe,直接用insmod加载模块:

  • 先定位内核模块文件:find / -name "i2c_dev.ko"(通常路径为/system/lib/modules/或/lib/modules/)
  • 加载基础I2C模块:insmod /path/to/i2c_dev.ko
  • 加载对应硬件的I2C适配器模块(全志芯片为i2c_sunxi.ko,Amlogic芯片为i2c_meson.ko):insmod /path/to/i2c_sunxi.ko
  • 验证加载结果:lsmod | grep i2c,能看到对应模块即成功

2. 修复smbus2报错

  • 先给设备节点加权限:chmod 666 /dev/i2c-1
  • 编译安装i2c-tools检测设备:
    1. 安装编译依赖:pkg install gcc make git
    2. 下载源码:git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git
    3. 编译安装:cd i2c-tools && make && make install PREFIX=$PREFIX
    4. 检测I2C设备:i2cdetect -y 1,确认设备地址是否正确(Errno6大概率是地址错误或设备未连接)
  • 重新运行smbus2代码,确保使用i2cdetect输出的正确地址

3. 替代I2C操作方案

如果smbus2仍有问题,直接用Python操作/dev/i2c-1文件,示例代码:

import fcntl

I2C_SLAVE = 0x0703

def write_i2c(address, data):
    fd = open('/dev/i2c-1', 'rb+')
    fcntl.ioctl(fd, I2C_SLAVE, address)
    fd.write(bytearray(data))
    fd.close()

# 示例:向地址0x48写入[0x01, 0x00]
write_i2c(0x48, [0x01, 0x00])

三、GPIO操作方案

放弃树莓派专属库,直接用sysfs接口:

1. 基础命令操作(Root下)

  • 导出GPIO(以内核编号12为例):echo 12 > /sys/class/gpio/export
  • 设置为输出方向:echo "out" > /sys/class/gpio/gpio12/direction
  • 设置高电平:echo 1 > /sys/class/gpio/gpio12/value
  • 设置低电平:echo 0 > /sys/class/gpio/gpio12/value
  • 取消导出:echo 12 > /sys/class/gpio/unexport

2. Python封装示例

class GPIO:
    def __init__(self, gpio_num):
        self.gpio_num = gpio_num
        self.base_path = f"/sys/class/gpio/gpio{gpio_num}"
        # 导出GPIO
        with open("/sys/class/gpio/export", "w") as f:
            f.write(str(gpio_num))
    
    def set_direction(self, direction):
        with open(f"{self.base_path}/direction", "w") as f:
            f.write(direction)
    
    def set_value(self, value):
        with open(f"{self.base_path}/value", "w") as f:
            f.write(str(value))
    
    def cleanup(self):
        with open("/sys/class/gpio/unexport", "w") as f:
            f.write(str(self.gpio_num))

# 使用示例
gpio = GPIO(12)
gpio.set_direction("out")
gpio.set_value(1)
# 用完清理
gpio.cleanup()

四、解决SELinux限制

如果操作时出现权限拒绝,临时关闭SELinux:

su -c "setenforce 0"

五、注意事项

  • BPI-CM4的GPIO内核编号和物理引脚编号不对应,必须查官方硬件手册确认映射关系,不能直接用树莓派的引脚编号。
  • 如果找不到内核模块,说明官方Android固件默认未编译这些模块,需要刷入带硬件支持的开发版固件,或自行编译内核并开启I2C/GPIO相关选项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:20:32