2014-09-21 13 views
7

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.

+0

E la API inotify? –

+1

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. –

+0

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

risposta

1

Non ho mai visto questa scheda prima, tuttavia suppongo che PIC sia completamente implementato per questa scheda (di solito è così), ma è necessario configurare l'interrupt in aggiunta nel controller GPIO (di solito è così). Alcune parti dovrebbero essere fatte come un modulo del kernel, quindi devi passare le informazioni sull'interrupt alla tua applicazione.

Esempio modo per farlo è quello di attuare in seguito cosa come un modulo del kernel:

e un periodo di riposo nella vostra applicazione:

  • una funzione che può coosomeoneperate con interrupt.

Il modo più semplice per passare informazioni sull'interrupt dal kernel all'app è tramite semaforo sul lato kernel. nel modulo è possibile implementare un ioctl che si interromperà fino a quando si verificherà l'interruzione. Quindi l'applicazione chiamerà questo ioctl e il suo thread sarà bloccato fino a quando non si verificherà l'interruzione.

All'interno del modulo, la routine di interrupt deve verificare se il thread dell'applicazione è ora bloccato e se è così su() semaforo.

EDIT *****

Questa CPU ha SSP che ha modo di funzionamento per SPI. Perché non usarlo ??

Problemi correlati