TS-4100 interrupts: Difference between revisions

From embeddedTS Manuals
No edit summary
No edit summary
Line 15: Line 15:
#include <sys/stat.h>
#include <sys/stat.h>
#include <unistd.h>
#include <unistd.h>
 
int main(int argc, char **argv)
int main(int argc, char **argv)
{
{
Line 21: Line 21:
int ret, irqfd = 0, i = 0;
int ret, irqfd = 0, i = 0;
fd_set fds;
fd_set fds;
FD_ZERO(&fds);
   
   
if(argc < 2) {
if(argc < 2) {
Line 26: Line 27:
return 1;
return 1;
}
}
 
snprintf(gpio_irq, sizeof(gpio_irq), "/sys/class/gpio/gpio%d/value", atoi(argv[1]));
snprintf(gpio_irq, sizeof(gpio_irq), "/sys/class/gpio/gpio%d/value", atoi(argv[1]));
irqfd = open(gpio_irq, O_RDONLY, S_IREAD);
irqfd = open(gpio_irq, O_RDONLY, S_IREAD);
 
if(irqfd == -1) {
if(irqfd == -1) {
printf("Could not open IRQ %s\n", argv[1]);
printf("Could not open IRQ %s\n", argv[1]);
Line 35: Line 36:
return 1;
return 1;
}
}
 
while(1) {
while(1) {
int buf; // Holds irq junk data
int buf; // Holds irq junk data
Line 41: Line 42:
// 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);
if(ret == -1) {
FD_ZERO(&fds);
continue;
}
 
if(FD_ISSET(irqfd, &fds))
if(FD_ISSET(irqfd, &fds))
{
{
FD_CLR(irqfd, &fds);  //Remove the filedes from set
printf("IRQ detected %d\n", i);
printf("IRQ detected %d\n", i);
i++;
i++;
Line 51: Line 55:
read(irqfd, &buf, sizeof(buf));
read(irqfd, &buf, sizeof(buf));
}
}
//Sleep, or do any other processing here
usleep(10000);
}
}
   
   

Revision as of 13:23, 29 June 2016

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, you would need to use a lower level language to poll() or select() on /sys/class/gpio/gpio48/value.

#include <stdio.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);
 
	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;
	}

	while(1) {
		int buf; // Holds irq junk data
		FD_SET(irqfd, &fds); //add the fd to the set
		// See if the IRQ has any data available to read
		ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
		if(ret == -1) {
			FD_ZERO(&fds);
			continue;
		}

		if(FD_ISSET(irqfd, &fds))
		{
			printf("IRQ detected %d\n", i);
			i++;
			// Clear the junk data in the IRQ file
			lseek(irqfd, 0, 0);
			read(irqfd, &buf, sizeof(buf));
		}
	}
 
	return 0;
}

This example can be run as "./irqtest 48" which will echo every time the pin changes, but will otherwise take no cpu time.