Sto usando il kernel 3.12 su una scheda Linux basata su ARM (CPU imx233). Il mio scopo è quello di rilevare il cambio pin di un GPIO (da 1 a 0).come rilevare un cambio pin di un GPIO sulla scheda Linux
posso leggere il valore perno chiamando costantemente la funzione di seguito (in un po (1) ciclo)
int GPIO_read_value(int pin){
int gpio_value = 0;
char path[35] = {'\0'};
FILE *fp;
sprintf(path, "/sys/class/gpio/gpio%d/value", pin);
if ((fp = fopen(path,"rb+")) == NULL){ //echo in > direction
//error
}
fscanf(fp, "%d", &gpio_value);
fclose(fp);
return gpio_value;
}
ma provoca carico eccessivo alla CPU. Non uso usleep
o nanosleep
, perché il cambio pin avviene per un tempo molto breve che mi farebbe perdere l'evento.
Per quanto ho scoperto, non è possibile utilizzare poll()
. C'è una funzione simile a poll()
che posso usare per rilevare un cambio pin di un GPIO?
EDIT: Solo nel caso, se sto facendo qualcosa di sbagliato, ecco la mia poll()
utilizzo che non rileva la modifica perno
struct pollfd pollfds;
int fd;
int nread, result;
pollfds.fd = open("/sys/class/gpio/gpio51/value", O_RDWR);
int timeout = 20000; /* Timeout in msec. */
char buffer[128];
if(pollfds.fd < 0){
printf(" failed to open gpio \n");
exit (1);
}
pollfds.events = POLLIN;
printf("fd opens..\n");
while (1)
{
result = poll (&pollfds, 0, timeout);
switch (result)
{
case 0:
printf ("timeout\n");
break;
case -1:
printf ("poll error \n");
exit (1);
default:
printf("something is happening..\n");
if (pollfds.revents & POLLIN)
{
nread = read (pollfds.fd, buffer, 8);
if (nread == 0) {
printf ("result:%d\n", nread);
exit (0);
} else {
buffer[nread] = 0;
printf ("read %d from gpio: %s", nread, buffer);
}
}
}
}
close(fd);
EDIT2: il codice a https://developer.ridgerun.com/wiki/index.php/Gpio-int-test.c funziona bene con poll()
avevo bisogno di definire il fronte di salita/discesa per l'interrupt e un po 'di correzione sulla definizione. Risolve il mio problema, tuttavia, potrebbe essere utile per me e alcune altre persone ascoltare/conoscere i metodi alternativi.
E la API inotify? –
Quando dici che il pin è attivo solo per un "brevissimo tempo", di che tipo di tempo stai parlando? Perché avendo anche il polling attivo come fai tu, farlo dallo userspace potrebbe introdurre delle latenze che possono farti mancare comunque. –
Voglio usare un GPIO come chipselect per leggere i dati SPI. in stato di riposo è logico. Va alla logica bassa quando inizia la trasmissione. Pertanto, la reazione più veloce è e meglio è. Quando trovo un metodo appropriato, lo verificherò con una velocità più bassa. – Angs