【发布时间】:2016-07-15 16:25:06
【问题描述】:
我有一个 i2c 适配器以 /dev/i2c-0 暴露给用户空间。当我在该适配器上使用 i2c-tools 包中的 i2cdetect 时,我看到我的设备列在此适配器上,并且我能够从命令行对其执行获取、设置和转储操作。
我有一些 C 代码尝试使用 ioctl I2C_RDWR 操作对其执行写入操作。
这是我正在使用的精简代码(仅为上下文提供,运行它对于回答问题并不重要)。
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;
我也尝试过使用 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)。
根据man 3 ioctl,ENXIO 错误的“一般”原因是:
ENXIO request 和 arg 参数对此设备驱动程序有效,但请求的服务无法在此特定子设备上执行.
然而,正如 Ian 在 cmets 中指出的那样,上述手册页中有关 STREAMS 的信息与 Linux 无关,我应该使用 man 2 ioctl - 不幸的是,这主要是说 ioctls 不真正符合任何标准,什么都行。
这提出了三个问题。
- 这对 i2c 适配器意味着什么?这个设备的驱动不支持用这种方法读写吗?
- 手册页包含 I_ 前缀操作的返回码的具体描述,但不包含其他操作的返回码。是否有其他地方可以查找特定于 I2C ioctl 操作的信息?
- 在哪里可以找到 i2c ioctl 函数的源代码?
【问题讨论】:
-
对 STREAMS 设备的引用与 Linux 无关,因为它不支持 STREAMS。你真的应该看看
man 2 ioctl。 -
@IanAbbott 嗯,那个甚至没有提到 ENXIO。 :(
-
参见“符合”部分。 :)
-
对于 i2c,我认为 ENXIO 意味着它得到了意外的 NAK。
-
您是否阅读过有关此开发接口的内核文档? @ 987654326@ 恕我直言,I2C_RDRW ioctl 接口非常复杂,如果您的有效负载是如何构建的,将会很有趣。也许有错误。该文档还说 I2C_SMBUS ioctl 是“不打算直接调用;相反,请使用下面的访问函数。”所以我会尝试使用它们。无论如何,这个界面看起来要容易得多。