1

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

不幸的是,我还没有弄清楚如何启用该条件。现在我正在做以下事情:

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

我可以设置 GPIO 以便当 gpio 线为高时 poll 将返回,即使 poll() 被多次调用而不清除条件,但如果线为低它会等待?我应该使用其他东西而不是尝试使用 poll() 吗?谢谢!

更新

我以为我有一个解决方案,但显然没有。我将 GPIO 线上的边缘设置为“上升”。在硬件方面,该线路与数据缓冲区的“FIFO used”计数相关联。如果 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() 在超时之前不会返回(如果有多个字节,它不会在我的系统中先进先出)。我现在看到的问题是 poll() 有时会返回,但 FIFO 中没有任何数据。实际上,poll() 返回 '1',但 FIFO 报告它是空的。

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

4

2 回答 2

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 中的评论,直到我完全理解我需要做什么。

于 2012-10-16T14:34:07.503 回答
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);
于 2012-09-27T23:54:51.897 回答