Я пытаюсь правильно зарегистрировать прерывание в ядре для пользовательского интерфейса.
Удивительно, но я не нашел много примеров в ядре для этого.
обработчик прерываний
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;
}
Мой вопрос:
- Должны ли мы поставить очистку от прерываний (clear_interrupt()) в fpga в прерывании до или после wake_up? Можем ли мы поместить прерывание очистки в обработчик пользовательского пространства (IOCTL_WAIT_IRQ) вместо очистки прерывания в обработчике прерываний?
- Как видно из кода, я использую циклический буфер для обработки случаев, когда в обработчике пользовательского пространства отсутствуют прерывания. Это действительно необходимо или можно считать, что промахов нет? Другими словами, разумно ли предположить, что прерывания никогда не должны быть пропущены? так что вызов ioctl никогда не должен видеть более 1 ожидающего прерывания? Если да - возможно, мне не нужен буферный механизм между обработчиком прерывания и обработчиком ioctl.
Спасибо, Ран