【问题标题】:reading a port (GPIO) value in C (beagleboard-xm)在 C (beagleboard-xm) 中读取端口 (GPIO) 值
【发布时间】:2012-07-07 14:35:39
【问题描述】:

我有一个运行 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调用输出正确的值,但是printf仍然打印0作为输出。 value2 不存储 system() 输出的值有什么问题。

如果我使用下面的代码而不是上面的while 循环,如果我将fopen 行放在while 循环之外,我会收到关于打开value 文件的错误(无法打开值文件。) ,它不会显示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);

    }

我的问题:我需要如何修复代码?或者我应该如何阅读value 文件? 作为我想知道的附加信息:与例如有什么区别?通过system("echo 139 &gt; /sys/class/gpio/export")fp = fopen("/sys/class/gpio/export","w"); fprintf(fp,"%d",139); 导出端口,您建议我使用哪种方法?为什么?

提前谢谢你。

【问题讨论】:

  • 调用system(3) 非常昂贵——您的进程首先执行fork(2),然后在子进程上执行/bin/sh 以处理命令。

标签: c beagleboard gpio


【解决方案1】:

system() 函数返回 cat 的返回值,即 0。它不会返回来自 cat 的标准输出,这正是您所期望的。

我认为您的第二段代码的问题在于您没有调用fclose()。由于您在一个紧密的循环中运行,您几乎立即超过了允许的打开文件数。

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

【讨论】:

    【解决方案2】:

    在 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); 
    

    【讨论】:

    • 你确定寻找像/sys那样的伪文件的开头会刷新内核将要传递的内容吗?
    • 不确定,取决于它是如何实现的。你只需要尝试一下。
    猜你喜欢
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多