首页 > 解决方案 > 在中断处理程序上读取字符导致等待队列永远等待

问题描述

我正在为串行通信设备编写驱动程序,其工作方式如下:

1 - 我从用户空间调用读取函数。

2 - 系统进入忙碌等待状态,直到第一个字符到达 FIFO。

3 - 一个字符到达并且系统读取它。

4 - 现在,系统将等待(处于非忙等待状态)直到下一个字符到达,因此正在使用等待队列。

5 - 当角色到达时,硬件引发中断。然后,此中断的处理程序唤醒读取过程,该过程继续进行。

最初,我有以下代码架构:

read_function(int number) {
    busy_wait(!fifo_empty)
    for(i = 0, i < number) {
         char_read = global_buffer;
         wait_event_interruptible(queue,!fifo_empty);
    }

 irq_handler() {
    wake_up(queue);
    global_buffer = read_fifo();
    return IRQ_HANDLED;
 }

但是,这有以下问题:在我读取处理程序上的 fifo 后,条件“fifo_empty”变为 true。这意味着即使我在它为假的时刻唤醒了进程,在我退出处理程序之前,条件将返回为真,然后读取过程将不会继续。

然后我决定删除缓冲区,并将 read_fifo() 调用放在读取函数上。但是,这会导致一些问题,即:

a) 在我执行 read_fifo 之前,引发中断的标志不会下降。我看到在内核消息上多次调用中断,并且函数的行为方式在首先出现的方面是非常随机的。

b) 如果一个字符在读取函数没有被调用的情况下到达,内核会因为中断进入循环而崩溃。

c) 出于某种原因,即使输入number了字符,系统也不会退出循环。

然后我想知道是否应该将 fifo_read 调用放在处理程序或读取上。我坚信(基于本网站上的其他答案)它应该放在处理程序上。但是我怎样才能唤醒这个过程呢?显然使用一些全局变量可以解决问题,但我想知道是否有更好的方法来做到这一点。

标签: kerneldriverwaitinterruptuart

解决方案


推荐阅读