Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 设备驱动程序中的中断处理&;投票_C_Linux Device Driver_Interrupt Handling - Fatal编程技术网

C 设备驱动程序中的中断处理&;投票

C 设备驱动程序中的中断处理&;投票,c,linux-device-driver,interrupt-handling,C,Linux Device Driver,Interrupt Handling,我将详细介绍一些代码,这些代码大致执行以下操作: 内核驱动程序处理中断 有一条中断线,因此当中断发生时,句柄读取一个32位寄存器,该寄存器告诉此中断的原因 对于设置的每一位,它调用ack_irq()清除中断,并将中断原因写入驱动程序中的缓冲区,以便进一步读取() 接下来,它调用wake_up_interruptable(),以唤醒正在select()上睡眠的用户空间进程 相应的poll()函数不执行poll\u wait() 返回select后,用户空间将从驱动程序中读取() 虽然我只了解1

我将详细介绍一些代码,这些代码大致执行以下操作:

  • 内核驱动程序处理中断
  • 有一条中断线,因此当中断发生时,句柄读取一个32位寄存器,该寄存器告诉此中断的原因
  • 对于设置的每一位,它调用ack_irq()清除中断,并将中断原因写入驱动程序中的缓冲区,以便进一步读取()
  • 接下来,它调用wake_up_interruptable(),以唤醒正在select()上睡眠的用户空间进程
  • 相应的poll()函数不执行poll\u wait()
  • 返回select后,用户空间将从驱动程序中读取()
虽然我只了解1位的基本操作,但在以下情况下会发生什么:

  • 中断发生,设置1位
  • 处理程序调用wake\u up\u interruptable()。poll()返回
  • 用户空间唤醒,开始读取()
  • 现在,另一个中断发生了->内核处理该中断并调用wake\u up\u interruptable(),但是现在没有人在等待这个事件

这是否意味着将错过第二个中断?如果是这样的话,克服这一问题的方法是什么

中断处理程序的任务是尽可能快地处理中断

为了与系统的其余部分通信,ISR使用一个(循环)缓冲区,将您的
原因放置在该缓冲区中。它在中断禁用状态下执行此操作

中断服务完成后,系统将继续。如果用户进程现在想要检查循环缓冲区中的新事件,则需要对缓冲区进行独占访问。因此,它必须禁用中断(优先级高于ISR)。它禁用中断,获取缓冲区的下一个元素,更新缓冲区指针或索引,并重新启用中断

如果出现了新的中断,则在用户进程重新启用中断之前,不会对其进行处理(IRQ线保持高位,芯片寄存器未被读取)。不用说,这种缓冲区访问也必须尽可能快(尽可能少的指令)。重新启用中断后,将为新的挂起中断提供服务

从缓冲区中获取下一项后,它将其交给功能用户进程。如果缓冲区中没有项目,它将休眠。当项目到达时,它将被唤醒、禁用中断、获取项目、重新启用中断并返回到用户进程


这样,就不会错过任何中断。

假设它是一个循环缓冲区,并且用户进程一直读取,直到没有更多的数据可读取为止(并且假设缓冲区被正确锁定),用户进程只会从缓冲区中读取下一个原因。谢谢,它是一个循环缓冲区,但是让我们假设用户进程完成了读取()在第一个中断发生时,就在select()再次进入睡眠状态之前,新的中断出现了。新的中断将调用wake_up_interruptable(),但用户进程尚未等待此事件。“在再次进入睡眠之前”新的“原因”已放置在缓冲区中,因此select()将返回下一个值。调用wake\u up\u interruptable()什么也不做(没有什么东西需要唤醒,因为没有东西在睡觉)。记住,是操作系统做了一切。它在中断时从用户进程获取CPU,因此用户进程什么也不做,并在每次内务处理完成后将CPU返回给用户进程。这就是为什么用户进程不会进入睡眠状态。不过,select()仍在驱动程序中执行poll()。我知道新的'cause'被放在新的缓冲区中,但是为什么“select()将返回下一个值”?poll()函数正在执行poll\u wait()。如果我理解正确,poll_wait()将一直休眠,直到有人通过调用wake_up_interruptable()将其唤醒。在上述情况下,对wake_up_Interruptable()的调用发生在对poll_wait()的调用之前。确定,select将不会返回下一个值(很抱歉),您的轮询例程将检查缓冲区。然后,轮询功能在中断禁用状态下工作变得非常重要。