Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
Шрифт:
При использовании функции InterruptAttach мы определяем другой набор параметров. Параметр handler — это адрес функции, которую надо вызвать. Как видно из прототипа, функция handler возвращает структуру
Допустим, что вы уже вызвали функцию InterruptAttachEvent или InterruptAttach.
Ниже приведен фрагмент программы, в котором реализовано подключение ISR к вектору аппаратного прерывания, идентифицируемого константой HW_SERIAL_IRQ:
Теперь, если по данному вектору произойдет прерывание, наш обработчик будет подвергнут диспетчеризации. При вызове функции InterruptAttach ядро демаскирует указанный источник прерываний на уровне контроллера (если это прерывание еще не демаскировано, что имело бы место в случае многочисленных обработчиков одного и то же прерывания).
Отключение обработчика прерывания
Когда вы закончили с обработчиком прерывания, вы можете пожелать уничтожить связь между ним и вектором:
Я сказал «можете», потому что обрабатывающие прерывания потоки, как правило, используются в серверах, а серверы обычно не завершаются. Это часто ведет к предрассудку, что хорошо организованному серверу никогда не понадобится самостоятельно вызывать InterruptDetach. К тому же, при смерти потока или процесса ОС автоматически отключит все связанные с ним обработчики прерываний. Таким образом, если программа просто
дойдет до конца main, вызовет exit или завершится по SIGSEGV, все ее ISR будут автоматически отключены от соответствующих векторов прерываний. (Впрочем, вы, вероятно, пожелаете сделать это несколько изящнее, запретив соответствующему устройству генерацию прерываний. Если же прерывание разделяемое, и его используют другие устройства, то здесь двух вариантов быть не может вообще — вы просто обязаны «убрать за собой», иначе у вас либо больше не будет прерываний (в режиме чувствительности по фронту), либо пойдет постоянный поток запросов на прерывание (в режиме чувствительности по уровню).Продолжая вышеприведенный пример, если бы мы захотели отключиться от прерывания, то мы использовали бы следующий код:
Если это последний ISR, связанный с данным вектором прерывания, то ядро автоматически произведет маскирование источника прерывания на уровне контроллера, чтобы таких прерываний больше не возникало.
Параметр flags
Последний параметр, flags, управляет различными дополнительными опциями:
_NTO_INTR_FLAGS_END
Указывает, что данный обработчик должен сработать после всех других обработчиков данного прерывания (если они есть).
_NTO_INTR_FLAGS_PROCESS
Указывает на то, что данный обработчик связан с процессом, а не с потоком. Что из этого вытекает, так это условие автоматического отключения обработчика. Если вы определяете этот флаг, обработчик будет автоматически отключен от источника прерывания при завершении процесса. Если этот флаг не определен, обработчик прерывания будет отключен от источника, когда завершится поток, подключивший его.
_NTO_INTR_FLAGS_TRK_MSK
Указывает, что ядро должно отследить, сколько раз данное прерывание было маскировано. Это приводит к несколько большей загрузке ядра, но это необходимо для корректного демаскирования источника прерываний при завершении потока или процесса.
Обработчик прерывания
Давайте рассмотрим собственно обработчик прерывания. В первом примере применим InterruptAttach, а затем рассмотрим аналогичный случай, только с применением функции InterruptAttachEvent.
В продолжение примера приведем функцию intHandler — наш обработчик прерывания. Она отвечает за микросхему последовательного порта 8250 (допустим, что она генерирует прерывание HW_SERIAL_IRQ).