TS-4900 interrupts: Difference between revisions

From embeddedTS Manuals
No edit summary
(Grammar, clarifications)
 
(One intermediate revision by one other user not shown)
Line 7: Line 7:
</source>
</source>


From here, you would need to use a lower level language to poll() or select() on /sys/class/gpio/gpio48/value.
From here, an application can poll() or select() on the "/sys/class/gpio/gpio48/value" file and will return when the edge setting has been triggered:


<source lang=c>
<source lang=c>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/select.h>
Line 21: Line 22:
int ret, irqfd = 0, i = 0;
int ret, irqfd = 0, i = 0;
fd_set fds;
fd_set fds;
FD_ZERO(&fds);
int buf;
   
   
if(argc < 2) {
if(argc < 2) {
Line 35: Line 38:
return 1;
return 1;
}
}
 
// Read first since there is always an initial status
ret = read(irqfd, &buf, sizeof(buf));
 
while(1) {
while(1) {
int buf; // Holds irq junk data
FD_SET(irqfd, &fds);
FD_SET(irqfd, &fds); //add the fd to the set
// See if the IRQ has any data available to read
// See if the IRQ has any data available to read
ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
Line 46: Line 51:
FD_CLR(irqfd, &fds);  //Remove the filedes from set
FD_CLR(irqfd, &fds);  //Remove the filedes from set
printf("IRQ detected %d\n", i);
printf("IRQ detected %d\n", i);
fflush(stdout);
i++;
i++;
// Clear the junk data in the IRQ file
/* The return value includes the actual GPIO register value */
read(irqfd, &buf, sizeof(buf));
read(irqfd, &buf, sizeof(buf));
lseek(irqfd, 0, SEEK_SET);
}
}
   
   
//Sleep, or do any other processing here
//Sleep, or do any other processing here
usleep(10000);
usleep(100000);
}
}
   
   
Line 59: Line 67:
</source>
</source>


This example can be run as "./irqtest 48" which will echo every time the pin changes, but will otherwise take no cpu time.
This example can be run as "./irqtest 48" which will echo every time the pin changes but not consume any CPU time while waiting for an edge to occur.

Latest revision as of 12:39, 6 March 2019

The i.MX6 CPU GPIO are also able to function as interrupts on rising and falling edges. This is accessible from the kernel as well as userspace. Userspace IRQs are exposed through the sysfs gpio mechanism. This example will trigger on a falling edge for GPIO 48:

echo "48" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio48/direction
echo "falling" > /sys/class/gpio/gpio48/edge

From here, an application can poll() or select() on the "/sys/class/gpio/gpio48/value" file and will return when the edge setting has been triggered:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
 
int main(int argc, char **argv)
{
	char gpio_irq[64];
	int ret, irqfd = 0, i = 0;
	fd_set fds;
	FD_ZERO(&fds);
	int buf;
 
	if(argc < 2) {
		printf("Usage: %s <gpio number>\n", argv[0]);
		return 1;
	}
 
	snprintf(gpio_irq, sizeof(gpio_irq), "/sys/class/gpio/gpio%d/value", atoi(argv[1]));
	irqfd = open(gpio_irq, O_RDONLY, S_IREAD);
 
	if(irqfd == -1) {
		printf("Could not open IRQ %s\n", argv[1]);
		printf("Make sure the GPIO is already exported", argv[1]);
		return 1;
	}

	// Read first since there is always an initial status
	ret = read(irqfd, &buf, sizeof(buf));

	while(1) {
		FD_SET(irqfd, &fds);
		// See if the IRQ has any data available to read
		ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
 
		if(FD_ISSET(irqfd, &fds))
		{
			FD_CLR(irqfd, &fds);  //Remove the filedes from set
			printf("IRQ detected %d\n", i);
			fflush(stdout);
			i++;
			
			/* The return value includes the actual GPIO register value */
			read(irqfd, &buf, sizeof(buf));
			lseek(irqfd, 0, SEEK_SET);
		}
 
		//Sleep, or do any other processing here
		usleep(100000);
	}
 
	return 0;
}

This example can be run as "./irqtest 48" which will echo every time the pin changes but not consume any CPU time while waiting for an edge to occur.