C GPIO轮询立即退出
我需要在等待GPIO引脚级别更改(上升或下降边缘)时释放处理器,因此我创建了一个简单的代码来轮询GPIO sysfs值文件,但我遇到了一些问题:C GPIO轮询立即退出,c,linux,C,Linux,我需要在等待GPIO引脚级别更改(上升或下降边缘)时释放处理器,因此我创建了一个简单的代码来轮询GPIO sysfs值文件,但我遇到了一些问题: 在第一个poll()调用中,它立即退出IME,并在revents中设置POLLPRI和POLLERR 在此之后,我lseek()和read()fd,并循环回到poll() 现在poll()挂起 这是我的代码: #include <stdio.h> #include <stdlib.h> #include <poll.h
- 在第一个
调用中,它立即退出IME,并在poll()
中设置revents
和POLLPRI
POLLERR
- 在此之后,我
和lseek()
fd,并循环回到read()
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);
}
}
}
#包括
#包括
#包括
#包括
#定义GPIO_DIR“/sys/class/GPIO/”
#定义GPIO_导出GPIO_目录“导出”
int main(int argc,字符**argv)
{
国际邮政总局;
结构pollfd gpiou fdset[1];
char pin_value[]=GPIO_DIR“gpioXYZ/value”;
sprintf(pin_值,GPIO_DIR“GPIO%s/值”,argv[1]);
gpio_fd=打开(仅限引脚值);
而(1)
{
字符缓冲区[64];
gpio_fdset[0]。fd=gpio_fd;
gpio_fdset[0]。事件=POLLPRI;
gpio_fdset[0]。revents=0;
轮询(gpio_fdset,1,-1);
if(gpio_fdset[0]。revents&POLLPRI)
{
printf(“归还的归还物”!\n);
lseek(gpio_fdset[0].fd,0,SEEK_SET);
读取(gpio_fdset[0].fd,缓冲区,64);
}
}
}
在调用它之前,我导出希望监视的pin(内核编号方案中的GPIO1_30或62)。我试着将这个引脚设置为输入、输出,在上升沿和下降沿上产生中断,但行为总是一样的。我错过了什么
据我所知,当我使用sysfs时,我不需要使用gpio_request()、gpio_to_irq()和其他相关函数来轮询这个pin。是这样吗
问候,
Guilherme如果我正确理解您的要求,那么您希望在引脚变高时采取一些措施 您可以在应用层自行轮询pin 从以下URL下载“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从内核级别向应用程序进程发送任何信号,那么方法将略有不同,但仅用于轮询此代码即可
希望这有帮助
编辑:
请参考下面的url了解更多详细信息,它解释了您的问题。您需要使用介于(信号编号32到64)之间的任何信号来检测GPIO
状态的变化。您需要向内核模块注册processId
http://yongbingchen.github.io/blog/2013/03/11/sending-a-signal-from-linux-kernel/
当
GPIO
状态发生变化时,内核会向应用层发送一个信号,应用层中的专用函数可以在该信号上执行。我发现了如何克服这个问题。在设置打开文件描述符后,只需执行一次伪读取()。显然,这是因为最近打开的fd被视为已更改(至少对于GPIO)。至于revents上的POLLERR,这是。您正在使用哪个处理器?我想它是一个ARM处理器。是的。它是AM335x,我的内核版本是3.2。您是否正确配置了pin mux?你能在值文件中看到正确的输入吗?实际上,我需要睡眠,直到检测到GPIO的值发生变化。因此使用poll。我希望它与套接字的方式相同,但它似乎对sysfs文件有不同的行为。我已经更新了描述,以便更清楚地解释我的问题:)@guilhermescosta-Answer-edited,请看一看。一点点就能解决你的问题。