2017-01-20 17 views
0

Я пытаюсь правильно зарегистрировать прерывание в ядре для пользовательского интерфейса.Обработка прерывания в символьном устройстве

Удивительно, но я не нашел много примеров в ядре для этого.

обработчик прерываний

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. Должны ли мы поставить ясно прерываний (clear_interrupt ()) в fpga в прерывании до или после wake_up? Можем ли мы провести событие прерывания в обработчике пользовательского пространства (IOCTL_WAIT_IRQ) ​​вместо того, чтобы очистить прерывание в обработчике прерываний ?
  2. Как вы можете видеть в коде, я использую циклический буфер, чтобы обрабатывать случаи, когда обработчик пользовательского пространства пропускает прерывания. Это действительно необходимо или мы можем предположить, что нет промахов? Иными словами, разве reasnoble предположить, что никогда не должны быть пропущены прерывания? так что вызов ioctl никогда не должен видеть более одного прерывания ожидания? Если да - возможно, мне не нужен буферный механизм между обработчиком прерываний и обработчиком ioctl.

Спасибо, Ран

+0

Зачем вам все, что в первую очередь? – 0andriy

+0

У нас есть пространство памяти fpga, и вместо этого вместо этого выполняем большинство драйверов в пользовательском пространстве и просто передаем прерывание в пространство пользователей из ядра – ransh

+0

Какая память? Общее назначение? Почему бы не использовать DMA в драйвере ядра для него? – 0andriy

ответ

1

Короткий ответ.

  1. Мне кажется разумным очищать прерывания в обработчике пользовательского пространства. Это имеет смысл сделать это как можно дольше, после того, как все будет сделано, если вы снова проверите после того, как очистите, что на самом деле нет работы, которую можно было бы сделать (еще одна работа могла прибыть непосредственно перед очисткой).
  2. Обработчик пользовательского пространства может действительно пропускать прерывания, например. если несколько соединений поступают между IOCTL_WAIT_IRQ. Прерывания также могут быть «пропущены» в некотором смысле, хотя, если несколько работ будут достигнуты до того, как прерывания будут очищены. Стек (аппаратное и программное обеспечение) должен быть спроектирован таким образом, чтобы это не было проблемой. Прерывание должно просто сигнализировать о том, что необходимо выполнить работу, и обработчик пользовательского пространства должен иметь возможность просто выполнить всю выдающуюся работу перед возвратом.
  3. Возможно, вы используете spin_lock_irqsave() в коде IOCtl [1].

[1] http://www.makelinux.net/ldd3/chp-5-sect-5

+0

Спасибо за подробный ответ. Можно ли предположить, что никогда не должно быть пропущенных прерываний? т.е. ioctl никогда не должен видеть более одного прерывания ожидания? Если да - возможно, мне не нужен буферный механизм между обработчиком прерываний и ioctl – ransh

+0

Не совсем уверен, что вы подразумеваете под «пропущенными прерываниями» здесь. Самое простое - сделать обработчик IOCtl (не волнуйтесь о моих капиталах, есть несколько вариантов), как только произойдет хотя бы одно прерывание с момента последнего clear_interrupts().Но обработчик пользовательского пространства должен предположить, что с момента последнего возвращения IOCtl может быть несколько прерываний, и должен быть способ для обработчика пользовательского пространства найти всю работу, которую эти прерывания сообщают. – michaeljt

+0

, поэтому я предполагаю, что буферный механизм, который я использовал в этом примере (some_buffer), весьма важен. – ransh

 Смежные вопросы

  • Нет связанных вопросов^_^