如何检测Linux板上GPIO引脚的变化

我在基于ARM的Linux板(imx233 CPU)上使用3.12内核。 我的目的是检测GPIO引脚的变化(1到0)。

我可以读取不断调用下面的函数的引脚值(在while(1)循环中)

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

但是这会给CPU造成太多的负担。 我不使用nanosleepnanosleep ,因为换针发生的时间很短,这会导致我错过这个事件。

据我所知,这是不可能使用poll() 。 是否有任何poll()函数,我可以用它来检测一个GPIO引脚变化?

编辑:以防万一,如果我做错了什么,这里是我的poll()用法,不检测引脚更改

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

编辑2:在https://developer.ridgerun.com/wiki/index.php/Gpio-int-test.c上的代码正常工作与poll()我需要定义中断的上升/下降边缘和一点点修复定义。 它解决了我的问题,但是,对于我和其他人听到/了解替代方法可能是好的。

Solutions Collecting From Web of "如何检测Linux板上GPIO引脚的变化"

我从来没有见过这个板子,但是我猜这个板子是PIC完全实现的(通常就是这样),但是你必须在GPIO控制器中另外配置中断(通常就是这样)。 有些部分应该作为内核模块来完成,那么你必须把有关中断的信息传给你的应用程序。

这样做的实例方法是将下面的东西作为内核模块来实现:

  • 设置GPIO控制器以在特定的端口和电平上启用中断(如何做到这一点,你可以在这里找到: http ://cache.freescale.com/files/dsp/doc/ref_manual/IMX23RM.pdf 37.2.3.3输入中断操作)

  • 在PIC中启用GPIO中断(如何执行此操作: http : //lwn.net/images/pdf/LDD3/ch10.pdf Chapter10)

  • 实现中断处理例程(我将在下面介绍一下)
  • 为你的模块实现ioctl接口。

并在你的应用程序中休息一下:

  • 一个函数可以coosomeoneperate与中断。

传递关于从内核到应用程序的中断信息的最简单的方法是通过内核方面的信号量。 在模块中,您可以实现一个可以休眠直到中断发生的ioctl。 所以应用程序将调用这个ioctl,它的线程将被阻塞,直到中断发生。

在模块内部,中断例程应该检查应用程序线程是否被阻塞,如果是的话()信号量。

编辑*****

该CPU具有SPI的工作模式的SSP。 为什么不使用它?