ENXIO对于i2c ioctl意味着什么?
我有一个i2c适配器作为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
/dev/i2c-0
暴露在用户空间中。当我从该适配器上的软件包中使用i2cdetect
时,我会看到该适配器上列出了我的设备,我可以从命令行对其执行获取、设置和转储操作
我有一些C代码,它试图使用ioctlI2C_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 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超时错误)。