使用 fgetc 读取 gpio 的 linux sysfs
Posted
技术标签:
【中文标题】使用 fgetc 读取 gpio 的 linux sysfs【英文标题】:reading linux sysfs for gpio with fgetc 【发布时间】:2015-08-21 19:36:52 【问题描述】:我编写了一个简单的程序来使用没有轮询的 linux sysfs 读取 gpio,但是当我想读取少于三个字符时 fgetc 和 fgets 无法正常工作我想知道这只是一个错误还是我做错了在我的代码中。
FILE* fd = fopen("/sys/class/gpio/gpio12/value", "rw+");
if(!fd)
cerr << "could not open the file." << endl;
setbuf(fd, NULL);
while(true)
if(fseek(fd, 0L, SEEK_SET))
cerr << "could not reposition the indicator" << endl;
char val = fgetc(fd);
cout << val << '\r';
cout.flush();
;
即使我对 gpio#12 施加高电平电压,上述代码也总是返回“0”,但是当我替换 fgetc 并且它与这些代码一致时
char str[3] = 0;
fgets(str, 3, fd);
cout << str[0] << 'r';
行程序正常工作。另一方面,值文件仅包含一个字符“1”或“0”,人们可能会考虑使用带有 2 个或 1 个字符的 fget。在这种情况下,它也不起作用。可以请一位专业人士解释那里发生了什么。上面的代码有什么问题。 我使用g++编译代码,我的gcc版本是4.6.3-14 armhf
【问题讨论】:
【参考方案1】:您可以使用 /bin/cat 来显示 /sys/class/gpio/gpioXX/value 文件的内容。该文件的内容将是 ASCII 字符“0”或 ASCII 字符“1”后跟换行符“\n”。
我认为您可以简单地获取文件中的第 0 个字节,看看它是 ASCII '0' (0x30) 字符还是 ASCII '1' 字符 (0x31)。在这种情况下,缓冲 I/O 没有意义。
int fd;
char val;
int ret;
if ((ret = open("/sys/class/gpio/gpio12/value", O_RDONLY)) < 0)
// Fail.
return;
fd = ret;
for (;;)
if ((ret = lseek(fd, 0, SEEK_SET)) < 0)
// Fail.
break;
if ((ret = read(fd, &val, 1)) < 0)
// Fail.
break;
if ((val != 0x30) && (val != 0x31))
// Whiskey tango foxtrot.
val = val - 0x30;
fprintf(stdout, "val=%d\n", val);
fflush(stdout);
;
【讨论】:
感谢您的回复,如果您提到'setbuf(fd, NULL);',我当然使用了无缓冲流是的,在这种情况下读取工作正常,但为什么 iso c fgetc 不起作用。是不是因为重新定位操作不适用于 fgetc 或类似这样的东西。 @AMCoded:您说您的 fgetc 示例不起作用,但我在嵌入式 ev500 PPC linux 上尝试过它,它是 A-OK。同样,我认为您在对大小为两个字节的 sysfs 虚拟文件进行操作时不必担心缓冲 I/O 的语义,只需使用 open(2)、lseek(2) 和 read(2 ) 并可能将您的学习精力集中在更有用的东西上。 好的,谢谢,因为它在您的嵌入式系统中工作,我不会花更多时间在它上面。我已经在 raspbian 中为树莓派板测试了上面的代码。它没有工作,所以我将它标记为 raspbian gcc 的错误。以上是关于使用 fgetc 读取 gpio 的 linux sysfs的主要内容,如果未能解决你的问题,请参考以下文章
C++:使用 fgetc 读取 csv 文件,并用分号“;”分隔单词