读取C中的端口(GPIO)值(beagleboard-xm)

时间:2012-07-07 14:35:40

标签: c beagleboard gpio

我有一个运行ubuntu 12.04的嵌入式主板(beagleboard-xm)。我需要连续读取GPIO以查看端口的值是否发生变化。我的代码如下:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

FILE *fp;

int main(void)
{
    //linux equivalent code "echo 139 > export" to export the port
    if ((fp = fopen("/sys/class/gpio/export", "w")) == NULL){
            printf("Cannot open export file.\n");
            exit(1);
        }
        fprintf( fp, "%d", 139 );
        fclose(fp);
      //  linux equivalent code "echo low > direction" to set the port as an input 
        if ((fp = fopen("/sys/class/gpio/gpio139/direction", "rb+")) == NULL){
            printf("Cannot open direction file.\n");
            exit(1);
        }
        fprintf(fp, "low");
        fclose(fp);

       // **here comes where I have the problem, reading the value**
        int value2;
        while(1){
        value2= system("cat /sys/class/gpio/gpio139/value");
        printf("value is: %d\n", value2);
        }
    return 0;
}

上面的代码连续读取端口(默认为0),但是,当我将端口更改为1时,system会调出输出正确的值,但是{{1}仍然打印printf作为输出。 0的问题是什么,它不存储value2输出的值。

如果我使用下面的代码而不是上面的system()循环,我会收到有关打开while文件(无法打开值文件。)的错误,如果我放了value行在fopen循环之外,它不会显示while文件中的更改。

value

我的问题:我如何修复代码?或者我该如何阅读char buffer[10]; while(1){ if ((fp = fopen("/sys/class/gpio/gpio139/value", "rb")) == NULL){ printf("Cannot open value file.\n"); exit(1); } fread(buffer, sizeof(char), sizeof(buffer)-1, fp); int value = atoi(buffer); printf("value: %d\n", value); } 文件? 作为一个额外的信息,我想知道:有什么区别,例如:按valuesystem("echo 139 > /sys/class/gpio/export")导出端口您建议我使用哪种方法?为什么呢?

提前谢谢。

2 个答案:

答案 0 :(得分:3)

system()函数返回cat的返回值,该值为0.它不返回cat的标准输出,这正是您所期望的。

我认为你的第二段代码的问题在于你没有打电话给fclose()。由于您在紧密循环中运行,因此几乎会立即超过允许的打开文件数。

所以,请致电fclose(),并考虑将sleep()放入其中。

答案 1 :(得分:1)

在C中读取文件时,文件中的位置会在您阅读时发生变化。例如,如果您要打开包含以下内容的文件:

First Line
Second Line
Third Line

并运行此程序:

char buffer[1024];
while(fgets(buffer, sizeof(buffer), theFile))
{
    printf("Buffer: %s", buffer);
}

它会打印出来:

First Line
Second Line
Third Line

当您读取每一行时,文件中的位置将更改为下一行。

在你的程序中,第一次读取值后,你试图读取文件中的空白空间,而不是你想要的值。

问题的解决方案是将fopen移到while循环之外,但每次循环时调用fseek将位置重置为文件的开头。

要使用fseek,您需要传递一个文件指针,字节偏移量和搜索点。在这里,您可以在文件中调用它,与航点SEEK_SET的偏移量为0字节,表示文件的起始位置。

fseek(theFile, 0, SEEK_SET);