• Аргумент dev_id
dev_id значение NULL!• Обработчик прерывания должен иметь возможность распознать, сгенерировано ли прерывание тем устройством, которое обслуживается этим обработчиком. Для этого требуется как поддержка аппаратного обеспечения, так и наличие соответствующей логики в обработчике прерывания. Если аппаратное устройство не имеет необходимых функций, то не будет никакой возможности в обработчике прерывания определить, какое из устройств на совместно используемой линии является источником прерывания.
Все драйверы, которые рассчитаны на совместно используемую линию прерывания, должны удовлетворять указанным выше требованиям. Если хотя бы одно из устройств, которые совместно используют линию прерывания, не делает это корректно, то все остальные устройства также не смогут совместно использовать линию. Если функция request_irq()
SH_SHIRQ, то этот вызов будет успешным только в том случае, если для данной линии прерывания еще нет зарегистрированных обработчиков или все обработчики для данной линии зарегистрированы с указанием флага SH_SHIRQ. Заметим, что для ядер серии 2.6, в отличие от более ранних серий, можно "смешивать" совместно используемые обработчики с различными значениями флага SA_INTERRUPT.Когда ядро получает прерывание, то оно последовательно вызывает все обработчики, зарегистрированные для данной линии. Поэтому важно, чтобы обработчик прерывания был в состоянии определить, какое устройство является источником этого прерывания. Обработчик должен быстро завершиться, если соответствующее ему устройство не генерировало это прерывание. Такое условие требует, чтобы аппаратное устройство имело регистр состояния (status register) или другой аналогичный механизм, которым обработчик может воспользоваться для проверки. На самом деле большинство устройств действительно имеют данную функцию.
Настоящий обработчик прерывания
Давайте рассмотрим настоящий обработчик прерывания, который используется в драйвере устройства RTC (real-time clock, часы реального времени), находящегося в файле drivers/char/rtc.c
rtc_init() для инициализации драйвера. Одна из ее обязанностей — это регистрация обработчика прерывания. Делается это следующим образом.if (request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL) {
printk(KERN_ERR "rtc: cannot register IRQ %d\n" , rtc_irq);
return -EIO;
}
Из данного примера видно, что номер линии прерывания — это константа RTC_IRQ
IRQ 8. Второй параметр— это обработчик прерывания, rtc_interrupt, при выполнении которого запрещены все прерывания в связи с указанием флага SA_INTERRUPT. Из четвертого параметра можно заключить, что драйвер будет иметь имя "rtc". Так как наше устройство не может использовать линию прерывания совместно с другими устройствами и обработчик прерывания не используется для каких-либо других целей, в качестве параметра dev_id передается значение NULL.И наконец, собственно сам обработчик прерывания.
/*
* Очень маленький обработчик прерывания. Он выполняется с
* установленным флагом SA_INTERRUPT, однако существует
* возможность конфликта с выполнением функции set_rtc_mmss()