IIO设备缓冲区始终为空。

4

我正在使用一种名为LSM6DSL的IMU传感器,与iio驱动程序配合使用。如果我运行以下命令显示原始值,它们可以正常工作:

cat /sys/bus/iio/devices/iio:device0/in_accel_x_raw

然后我决定使用libiio,这样我就可以从C程序中读取所有这些值:

struct iio_context *context = iio_create_local_context();
struct iio_device *device = iio_context_get_device(context, 1);
struct iio_channel *chan = iio_device_get_channel(device, 0);
iio_channel_enable(chan);
if (iio_channel_is_scan_element(chan) == true)
    printf("OK\n");
struct iio_channel *chan2 = iio_device_get_channel(device, 1);
iio_channel_enable(chan2);
struct iio_buffer *buff = iio_device_create_buffer(device, 1, true);
if (buff == NULL)
{
  printf("Error: %s\n", strerror(errno));
  return (1);
}

这是结果:

OK
Error: Device or resource busy

我有遗漏吗?如果您需要更多信息,请告诉我。


1
很难说是什么原因。可能是权限问题(尝试使用root?)或库错误。您应该调试您的程序+ libiio(使用gdbstrace或只需添加printf跟踪)。在调用iio_device_create_buffer()之前设置断点,并向下步进,直到找到确切发生-EBUSY错误的位置。您可能需要使用调试符号来调试libiio。如果您需要我们的帮助,请在此处更新,提及在libiio中设置-EBUSY的确切代码行。 - Sam Protsenko
此外,通过在libiio源代码中使用“EBUSY”关键词进行grep操作是一个好主意。假设这个错误是由libiio函数而不是syscall/libc函数(如“open()”或“fopen()”)返回的,你可能会对发生了什么有一个相当好的想法。 - Sam Protsenko
1
@SamProtsenko,顺便说一下,有一个技巧可以用来找到罪魁祸首代码行,即#undef EINVAL; #define EINVAL __LINE__。也许我得写一篇文章来介绍它 :-) - 0andriy
@0andriy 很巧妙的技巧 :) 但在这种情况下,您必须重新构建libiio以利用该技巧。而且仍然有可能-EBUSY来自某些系统调用或libc调用。因此,在这里我倾向于使用老式的调试方法。 - Sam Protsenko
@0andriy 谈到调试技巧,我发现最有用的是我称之为“智能grep”的方法。它的意思是:1)使用grep/cscope/等工具定位可能导致问题的所有代码位置。2)利用你的知识和逻辑进一步缩小可能的原因,这通常会立即给出答案,消除了实际调试的需要。3)如果仍然有几个可能的原因——几个printk/printf跟踪通常足以快速找出实际原因所在。这种方法唯一的问题是要强迫自己更经常地使用它 :) - Sam Protsenko
显示剩余2条评论
1个回答

2

我想我找到了答案,而且我没有注意到ncurses库的影响(很抱歉没有提到我在使用它)。

我将这些函数移到ncurses初始化之前,现在缓冲区创建成功了。


好事是你找到了问题的根本原因。继续并接受你的答案。 - Sam Protsenko
嗨,Stackoverflow说我将能在20小时内完成! - user7581609

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接