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

Windows下Android Studio开发Orange Pi CM4 C++模块缺失SMBus方法定义

解决Android Studio开发RK3566平台C++模块时SMBus方法缺失问题

问题背景

在Windows环境下使用Android Studio为Orange Pi CM4(搭载Rockchip 3566、Android 11、Linux内核4.19.232)开发C++模块时,遇到以下问题:

  • 无法找到<i2c/smbus.h>头文件,导致i2c_smbus_read_word_data()、i2c_smbus_write_word_data()等SMBus方法无定义
  • 已能通过read()/write()读写/dev/i2c-2端口,但SMBus专用方法无法使用
  • NDK 25.1的<linux/i2c.h>仅包含SMBus相关常量(如I2C_FUNC_SMBUS_READ_WORD_DATA),无方法原型
  • 确认厂商内核源码RK356X_Android11/kernel/drivers/i2c-core-smbus.c存在方法实现,推测缺失用户态头文件

解决方案

1. 手动补充<i2c/smbus.h>头文件

SMBus方法的原型定义在用户态头文件里,你有两个可靠来源:

  • 从厂商内核源码提取:找到内核源码中的RK356X_Android11/kernel/include/linux/i2c/smbus.h,将其复制到你的C++模块的jni/include/linux/i2c/目录下(需手动创建对应层级)
  • 从i2c-tools源码提取:下载i2c-tools开源源码,从中取出include/linux/i2c/smbus.h,同样放到项目的头文件目录中

之后在代码中修改头文件引用路径为本地路径,或者在CMakeLists.txt中添加头文件搜索路径:

include_directories(${CMAKE_SOURCE_DIR}/jni/include)

2. 自行封装SMBus方法(无需依赖外部库)

如果不想引入额外头文件,可直接通过ioctl调用内核的SMBus接口,本质上i2c_smbus_*系列函数都是封装了I2C_SMBUS类型的ioctl请求。以下是示例封装:

#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

static inline __s32 i2c_smbus_read_word_data(int fd, __u8 command) {
    union i2c_smbus_data data;
    struct i2c_smbus_ioctl_data args = {
        .read_write = I2C_SMBUS_READ,
        .command = command,
        .size = I2C_SMBUS_WORD_DATA,
        .data = &data
    };
    if (ioctl(fd, I2C_SMBUS, &args) < 0)
        return -1;
    return data.word;
}

static inline __s32 i2c_smbus_write_word_data(int fd, __u8 command, __u16 value) {
    union i2c_smbus_data data;
    data.word = value;
    struct i2c_smbus_ioctl_data args = {
        .read_write = I2C_SMBUS_WRITE,
        .command = command,
        .size = I2C_SMBUS_WORD_DATA,
        .data = &data
    };
    return ioctl(fd, I2C_SMBUS, &args);
}

3. 集成i2c-tools的libi2c库(完整SMBus支持)

若需要完整的SMBus工具链,可将i2c-tools的libi2c库编译到项目中:

  • 下载i2c-tools源码,解压到项目的jni/i2c-tools目录下
  • 在CMakeLists.txt中添加编译规则:
# 添加libi2c编译
add_subdirectory(jni/i2c-tools/lib)
# 链接到你的模块
target_link_libraries(你的模块名称 PRIVATE libi2c)
  • 注意适配NDK交叉编译:修改i2c-tools/lib目录下的Makefile,替换为NDK的编译器(如arm-linux-androideabi-gcc),或直接用CMake重新编写编译脚本

4. 权限配置

Android 11对设备节点访问有严格限制,需确保:

  • 在AndroidManifest.xml中添加硬件访问权限:
<uses-permission android:name="android.permission.HARDWARE_TEST" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 部分设备需此权限访问I2C -->
  • 若设备已root,可手动修改/dev/i2c-2的权限为666,或配置SELinux规则允许应用访问该节点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:53:22