我等待更改GPIO引脚电平(上升沿或下降沿)时需要释放处理器,所以我创建了一个简单的代码来轮询GPIO sysfs值文件,但是我是陷入困境:
在第一次poll()
调用中,它会退出i POLLPRI
中设置POLLERR
和revents
;
在此之后,我lseek()
和read()
fd,然后循环回poll()
;
现在poll()
挂起。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/fcntl.h>
#define GPIO_DIR "/sys/class/gpio/"
#define GPIO_EXPORT GPIO_DIR "export"
int main(int argc, char **argv)
{
int gpio_fd;
struct pollfd gpio_fdset[1];
char pin_value[] = GPIO_DIR "gpioXYZ/value";
sprintf(pin_value, GPIO_DIR "gpio%s/value", argv[1]);
gpio_fd = open(pin_value, O_RDONLY);
while (1)
{
char buffer[64];
gpio_fdset[0].fd = gpio_fd;
gpio_fdset[0].events = POLLPRI;
gpio_fdset[0].revents = 0;
poll(gpio_fdset, 1, -1);
if (gpio_fdset[0].revents & POLLPRI)
{
printf("revents returned POLLPRI!\n");
lseek(gpio_fdset[0].fd, 0, SEEK_SET);
read(gpio_fdset[0].fd, buffer, 64);
}
}
}
在调用它之前,我导出了我想监视的引脚(内核编号方案中的GPIO1_30或62)。我尝试将此引脚设置为输入,输出,在上升沿和下降沿产生中断,但行为始终相同。我错过了什么?
根据我的阅读,当我使用sysfs时,我不需要使用gpio_request(),gpio_to_irq()和其他相关函数来轮询此引脚。这是对的吗?
此致
吉尔赫尔梅
答案 0 :(得分:1)
我发现了如何克服这个问题。在设置打开文件描述符后,只需执行虚拟读取()。显然这是因为最近打开的fd被认为已经改变(至少对于GPIO而言)。至于revents上的POLLERR,这是standard sysfs behaviour。
答案 1 :(得分:0)
如果我理解你的要求是正确的,那么当引脚变高时你想要采取一些行动。
你可以自己轮询应用层中的引脚。
从以下网址下载“SimpleGPIO.h”和“SimpleGPIO.cpp”:
https://github.com/derekmolloy/beaglebone
SimpleGPIO.h / cpp是自解释的,你可以使用简单的函数调用对GPIO进行所有操作。 这个适用于任何am335x处理器。然后要进行调查,您可以在代码中使用类似这样的东西
int main()
{
//Your code
while(1)
{
if(gpio_get_value())
{
//Do what ever you want to do.
}
}
}
注:: 如果你想使用irq从内核级别向你的应用程序进程发送任何信号,那么方法会有所不同,但只有轮询这段代码才能正常工作。
希望这有帮助。
编辑:
请参阅以下网址了解详情,它解释了您的问题。您需要使用(信号编号32到64)之间的任何信号来检测GPIO
状态的变化。您需要在内核模块中注册processId
。
http://yongbingchen.github.io/blog/2013/03/11/sending-a-signal-from-linux-kernel/
当GPIO
状态发生变化时,内核会向应用层发送信号,应用层中的专用功能可以在该应用层上执行。