Обработчик прерывания - Interrupt handler

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

Традиционная форма обработчика прерывания - аппаратный обработчик прерывания. Аппаратные прерывания возникают из-за электрических состояний или низкоуровневых протоколов, реализованных в цифровой логике , обычно отправляются через жестко закодированную таблицу векторов прерываний асинхронно с потоком нормального выполнения (насколько позволяют уровни маскирования прерываний), часто с использованием отдельного стека, и автоматический переход в другой контекст выполнения (уровень привилегий) на время выполнения обработчика прерывания. Как правило, аппаратные прерывания и их обработчики используются для обработки условий с высоким приоритетом, которые требуют прерывания текущего кода, выполняемого процессором .

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

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

Обработчик прерывания - это низкоуровневый аналог обработчиков событий . Однако обработчики прерываний имеют необычный контекст выполнения, множество жестких ограничений во времени и пространстве, а их внутренняя асинхронность делает их заведомо трудными для отладки стандартной практикой (воспроизводимые тестовые примеры обычно не существуют), что требует специального набора навыков - важное подмножество системного программирования - инженеров- программистов, работающих на уровне аппаратных прерываний.

Флаги прерывания

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

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

Выход из обработчика прерывания с системой прерывания в точно правильном состоянии при любых обстоятельствах может иногда быть трудной и требовательной задачей, а его неправильное обращение является источником многих серьезных ошибок, которые полностью останавливают систему. Эти ошибки иногда носят временный характер, при этом случай неправильного обращения с периферией не возникает в течение недель или месяцев непрерывной работы. Формальная проверка обработчиков прерываний чрезвычайно сложна, в то время как тестирование обычно выявляет только наиболее частые режимы отказов, поэтому незаметные периодические ошибки в обработчиках прерываний часто отправляются конечным клиентам.

Контекст выполнения

В современной операционной системе при входе контекст выполнения обработчика аппаратных прерываний неуловим.

Из соображений производительности обработчик обычно запускается в памяти и контексте выполнения запущенного процесса, к которому у него нет специального соединения (прерывание по сути узурпирует текущий контекст - учет времени процесса часто увеличивает время, затраченное на обработку прерываний, до прерванный процесс). Однако, в отличие от прерванного процесса, прерывание обычно повышается с помощью жестко запрограммированного механизма ЦП до уровня привилегий, достаточно высокого для прямого доступа к аппаратным ресурсам.

Соображения относительно места в стеке

В микроконтроллере низкого уровня микросхема может не иметь режимов защиты и не иметь блока управления памятью (MMU). В этих микросхемах контекст выполнения обработчика прерывания будет по существу таким же, как у прерванной программы, которая обычно выполняется в небольшом стеке фиксированного размера (ресурсы памяти традиционно были крайне скудными на нижнем уровне). Часто предоставляются вложенные прерывания, что усугубляет использование стека. Основным ограничением для обработчика прерывания в этом программном начинании является недопущение превышения доступного стека в наихудшем случае, требуя от программиста глобальных размышлений о требованиях к пространству стека для каждого реализованного обработчика прерываний и прикладной задачи.

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

В случае с возможностью записи можно реализовать сигнальную защиту стека - фиксированное значение сразу за концом допустимого стека, значение которого может быть перезаписано, но никогда не будет, если система работает правильно. Часто можно регулярно наблюдать повреждение ограждения стека при использовании какого-либо механизма сторожевого пса. Это позволит выявить большинство условий переполнения стека в момент времени, близкий к операции, вызывающей нарушение.

В многозадачной системе каждый поток выполнения обычно имеет свой собственный стек. Если для прерываний не предусмотрен специальный системный стек, прерывания будут занимать пространство стека из любого потока выполнения, который был прерван. Эти проекты обычно содержат MMU, а пользовательские стеки обычно конфигурируются таким образом, что переполнение стека перехватывается MMU либо как системная ошибка (для отладки), либо для переназначения памяти для увеличения доступного пространства. Ресурсы памяти на этом уровне микроконтроллера обычно гораздо менее ограничены, поэтому стеки могут быть выделены с большим запасом прочности.

В системах, поддерживающих большое количество потоков, лучше, если механизм аппаратных прерываний переключает стек на специальный системный стек, чтобы ни один из стеков потоков не учитывал использование вложенных прерываний в наихудшем случае. Крошечные процессоры еще в 8-битной Motorola 6809 1978 года обеспечивали отдельные указатели стека системы и пользователя.

Ограничения по времени и параллелизму

По многим причинам очень желательно, чтобы обработчик прерывания выполнялся как можно короче, и крайне не рекомендуется (или запрещается) для аппаратного прерывания вызывать потенциально блокирующие системные вызовы. В системе с несколькими исполнительными ядрами вопросы повторного входа также имеют первостепенное значение. Если система обеспечивает аппаратный DMA , проблемы с параллелизмом могут возникнуть даже с одним ядром ЦП. (Микроконтроллер среднего уровня нередко не имеет уровней защиты и MMU, но все же предоставляет механизм DMA с множеством каналов; в этом сценарии многие прерывания обычно запускаются самим механизмом DMA, а связанный с ним обработчик прерываний ожидается, что нужно действовать осторожно.)

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

Разделенные обработчики в современных операционных системах

В некоторых операционных системах, Linux , Unix , MacOS , Microsoft Windows , г / OS , DESQview и некоторые другие операционные системы , используемые в прошлом-обработчики прерываний разделены на две части: первый уровень Обработчик прерываний ( FLIH ) и Второй -Уровневые обработчики прерываний ( SLIH ). FLIH также известны как обработчики аппаратных прерываний или обработчики быстрых прерываний , а SLIH также известны как обработчики медленных / мягких прерываний или отложенные вызовы процедур в Windows.

FLIH реализует как минимум зависящую от платформы обработку прерываний, аналогичную процедурам обработки прерываний . В ответ на прерывание происходит переключение контекста , и код прерывания загружается и выполняется. Задача FLIH - быстро обслуживать прерывание или записывать критическую информацию, зависящую от платформы, которая доступна только во время прерывания, и планировать выполнение SLIH для дальнейшей долговременной обработки прерываний.

FLIH вызывают дрожание при выполнении процесса. FLIH также маскируют прерывания. Уменьшение джиттера является наиболее важным для операционных систем реального времени , поскольку они должны обеспечивать гарантию того, что выполнение определенного кода будет завершено в течение согласованного периода времени. Чтобы уменьшить джиттер и снизить вероятность потери данных из-за маскированных прерываний, программисты пытаются минимизировать время выполнения FLIH, переходя в максимально возможной степени на SLIH. Со скоростью современных компьютеров FLIH могут реализовать все операции, зависящие от устройств и платформ, а также использовать SLIH для дальнейшей долговременной обработки, не зависящей от платформы.

FLIH, которые обслуживают оборудование, обычно маскируют связанное с ними прерывание (или, в зависимости от обстоятельств, маскируют его), пока не завершат свое выполнение. (Необычный) FLIH, который демаскирует связанное с ним прерывание до его завершения, называется обработчиком повторно входимого прерывания . Обработчики повторных прерываний могут вызвать переполнение стека из-за нескольких прерываний одним и тем же вектором прерывания , поэтому их обычно избегают. В системе приоритетных прерываний FLIH также (на короткое время) маскирует другие прерывания с таким же или меньшим приоритетом.

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

В Linux FLIH называются верхней половиной , а SLIH - нижней половиной или нижней половиной . Это отличается от именования, используемого в других Unix-подобных системах, где оба являются частью нижней половины .

Смотрите также

использованная литература