stringtranslate.com

Обработчик прерываний

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

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

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

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

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

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

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

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

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

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

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

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

Соображения по поводу пространства в стеке

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

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

В случае записи можно реализовать сторожевой стековый сторожевой ...

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

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

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

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

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

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

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

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

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

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

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

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

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

Ссылки

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