Pergunta

I have an embedded board (beagleboard-xm) that runs ubuntu 12.04. I need to read a GPIO continuously to see if the value of the port changes. My code is herebelow:

#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;
}

the code above reads the port continuously (0 by default), however, when I change the port as 1, system call output the correct value, however printf still prints 0 as an output. What is the problem with value2 that does not store the value that system() outputs.

If I use the code below instead of while loop above, I get an error about opening the value file (Cannot open value file.), if I put the fopen line outside of while loop, it does not show the changes in the value file.

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

    }

My question: how do I need to fix the code? or how should I read the value file? As an additional info that I wonder: what is the difference to e.g. export the port by system("echo 139 > /sys/class/gpio/export") and fp = fopen("/sys/class/gpio/export","w"); fprintf(fp,"%d",139); which method do you suggest me to use? Why?

Thank you in advance.

Foi útil?

Solução

The system() function returns the return value of cat, which is 0. It does not return the standard output from cat, which is what you were expecting.

I think the problem with your second bit of code is that you're not calling fclose(). Since you're running in a tight loop, you almost immediately exceed the number of open files allowed.

So, call fclose(), and think about putting a sleep() in there too.

Outras dicas

When reading a file in C, your position in the file changes as you read it. For example, if you were to open a file with the contents:

First Line
Second Line
Third Line

and run this program:

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

It would print:

First Line
Second Line
Third Line

As you read each line, the position in the file changes to the next line.

In your program, after reading the value the first time, you are trying to read the empty space in the file, instead of the value you want.

The solution to your problem is to move fopen outside of the while loop, but call fseek to reset your position to the start of the file each time through the loop.

To use fseek, you need to pass it a file pointer, byte offset and seek point. Here you call it on your file, with a 0 byte offset from the waypoint SEEK_SET, which indicates the start of the file.

fseek(theFile, 0, SEEK_SET); 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top