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

如何在非Android Things的Android系统中通过NDK访问GPIO/SPI/I2C接口

树莓派LineageOS下NDK访问GPIO/SPI/I2C方案

接口底层运行逻辑

  • GPIO:Android基于Linux内核,和树莓派OS逻辑一致,GPIO通过sysfs节点(默认路径/sys/class/gpio/)控制,核心操作就是导出引脚、设置输入输出方向、读写电平值,你之前的理解完全正确。你所用的LineageOS16对应树莓派4.9版本以上内核,默认已经开启GPIO的sysfs支持。
  • I2C:内核加载i2c-dev驱动模块后,会生成/dev/i2c-*格式的字符设备文件,树莓派3B+默认启用的I2C总线对应/dev/i2c-1,操作时直接打开对应设备文件,通过ioctl系统调用指定从设备地址,即可完成数据读写。
  • SPI:内核启用spidev驱动后,会生成/dev/spidevX.Y格式的设备文件,X是总线编号、Y是片选编号,树莓派3B+默认SPI0总线的两个片选对应/dev/spidev0.0和/dev/spidev0.1。SPI的4引脚时序逻辑完全由内核驱动处理,不需要单独操作单个GPIO引脚,直接对设备文件做读写、通过ioctl配置时钟频率、极性、相位等参数即可完成通信。

树莓派LineageOS16前置配置

你所用的第三方编译版LineageOS已经默认把上述驱动编译进内核,只需要修改启动参数开启接口即可:

  1. 把树莓派的SD卡插到电脑上,打开boot分区的config.txt文件,添加以下配置:
dtparam=i2c_arm=on
dtparam=spi=on
dtparam=gpio_in_pull=up
  1. 保存文件后插回树莓派开机,通过adb shell进入系统目录,查看/dev/路径下有没有i2c-1、spidev0.0类文件,存在即说明接口启用成功。
  2. 权限配置:默认这些设备文件只有root权限可访问,调试阶段可以临时执行chmod 666 /dev/i2c-1 /dev/spidev0.0 /sys/class/gpio/export /sys/class/gpio/unexport开放权限,长期使用可以修改系统ueventd规则实现开机自动配置权限。

NDK调用示例

不需要移植第三方库,直接在native层操作对应设备文件即可:

GPIO操作示例

// 导出GPIO18引脚
int export_fd = open("/sys/class/gpio/export", O_WRONLY);
write(export_fd, "18", 2);
close(export_fd);
// 设置引脚为输出模式
int dir_fd = open("/sys/class/gpio/gpio18/direction", O_WRONLY);
write(dir_fd, "out", 3);
close(dir_fd);
// 输出高电平
int val_fd = open("/sys/class/gpio/gpio18/value", O_WRONLY);
write(val_fd, "1", 1);
close(val_fd);

I2C操作示例

#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
int fd = open("/dev/i2c-1", O_RDWR);
// 设置通信的从设备地址为0x48
ioctl(fd, I2C_SLAVE, 0x48);
// 读取2字节传感器数据
unsigned char buf[2];
read(fd, buf, 2);
close(fd);

SPI操作示例

#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
int fd = open("/dev/spidev0.0", O_RDWR);
// 配置SPI模式0
uint8_t mode = SPI_MODE_0;
ioctl(fd, SPI_IOC_WR_MODE, &mode);
// 配置最大通信时钟为1MHz
uint32_t speed = 1000000;
ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
// 半双工收发3字节数据
unsigned char tx_buf[3] = {0x01, 0x02, 0x03};
unsigned char rx_buf[3];
struct spi_ioc_transfer tr = {
    .tx_buf = (unsigned long)tx_buf,
    .rx_buf = (unsigned long)rx_buf,
    .len = 3,
    .speed_hz = speed,
    .bits_per_word = 8,
};
ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
close(fd);

如果对GPIO操作性能有要求,可以替换为更高效的gpiochar驱动方案,对应/dev/gpiochip*设备,操作逻辑和上述示例一致,调用内核对应ioctl指令即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:36:06