在嵌入式Linux设备上使用GPIO触发电平中断

时间:2012-09-27 22:49:46

标签: embedded-linux interrupt gpio

我正在移植和使用级别触发的中断到嵌入式Linux设备的现有系统。我遇到了一些麻烦,希望有人可以提供帮助。我的计划是使用poll()函数(在用户空间,没有低级驱动程序的计划)来检测gpio行何时为高。这是做某事的迹象。

不幸的是我还没弄明白如何启用这个条件。现在我正在做以下事情:

  • 将gpio编号写入/ sys / class / gpio / export
  • 将方向设为“in”
  • 将边缘设为?

我可以设置GPIO,只要gpio线为高电平时轮询将返回,即使多次调用poll()而没有清除条件,但是如果线路很低,它会等待吗?我应该使用其他东西而不是尝试使用poll()吗?谢谢!

更新

我以为我有一个解决方案,但显然没有。我将GPIO线上的边沿设置为“上升”。在硬件方面,该线与数据缓冲区的“FIFO已使用”计数相关联。如果FIFO中有数据,则该行为高。否则它很低。然后我设置了以下系统:

GetByte() {
    Is there data in the FIFO? {
        Read a byte.
        Return
    }
    Call poll() to wait for the data {
        Is there data in the FIFO? {
            Read a byte.
            Return
        }
    }
}

第一个“If”语句是因为我一次只读取一个字节,如果条件没有改变,poll()将不会在超时之前返回(如果多个则不会在我的系统中字节在FIFO中)。我现在看到的问题是poll()有时会返回,但FIFO中没有任何数据。事实上,poll()返回'1',但FIFO报告它是空的。

我希望poll()仅在gpioXX / value文件从0变为1时检测到由于GPIO线的“上升”边沿设置而发生的变化。那是对的吗?这是使用poll()的合理方式,还是我应该考虑不同的设计。

2 个答案:

答案 0 :(得分:1)

我终于找到了答案。我需要在清空FIFO之前读取GPIO的值文件,以确保下次调用poll()时状态处于良好状态。这是对伪代码的更改:

GetByte() {
    Is there data in the FIFO? {
        Read the GPIO value file
        Read a byte.
        Return
    }
    Call poll() to wait for the data {
        Is there data in the FIFO? {
            Read a byte.
            Return
        }
    }
}

如果一个字节可用,我总是尝试读取一个字节。如果它是FIFO中的最后一个字节,我首先读取GPIO值文件。我知道当我这样做时,级别触发的中断线很高,所以我可以安全地清除poll()可能看到的任何挂起的文件事件。现在我读了字节。

现在当我调用poll()时,我知道它不会返回,除非它看到中断的上升沿。简单的修复,但直到我在kernel / fs / sysfs / file.c中读取注释,直到我完全理解我需要做什么为止。

答案 1 :(得分:0)

我有这种感觉,如果不编写驱动程序,您将需要自己访问硬件寄存器。这涉及1.了解硬件,以便了解您需要访问的寄存器的硬件地址,2。使用open& mmap获取指向寄存器的指针,3。取消引用指针。

这是我从我的一个项目中剪下来的一些代码:

fd = open("/dev/mem", O_RDWR|O_SYNC);
if (fd == -1)
{
perror("open /dev/mem");
exit(1);
}
unsigned char *start;
start = (unsigned char*)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED,
fd, 0x80810000);