【问题标题】:Android i2c permission deniedAndroid i2c 权限被拒绝
【发布时间】:2020-08-27 22:02:54
【问题描述】:

我开发了一个 NDK 应用程序来通过 i2c-dev 接口访问 i2c 设备。此应用程序在 Android 开发套件上运行,我们已在其上通过 i2c 连接了 MPU6050 设备。

我已经为设备设置了DT绑定,如下图

i2c@78b5000 {                                                           
    MPU6050@68 {
        compatible = "qcom, i2c-msm-v2";
        reg = <0x68>;
    };
};

并启用 i2c-1 总线 - 这是设备连接到的 i2c 总线 - 通过将以下行从“禁用”更改为“好的”

 &i2c_1 {                                                                    
     status = "okay";
 };

问题是当我尝试通过 open() 在我的应用程序中打开 i2c-1 文件时

char *filename = "dev/i2c-1";
const int file = open(filename, O_RDWR);

我收到返回的权限被拒绝错误代码。

我仅通过以下步骤成功读取了 WHO-AM-I 寄存器一次:

  1. 使用

    将/dev/i2c-1文件的权限调整为666
    $ chmod 666 i2c-1
    
  2. 修改 ueventd.rc 文件以包含此行

    /dev/i2c-1                0666   root       root
    
  3. 杀死 ueventd 进程以允许它重新加载。

    $ pgrep ueventd
    $ kill xxx
    

在 /dev 文件夹中运行 ls -la 将 i2c-1 的权限显示为

crw-rw-rw- root root 

此链接的更多详细信息:Android: how to grant 666 privs to a device via ueventd.rc

应用此过程的问题是,每次设备重新启动时,ueventd 文件都会恢复到原始状态并恢复权限。 从那以后,我尝试重复这个确切的过程,使用更改的文件/权限重建启动映像,并将新的启动映像刷入设备。这似乎不起作用,因为我仍然收到相同的“权限被拒绝”错误。

为了解决这个问题,我将 i2ctools 包含在系统映像中(没有库存)。在尝试运行 i2cdetect 时,我最初获得的权限被拒绝,所以我遵循了上述相同的程序。此过程成功允许 i2ctools 访问 /dev/i2c-1 并检测我的设备。

问题是使用 /dev/i2c-1 的 NDK 应用程序即使在应用该进程后仍然返回权限被拒绝。

我可能会修改我的应用程序以使用 i2ctools,但我的想法是,如果 i2ctools 在修改权限后可以访问 i2c-1,那么我的应用程序应该能够 - 如果我错了,请纠正我。

更新: 如果我以 root 身份运行 shell,我似乎只能使用 i2ctool;这是将 i2c-1 的权限设置为全局读/写。我还尝试将 i2c-1 所在的父文件夹的权限设置为 777 - 仍然是同样的问题。

谁能告诉我我做错了什么或如何停止权限被拒绝错误?

【问题讨论】:

  • 使用 IIO 内核驱动程序——这是正确的做法。
  • 我查看了 IIO,但不确定它是否适合我的要求。我应该在我的帖子中指出,我确实注意到需要对 i2c 设备进行快速读/写。 MPU6050 被用作通过 i2c 总线读取/写入能力的简单测试。未来我们将用 ASIC 代替 MPU6050,这需要通过向芯片写入一系列配置字节来进行设置。
  • IIO是针对传感器的(MPU6050有驱动),一般I2Cfast是互斥的。但大多数性能只能通过使用内核驱动程序或 RTOS 才能获得。
  • 我同意你的说法,我的意思是我需要一个 I2C 通信的通用实现,它可以在启动时发送大约 30 个字节。 MPU6050 只是临时的,我们将连接的设备(MIPI-DSI 到 RGB ASIC)没有驱动程序。如果我们要连接的设备还没有编写驱动程序,那么使用 IIO 有多难?我遇到的大多数资源似乎都在谈论 IIO 并将其与已编写且可供使用的驱动程序一起使用。
  • 好的,IIO 仅适用于您的传感器外壳 (MPU6050),其余的则需要内核驱动程序。

标签: android linux linux-kernel i2c


【解决方案1】:

问题似乎是由 SELinux 引起的。虽然不是永久解决方案,但我运行了命令

$ /system/bin/setenforce 0

从 adb shell 中,应用程序现在可以访问 i2c-1 并从设备成功读取。

更持久的解决方案是创建新的 SEPolicy 规则并将新策略设置为在启动时加载。这篇文章有更多关于这个主题的信息:https://android.stackexchange.com/questions/207484/how-to-fix-selinux-avc-denied-errors-when-launching-dnscrypt-as-init-d-script/207647#207647

[更新] 我已成功将 SELinux 设置为许可,并通过编辑 BoardConfig.mk 文件并添加该行在重新启动后保持不变

BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive

重建启动映像并将新映像刷入设备。

【讨论】:

    猜你喜欢
    • 2013-07-03
    • 2015-12-21
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2012-06-13
    相关资源
    最近更新 更多