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

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

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

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

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

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

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

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

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

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

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

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

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

Рекомендации по пространству стека

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

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

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

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

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

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

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

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

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

В нескольких операционных системах‍ — ‌Linux, Unix, macOS, Майкрософт Виндоус, z / OS, DESQview и некоторые другие операционные системы, использовавшиеся в прошлом‍ —‌ обработчики прерываний делятся на две части: Обработчик прерывания первого уровня (FLIH) и Обработчики прерываний второго уровня (SLIH). FLIH также известны как обработчики аппаратных прерываний или же быстрые обработчики прерываний, а SLIH также известны как обработчики медленных / мягких прерываний, или же Отложенные вызовы процедур в Windows.

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

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

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

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

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

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

Рекомендации

  1. ^ а б c «Руководство по программированию модуля ядра Linux, глава 12. Обработчики прерываний». Проект документации Linux. 18 мая 2007 г.. Получено 20 февраля, 2015.
  2. ^ а б c d Джонатан Корбет; Алессандро Рубини; Грег Кроа-Хартман (27 января 2005 г.). «Драйверы устройств Linux, Глава 10. Обработка прерываний» (PDF). O'Reilly Media. Получено 20 февраля, 2015.