ENXIO对于i2c ioctl意味着什么?

ENXIO对于i2c ioctl意味着什么?,c,linux,i2c,C,Linux,I2c,我有一个i2c适配器作为/dev/i2c-0暴露在用户空间中。当我从该适配器上的软件包中使用i2cdetect时,我会看到该适配器上列出了我的设备,我可以从命令行对其执行获取、设置和转储操作 我有一些C代码,它试图使用ioctlI2C_RDWR操作对其执行写操作 下面是我正在使用的精简代码(仅为上下文提供,运行它对回答问题并不重要) 我还尝试过使用smbus ioctl函数,如下所示 fd = open ("/dev/i2c-0", O_RDWR | O_NONBLOCK); /* other

我有一个i2c适配器作为
/dev/i2c-0
暴露在用户空间中。当我从该适配器上的软件包中使用
i2cdetect
时,我会看到该适配器上列出了我的设备,我可以从命令行对其执行获取、设置和转储操作

我有一些C代码,它试图使用ioctl
I2C_RDWR
操作对其执行写操作

下面是我正在使用的精简代码(仅为上下文提供,运行它对回答问题并不重要)

我还尝试过使用smbus ioctl函数,如下所示

fd = open ("/dev/i2c-0", O_RDWR | O_NONBLOCK);

/* other stuff happens here */

if (ioctl (fd, I2C_FUNCS, &funcs) != 0)
    return -1;
if (!(funcs & I2C_FUNC_SMBUS_WORD_DATA))
    return -1;

/* i added this bit of debug just to be sure fd didn't
 * get inadvertently closed along the way.
 */
if (fcntl (fd, F_GETFD) != 0) {
    return -1;
}

/* build the ioctl smbus message payload */

if (ioctl (fd, I2C_SLAVE_FORCE, dev) != 0)
    return -1;

ret = ioctl (fd, I2C_SMBUS, &payload);
if (ret) {
    fprintf (stderr, "ioctl returned %d. Reason: %s (errno=%d).",
             ret, strerror(errno), errno);
    return -1;
}

return 0;
在所有情况下,程序总是点击
fprintf
,这是输出:

ioctl返回-1。原因:没有这样的设备或地址(errno=6)

根据,ENXIO错误的“一般”原因是:

ENXIO请求和arg参数对此设备驱动程序有效,但无法在此特定子设备上执行请求的服务

然而,正如Ian在评论中指出的那样,上面手册页中关于流的信息在Linux上并不相关,我应该使用——不幸的是,这主要是说IOCTL并不真正符合任何标准,任何事情都会发生

这引发了三个问题

fd = open ("/dev/i2c-0", O_RDWR | O_NONBLOCK);

/* other stuff happens here */

if (ioctl (fd, I2C_FUNCS, &funcs) != 0)
    return -1;
if (!(funcs & I2C_FUNC_I2C))
    return -1;

/* i added this bit of debug just to be sure fd didn't
 * get inadvertently closed along the way.
 */
if (fcntl (fd, F_GETFD) != 0) {
    return -1;
}

/* build the ioctl message payload */

ret = ioctl (fd, I2C_RDWR, &payload)
if (ret) {
    fprintf (stderr, "ioctl returned %d. Reason: %s (errno=%d).",
             ret, strerror(errno), errno);
    return -1;
}

return 0;
  • 这对i2c适配器意味着什么?此设备的驱动程序是否不支持使用此方法进行读写
  • 手册页包含I_uu前缀操作的返回代码的特定描述,但不包含其他操作的返回代码。是否有其他地方可以查找I2C ioctl操作的特定信息
  • 在哪里可以找到i2c ioctl函数的源代码

  • 通常,这意味着设备没有响应。具体取决于您的硬件

    通用I2C ioctl代码是I2C开发包的一部分,它是lm传感器项目的一部分。这些IOCTL没有自己的手册页,但确实有

    在内核中,实现都保存在和中。切入点是。这些通用代码都不会返回ENXIO

    最终,该通用代码需要调用i2c总线上的硬件级驱动程序功能。i2c总线的硬件驱动程序存储在中。每个驱动程序都可以实现一个或两个
    master\u xfer
    (用于
    I2C\u RDWR
    ioctls)或
    smbus\u xfer
    (用于
    I2C\u smbus
    )功能


    在我的例子中,该设备实际上没有专用的i2c硬件,并且使用的似乎是在功能上实现的一个非常强大的软件仿真。ENXIO源于函数。

    对STREAMS设备的引用对于Linux来说有点无关,因为它不支持。你真的应该看看。@IanAbbott嗯,那本书甚至没有提到安西欧(请参阅“符合”一节:)对于i2c,我认为ENXIO意味着它得到了一个意外的NAK。您阅读过关于这个开发接口的内核文档吗?I2C_RDRW ioctl接口非常复杂,您的有效负载是如何构建的,这会很有趣。也许是错误。该文件还说I2C_SMBUS IOCTL“不是直接调用的,而是使用下面的访问函数。”所以我会尝试使用它们。不管怎样,这个界面看起来容易多了。提示:使用
    dmesg
    读取内核日志。通常,它会有失败的原因(例如,如果设备没有响应,则会出现I2C超时错误)。