Linux 内核 IIO 事件 sysfs 文件仅可读

Linux Kernel IIO events sysfs files only readable

我在为上升和下降阈值注册 IIO 事件时遇到了问题。 我可以在事件子文件夹中看到 sysfs 文件并可以读取它们,但是当我尝试编写一个新的阈值时,它显示 "permission denied".

以下设置:

static const struct iio_event_spec as6200_events[] = {
  {
    .type = IIO_EV_TYPE_THRESH,
    .dir = IIO_EV_DIR_RISING,
    .mask_separate = BIT(IIO_EV_INFO_VALUE),
  }, {
    .type = IIO_EV_TYPE_THRESH,
    .dir = IIO_EV_DIR_FALLING,
    .mask_separate = BIT(IIO_EV_INFO_VALUE),
  }
};

static const struct iio_chan_spec as6200_channels[] = {
  {
    .type = IIO_TEMP,
    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
      BIT(IIO_CHAN_INFO_PROCESSED) |
      BIT(IIO_CHAN_INFO_SCALE),
    .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
    .event_spec = as6200_events,
    .num_event_specs = ARRAY_SIZE(as6200_events),
  }
};

finding: it works when I change the permissions of the in_temp_thresh_rising_value file to 666 via sudo. But why is it not created with this permissions via IIO subsystem?

这是 sysfs 文件的常见做法,因为写入这些文件会改变系统的行为,甚至危及或破坏系统。所以如果你想写入这些文件,你应该从 root 执行,或者将你的用户添加到相应的组,或者更改文件模式(通过 udev 规则或手动)。

这是在 IIO 代码中的实现方式:

  • IIO sysfs 节点名称源自 drivers/iio/industrialio-event.c 中的下一个表:iio_ev_type_textiio_ev_dir_textiio_ev_info_text
  • 接下来是节点创建路径:iio_device_add_event() -> __iio_add_chan_devattr() -> __iio_device_attr_init()
  • 正在为 sysfs 节点设置文件模式 __iio_device_attr_init():

    • 阅读:dev_attr->attr.mode |= S_IRUGO;

      • 所以每个用户都可以读取节点(因为S_IRUGO允许RUser,G组和O其他)
    • 写作:dev_attr->attr.mode |= S_IWUSR;

      • 所以它只能由 root 写入(因为 S_IWUSR 只允许文件所有者写入,即 root)

这个问题的另一个解决方案是结合使用 libiio 的网络和本地上下文。在这种情况下,将以适当的权限启动 libiio 守护进程以写入 sysfs 文件,然后用户应用程序将使用 libiio 网络上下文连接到该守护进程。