How to detect GPIO change on Linux board

I am using Linux kernel based on ARM based Linux 3.12 (imx233 CPU). My goal is to detect a GPIO finger change (1 to 0).

I can read the pin value constantly calling the function below (during the (1) loop)

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

But this causes too much CPU load. I do not use usleep or nanosleep , because the contact change occurs within a very short time, because of which I miss the event.

As far as I know, using poll() not possible. Is there any poll() function that I can use to detect GPIO finger changes?

EDIT: Just in case, if I am doing something wrong, here is my use of poll() , which does not detect shift change

 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: the code https://developer.ridgerun.com/wiki/index.php/Gpio-int-test.c works fine with poll() I needed to define a rising / falling edge for the interrupt and fix it a bit for definition. This solves my problem, however it may be good for some other people to hear / learn alternative methods.

+7
c linux posix embedded-linux gpio
source share
1 answer

I have never seen this board before, but I believe that PIC is fully implemented for this board (usually it is), but you need to additionally configure the interrupt in the GPIO controller (usually it is). Some part should be executed as a kernel module, then you need to pass the interrupt information to your application.

An example for this is to implement the following as a kernel module:

and rest in the application:

  • function that can interact with interrupt.

The simplest way to pass interrupt information from the kernel to the application is by using a kernel side semaphore. in the module, you can implement ioctl, which will sleep until an interrupt occurs. Therefore, the application will call this ioctl, and its flow will be blocked until interruption occurs.

Inside the module, the interrupt procedure must check if the application thread is blocked, and if so () a semaphore.

EDIT *****

This processor has an SSP that has an operating mode for SPI. Why not use it?

+1
source share

All Articles