处理字符设备中的中断

时间:2017-01-20 06:34:13

标签: linux-kernel interrupt-handling ioctl

我正在尝试在内核中为用户界面正确注册中断。

令人惊讶的是,我没有在内核中找到很多例子。

irq handler

static irqreturn_t irq_handler(int irq, void *dev_id)
{
   struct el_irq_dev *el_irq = &el_irq_devices[0];
    printk("irq in\n");

    spin_lock(&el->my_lock,flags);

    clear_interrupt() 

    some_buffer[buf_wr] = ch;
    el_irq->buf_wr++;
    if (el_irqbuf_wr >= 16)
        el_irqbuf_wr = 0;


     spin_unlock(&el->my_lock,flags);
     wake_up_interruptible(&el->pollw);



return IRQ_HANDLED;

}

用于等待中断的ioctl

static long el_device_ioctl( struct file *filp, 
         unsigned int ioctl_num, 
         unsigned long ioctl_param)
{
    struct el_irq_dev *el_irq = &el_irq_devices[0];
switch (ioctl_num) {
case IOCTL_WAIT_IRQ:      <<<---- using ioctl (no poll) to wait on interrupt
    wait_event_interruptible(el_irq->pollw, &el_irq->buf_wr != &el_irq->buf_rd) ;
    spin_lock(&el_irq->my_lock);
    if (el_irq->buf_wr != &el_irq->buf_rd)
    {
        my_value=some_buffer[el_irq->buf_rd];
        el_irq->buf_rd++;
        if (el_irq->buf_rd >= 16)
            el_irq->buf_rd = 0;
    }

    spin_unlock(&el_irq->my_lock);
    copy_to_user(ioctl_param,&my_value,sizeof(my_value));

default:
        break;
    }
    return 0;
}

我的问题是:

  1. 我们是否应该在中断中清除fpga中的中断(clear_interrupt()) 在wake_up之前或之后?我们可以将清除中断放在用户空间处理程序(IOCTL_WAIT_IRQ)中,而不是清除中断 中断处理程序?
  2. 正如您在代码中看到的,我使用循环缓冲区来处理用户空间处理程序缺少中断的情况。这是真的需要还是我们可以假设没有错过? 换句话说,是否可以假设永远不会错过中断?以便ioctl调用永远不会看到超过1个等待中断?如果是 - 也许我不需要中断处理程序和ioctl处理程序之间的缓冲机制。
  3. 谢谢你, 然

1 个答案:

答案 0 :(得分:1)

简短回答。

  1. 我清除用户空间处理程序中的中断似乎是合理的。在完成所有工作之后尽可能晚地完成它是有道理的,只要在清除之后再次检查确实没有剩下的工作要做(在清理之前可能还有更多的工作已经到达)。
  2. 用户空间处理程序可能确实错过了中断,例如如果几个到达IOCTL_WAIT_IRQ的调用之间。中断也可能会被错过&#34;在某种意义上,如果在中断被清除之前有几件工作到了。应该设计堆栈(硬件和软件),以便这不是问题。中断应该只表示有工作要做,并且用户空间处理程序应该能够在返回之前完成所有未完成的工作。
  3. 您可能应该在IOCtl代码[1]中使用spin_lock_irqsave()。
  4. [1] http://www.makelinux.net/ldd3/chp-5-sect-5