Читать «Разработка ядра Linux» онлайн - страница 83

Роберт Лав

Для регистрации линии прерывания и инсталляции обработчика в коде драйвера можно использовать следующий вызов.

if (request_irq(irqn, my_interrupt, SA_SHIRQ, "my_device", dev)) {

 printk(KERN_ERR "my_device: cannot register IRQ %d\n", irqn);

 return -EIO;

}

В этом примере параметр irqn — это запрошенный номер линии запроса на прерывание, параметр my_interrupt — это обработчик этой линии прерывания, линия запроса на прерывание может быть совместно используемой, имя устройства — "my_device", dev — значение параметра dev_id. В случае ошибки код печатает сообщение, что произошла ошибка, и возвращается из выполняющейся функции. Если функция регистрации возвращает нулевое значение, то обработчик прерывания инсталлирован успешно. С этого момента обработчик прерывания будет вызываться в ответ на приходящие прерывания. Важно произвести инициализацию оборудования и регистрацию обработчика прерывания в правильной последовательности, чтобы предотвратить возможность вызова обработчика до того момента, пока оборудование не инициализировано.

Освобождение обработчика прерывания

Для освобождения линии прерывания необходимо вызвать функцию

void free_irq(unsigned int irq, void *dev_id);

Если указанная линия не является совместно используемой, то эта функция удаляет обработчик и запрещает линию прерывания. Если линия запроса на прерывание является совместно используемой, то удаляется обработчик, соответствующий параметру dev_id. Линия запроса на прерывание также запрещается, когда удаляется последний обработчик. Теперь понятно, почему важно передавать уникальное значение параметра dev_id. При использовании совместно используемых прерываний требуется уникальный идентификатор для того, чтобы отличать друг от друга различные обработчики, связанные с одним номером прерывания, и позволить функции free_irq() удалять правильный обработчик. В любом случае, если параметр dev_id не равен значению NULL, то он должен соответствовать тому обработчику, который удаляется.

Вызов функции free_irq() должен производиться из контекста процесса.

Таблица 6.1. Список функций управления регистрацией прерываний

Функция Описание
request_irq() Зарегистрировать заданный обработчик прерывания для заданной линии прерывания
free_irq() Освободить указанный обработчик прерывания. Если с линией прерывания больше не связан ни один обработчик, то запретить указанную линию прерывания

Написание обработчика прерывания

Следующее описание является типичным для обработчика прерывания.