reading a port (GPIO) value in C (beagleboard-xm)
-
19-06-2021 - |
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.
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);