Abort сбросить выполнение программы


Содержание

Прерывание выполнения программы

10.05.2020, 15:20

Скорость выполнения программы
Как ускорить ход выполнение программы ? for a in range(1,1000+1): for b in range(1,1000+1).

Ошибка во время выполнения программы
Задача: Дано действительное положительное число a и целоe число n. Вычислите an. Решение.

Получение статуса выполнения от внешней программы
Всем привет. На работе много конвертирую видео в разные форматы с разными настройками. Для своего.

Как уменьшить время выполнения программы
Помогите сократить время работы этой программы a, b, k = map(int, input().split()) if a > b: .

PyCharm Edu 4.0 нет результата выполнения программы в консоли
Доброе время суток! Начала изучать Python. Для этого поставила себе PyCharm Edu 4.0. Но в.

10.05.2020, 17:19 2

Я не знаю, что у вас там за приложение, но самое простое, заюзать модуль cmd и прерывать выполнение через обработку KeyboardInterrupt (ctrl-c в любой ОС).

10.05.2020, 17:38 3 10.05.2020, 18:44 [ТС] 4
10.05.2020, 18:44
10.05.2020, 19:48 5
10.05.2020, 20:08 [ТС] 6
10.05.2020, 20:57 7
10.05.2020, 21:18 [ТС] 8
10.05.2020, 21:38 9

Решение

10.05.2020, 21:43 [ТС] 10
11.05.2020, 00:32 11

Добавлено через 2 часа 48 минут
. На самом деле запускать важные задачи в потоках демонах не очень хорошо, так как мы не можем их корректно завершить. ОС их просто грохает при завершении главного потока, без возможности разрулить освобождение ресурсов.
К тому же если поток-демон нормально завершил работу (закончил задачу), основной поток заблокированный ожиданием ввода через input об этом никак не узнает и будет продолжать висеть.

Поэтому есть смысл сделать все немного тоньше, через ивенты:

11.05.2020, 00:32
11.05.2020, 00:32

Как записать результат выполнения программы в txt-файл?
Добрый день, Господа, подскажите пожалуйста как записать результат программы в файл .txt def.

Вычислить время выполнения между двумя точками программы
Перепробовал все что логически можно с библиотекой time: 1) в этом случае t получается 0, фз.

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

Раздел 2. Системный сброс, прерывания и рабочие режимы

Этот раздел описывает системный сброс, прерывания и рабочие режимы семейства MSP430x1xx.

Системный сброс и инициализация

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

Рис.2-1 Схема сброса (POR) и очистки (PUC) при включении

Сигнал POR сбрасывает устройство. Он может быть сгенерирован в следующих двух случаях:

  • включение устройства;
  • появление сигнала низкого уровня на выводе RST/NMI, когда он сконфигурирован как вход сигнала «сброса».

Сигнал PUC генерируется всегда при появлении сигнала POR, cигнал POR не генерируется cигналом PUC. Следующие события приводят к появлению сигнала PUC:

  • сигнал POR;
  • срабатывание «сторожевого» таймера (только если сторожевой таймер активирован);
  • произошло нарушение ключа безопасности «сторожевого» таймера;
  • произошло нарушение ключа безопасности Flash-памяти.

2.1.1 Сброс при включении питания (POR)

Когда напряжение Vcc повышается медленно, детектор POR удерживает сигнал POR в активном состоянии до тех пор, пока Vcc не превысит уровень V(POR), как показано на рис.2.2. Когда питающее напряжение Vcc повышается быстрее задержки POR, сигнал POR удерживается в активном состоянии в течение времени t(POR_DELAY) для корректной инициализации MSP430.

Если питающее напряжение циклически изменяется, его уровень должен упасть ниже значения V(min), чтобы гарантировано появился новый сигнал POR, когда напряжение восстановится снова. Если напряжение Vcc не падает ниже уровня V(min) в течение цикла или появляется кратковременная импульсная помеха, сигнал POR не генерируется и состояние после включения может быть некорректным. Точные параметры можно узнать из руководства по конкретному устройству.

Рис.2-2 Временные диаграммы сигнала POR

2.1.2 Сброс при пониженном напряжении питания (BOR)

Некоторые устройства имеют схему сброса при пониженном напряжении питания (см. соответствующие справочные данные), вместо схемы детектирования и задержки POR. Схема сброса при пониженном напряжении питания детектирует понижение питающего напряжения, например, напряжение, подаваемое или снимаемое с вывода Vcc. Схема сброса при пониженном напряжении сбрасывает устройство, вызывая появление POR-сигнала, когда напряжение прикладывается или снимается. Рабочие уровни показаны на рис.2.3.

Сигнал POR становится активным, когда напряжение Vcc достигает уровня Vcc(start). И остается активным до тех пор, пока Vcc не пересечет порог V(B_IT+) и не закончится выдержка t(BOR). Адаптивная задержка t(BOR) бывает больше при медленном изменении Vcc. Гистерезис VHys(B_IT-) введен, чтобы гарантировать, что питающее напряжение должно снизится ниже уровня V(B_IT-), прежде чем схемой сброса будет сгенерирован другой сигнал POR.

Рис.2-3 Временные диаграммы схемы сброса при пониженном напряжении питания

Поскольку уровень V(B_IT-) значительно выше уровня V(min) схемы POR, система BOR обеспечивает сброс при сбоях в источнике питания, когда напряжение Vcc не падает ниже уровня V(min). Точные параметры можно узнать из руководства по конкретному устройству.

2.1.3 Исходное состояние устройства после системного сброса

После снятия сигнала POR, MSP430 переходит в следующее состояние:

  • Вывод RST/NMI конфигурируется как вход «сброса»
  • Выводы ввода/вывода переключаются в режим ввода в соответствии с описанием в разделе «Цифровые входы/выходы»
  • Другие периферийные модули и регистры инициализируются так, как описано в соответствующих разделах этого руководства
  • Регистр статуса (SR) сбрасывается
  • Сторожевой таймер активизируется в сторожевом режиме
  • В программный счетчик загружается адрес, содержащийся в вектора сброса (0FFFEh). ЦПУ начинает выполнять команды с этого адреса.


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

  • Инициализировать указатель стека SP (как правило, указывается вершина ОЗУ)
  • Инициализировать сторожевой таймер в зависимости от требований приложения
  • Сконфигурировать периферийные модули в зависимости от требований приложения

Дополнительно можно оценить состояние флагов сторожевого таймера, флэш-памяти и неисправности осциллятора для определения источника сброса.

Приоритеты прерываний показаны на рис. 2.4. Приоритеты определяются порядком расположения модулей в соединяющей их цепи. Чем ближе модуль к ЦПУ/NMIRS, тем выше его приоритет.

Прерывания делятся на три типа:

  • Системное (системный сброс)
  • Немаскируемое (NMI)
  • Маскируемое

Рис.2-4 Приоритеты прерываний

2.2.1 Немаскируемые прерывания

Немаскируемые прерывания NMI не маскируются общим битом разрешения прерываний (GIE), но могут управляться индивидуальными битами включения прерывания (ACCVIE, NMIIE, OFIE). Когда происходит немаскируемое прерывание NMI, все биты разрешения NMI-прерываний автоматически сбрасываются. Выполнение программы продолжается с адреса, содержащегося в векторе немаскируемого прерывания (0FFFCh). Программное обеспечение пользователя должно установить необходимые биты NMI-прерывания, чтобы оно было разрешено вновь. Блок-схема источников NMI-прерываний показана на рис.2.5.

Немаскируемое прерывание NMI может быть вызвано тремя событиями:

  • Появление фронта сигнала на выводе RST/NMI
  • Появление неисправности осциллятора
  • Нарушение доступа к флэш-памяти

При включении микроконтроллера вывод RST/NMI конфигурируется как вывод сброса. Его функциональное назначение определяется в регистре управления сторожевым таймером WDTCTL. Если вывод RST/NMI запрограммирован на функцию сброса, ЦПУ будет находиться в состоянии сброса до тех пор, пока на этом выводе присутствует сигнал низкого уровня. После смены уровня на этом входе на лог.«1», ЦПУ начинает выполнять программу с команды, адрес которой хранится в векторе сброса (0FFFEh).

Если вывод RST/NMI сконфигурирован программой пользователя как вход вызова немаскируемого прерывания, фронт сигнала, выбранного битом NMIES вызовет NMI-прерывание, если установлен бит NMIIE. Также будет установлен флаг NMIFG.

Примечание: Удержание вывода RST/NMI в состоянии лог.«0».
Когда вывод RST/NMI сконфигурирован в NMI-режиме, сигнал, вызывающий NMI-прерывание, не должен удерживаться на выводе RST/NMI в состоянии лог.«0». Если появится сигнал PUC от какого-либо источника, когда NMI-сигнал имеет низкий уровень, микроконтроллер будет сброшен, поскольку сигнал PUC изменит назначение вывода RST/NMI и он станет входом сигнала сброса.
Примечание: Модификация NMIES.
Когда выбран режим NMI и изменен бит NMIES, появление NMI-прерывания определяется уровнем сигнала на выводе RST/NMI. Если бит выбора фронта NMI-сигнала изменен до выбора режима NMI, немаскируемое прерывание NMI не генерируется.

Рис.2-5 Блок-схема источников немаскируемого прерывания

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

Сигнал неисправности осциллятора может быть вызван PUC-сигналом, поскольку он переводит осциллятор LFXT1 из режима HF в режим LF. Сигнал PUC также отключает осциллятор XT2.

Нарушение доступа к Flash-памяти

Флаг ACCVIFG устанавливается, когда происходит нарушение доступа к Flash-памяти. Генерация NMI-прерывания при нарушении доступа к Flash-памяти происходит при установленном бите ACCVIE. Проверкой флага ACCVIFG в процедуре обработки NMI-прерывания можно определить, было ли вызвано прерывание нарушением доступа к Flash-памяти.

Пример программы обработки немаскируемого прерывания NMI

NMI-прерывание имеет много возможных источников. NMI-прерывание автоматически сбрасывает биты разрешения прерываний NMIIE, OFIE и ACCVIE. Пользовательская процедура обработки NMI-прерывания сбрасывает флаги прерывания и включает биты разрешения прерываний в соответствии с требованиями приложения так, как показано на рис.2.6.

Рис.2-6 Алгоритм процедуры обработки NMI-прерывания

Примечание: Разрешение NMI-прерывания с помощью ACCVIE, NMIIE и OFIE
Установка битов разрешения NMI-прерывания ACCVIE, NMIIE и OFIE не должна производится в теле процедуры обработки NMI-прерывания, за исключением случая, когда это происходит непосредственно перед командой RETI. В противном случае могут появиться вложенные NMI-прерывания, что приведет к переполнению стека и дальнейшей непредсказуемой работе.

2.2.2 Маскируемые прерывания

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

Каждое конкретное периферийное прерывание будет рассмотрено в этом руководстве в разделе описания соответствующего периферийного устройства.

2.2.3 Обработка прерывания

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

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

  1. Любая текущая команда выполняется до конца;
  2. Содержимое программного счетчика PC, указывающего на следующую команду, помещается в стек;
  3. Содержимое регистра статуса SR помещается в стек;
  4. Если поступило несколько прерываний во время выполнения последней команды, обрабатывается прерывание с наивысшим приоритетом, остальные ожидают обслуживания;
  5. Автоматически сбрасывается флаг одного источника прерывания. Флаги запроса остальных прерываний остаются установленными в ожидании обслуживания программным обеспечением.
  6. Регистр SR очищается, за исключением бита SCG0, остающегося неизменным. Процессор переходит из режима пониженного потребления в активный режим;
  7. Содержимое вектора прерывания загружается в РС и начинается выполнение процедуры обработки прерывания с загруженного адреса.

Рис.2-7 Процесс прерывания

Возврат из прерывания

Подпрограмма обработки прерывания заканчивается такой командой:

RETI (возврат из подпрограммы обработки прерывания)

Для возврата из прерывания необходимо 5 машинных циклов, чтобы выполнить действия, показанные на рис.2.8.

  1. Восстанавливается из стека содержимое регистра SR. Становятся актуальными все предыдущие установки GIE, CPUOFF и пр., в не зависимости от установок, использовавшихся в процедуре обработке прерывания.
  2. Восстанавливается из стека содержимое программного счетчика PC и начинается выполнение программы с того места, где она была прервана.

Рис.2-8 Возврат из прерывания

Допускаются вложенные прерывания, если бит GIE установлен во время выполнения процедуры обработки прерывания.

2.2.4 Векторы прерываний

Векторы прерываний и стартовые адреса расположены в адресном диапазоне с 0FFFFh по 0FFE0h, как показано в таблице 2.1. Вектор программируется пользователем с помощью указания 16-разрядного стартового адреса соответствующей процедуры обработки прерывания. Полный перечень векторов прерываний приводится в справочном руководстве каждого конкретного устройства.

Таблица 2.1. Источники прерываний, флаги и векторы

Источник прерывания Флаг прерывания Характер прерывания Адрес слова Приоритет
Включение питания, внешний сброс, сигнал сторожевого таймера, проверка пароля Flash-памяти WDTIFG
KEYV
Сброс 0FFFEh 15, наивысший
NMI-прерывание, неисправность осциллятора, нарушение доступа к Flash-памяти NMIIFG
OFIFG
ACCVIFG
Немаскируемое
Немаскируемое
Немаскируемое
0FFFCh 14
Определяется устройством 0FFFAh 13
Определяется устройством 0FFF8h 12
Определяется устройством 0FFF6h 11
Сторожевой таймер WDT Маскируемое 0FFF4h 10
Определяется устройством 0FFF2h 9
Определяется устройством 0FFF0h 8
Определяется устройством 0FFEEh 7
Определяется устройством 0FFECh 6
Определяется устройством 0FFEAh 5
Определяется устройством 0FFE8h 4
Порт ввода/вывода Р2 С P2IFG.0 по P2IFG.7 Маскируемое 0FFE6h 3
Порт ввода/вывода Р1 С P1IFG.0 по P1IFG.7 Маскируемое 0FFE4h 2
Определяется устройством 0FFE2h 1
Определяется устройством 0FFE0h 0, низший

2.2.5 Регистры специального назначения (SFRs)

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

2.3 Режимы работы

Семейство MSP430 разработано для приложений с ультранизким потреблением мощности и имеет различные режимы работы, показанные на рис.2.10.

Режимы работы учитывают три различные потребности:

  • ультранизкое потребление
  • скорость и пропускную способность
  • минимизацию потребления тока конкретной периферией


Типичное потребление тока микроконтроллерами семейства MSP430 показано на рис.2.9.

Рис.2-9 Типичное потребление тока устройствами 13х и 14х в зависимости от режима работы

Режимы низкого энергопотребления 0-4 конфигурируются с помощью битов CPUOFF, OSCOFF, SCG0 и SCG1 в регистре статуса. Преимущество включения битов управления режимом CPUOFF, OSCOFF, SCG0 и SCG1 в состав регистра статуса SR состоит в том, что текущий режим работы может быть сохранен, путем помещения содержимого SR в стек во время работы процедуры обработки прерывания. Выполняемая программа возвращается к предыдущему режиму работы, если сохраненное содержимое регистра SR не было изменено процедурой обработки прерывания. Выполнение программы может продолжится в другом рабочем режиме, если процедура обработки прерывания изменит значение регистра SR в стеке. Обращение к битам управления режимом и стеку может производиться с помощью любой команды.

При изменении любого бита управления режимом, выбранный режим работы активизируется немедленно. При отключении любой системы тактирования, блокируются также периферийные устройства, работающие от этой системы. Периферийные устройства также могут отключаться с помощью соответствующих им индивидуальных управляющих регистров. Состояние всех выводов портов ввода/вывода и ячеек ОЗУ остается неизменным. «Пробуждение» возможно через все разрешенные прерывания.

Рис.2-10 Режимы работы основной системы тактирования MSP430

SCG1 SCG0 OSCOFF CPUOFF Режим Состояние ЦПУ и систем тактирования
Активный ЦПУ и все системы тактирования активны
1 LPM0 ЦПУ и MCLK отключены; SMCLK и ACLK активны
1 1 LPM1 ЦПУ, MCLK и DCO-осцил. отключены; DC генератор отключен, если DCO не используется для MCLK или SMCLK в активном режиме; SMCLK и ACLK активны
1 1 LPM2 ЦПУ, MCLK, SMCLK и DCO-осцил. отключены; DC генератор остается включенным; ACLK активно
1 1 1 LPM3 ЦПУ, MCLK, SMCLK и DCO-осцил. отключены; DC отключен; ACLK активно
1 1 1 1 LPM4 ЦПУ и все системы тактирования отключены

2.3.1 Вход и выход из режимов пониженного энергопотребления

Появление прерывания выводит микроконтроллер семейства MSP430 из любого режима пониженного энергопотребления.

Программный поток выглядит так:

  • Вход в процедуру обработки прерывания:
    • Содержимое регистров PC и SR сохраняется в стеке;
    • Биты CPUOFF, SCG1 и OSCOFF автоматически сбрасываются;
  • Параметры для возвращения из процедуры обработки прерывания:
    • Исходное содержимое регистра SR восстанавливается из стека, что приводит к возобновлению работы устройства в предыдущем режиме;
    • Биты регистра SR, сохраненного в стеке, могут быть модифицированы процедурой обработки прерывания, что приведет к переходу в другой рабочий режим после выполнения команды RETI.

Нахождение в режимах пониженного энергопотребления в течение длительного времени

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

2.4 Принципы создания приложений с низким энергопотреблением

Часто, наиболее важным фактором для снижения энергопотребления является использование системы тактирования MSP430 для увеличения времени пребывания микроконтроллера в режиме LPM3. Типичное потребление тока в этом режиме составляет менее 2 мкА при функционирующей схеме тактирования реального времени и активированной системе прерываний. Модуль ACLK использует часовый кристалл 32 кГц, а ЦПУ тактируется от DCO (выключенного в нормальном режиме), который имеет время «пробуждения» 6 мкС.

  • Использование прерываний, «пробуждающих» процессор и управляющий программный поток;
  • Периферийные устройства должны включаться только при необходимости;
  • Следует использовать интегрированные периферийные модули с низким энергопотреблением вместо функций, реализуемых программными методами. К примеру таймер А и таймер В могут автоматически генерировать сигнал ШИМ и делать захват внешней синхронизации без использования ресурсов ЦПУ;
  • Вместо опроса флагов и длительных программных вычислений следует использовать рассчитываемое ветвление и быстрые таблицы преобразований;
  • Нужно избегать частого вызова подпрограмм и функций, увеличивающих непроизводительные издержки;
  • В длинных программных процедурах необходимо использовать однотактные регистры ЦПУ.

2.5 Подключение неиспользуемых выводов

Правильное подключение всех неиспользуемых выводов приведено в таблице 2.2.

Таблица 2.2. Подключение неиспользуемых выводов

Длительные операции на сервере

Область применения: управляемое приложение.

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

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

В противном случае такие вызовы могут привести к потере работоспособности приложения или затруднению работы с ним:

  • браузер может предложить прекратить длительно выполняющийся сценарий, после чего приложение станет неработоспособным;
  • веб сервер может прервать длительное обращение к серверу 1С:Предприятия и вернуть ошибку 504 (шлюз не отвечает);
  • в случае длительного выполнения операции, у пользователя нет возможности отменить ее.

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


    Код, выполняющий длительную обработку данных, располагается в модуле менеджера объекта* или в общем модуле. Результат своей работы он помещает во временное хранилище;

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

  • Для выполнения этого кода на сервере запускается фоновое задание, при этом необходимо ожидать завершения выполнения фонового задания в течение 0.8 сек;
  • Если за время ожидания выполнения задания оно не завершилось, то управление возвращается на клиент, и в клиентском коде подключается обработчик ожидания, в котором периодически проверяется состояние фонового задания. При этом интервал опроса задания увеличивается от 1 до 15 секунд с фиксированным коэффициентом 1.4 ;
  • На время выполнения длительной операции пользователю отображается индикатор;
    при этом для отчетов индикатор выводится в поле табличного документа, используя свойство поля табличного документа ОтображениеСостояния :

    а для прочих мест – выводится блокирующая форма ( РежимОткрытияОкна = БлокироватьОкноВладельца ), на которой размещена декорация с анимированной картинкой и кнопка «Отмена» :

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

    • разработаны без использования СКД или с использованием СКД, но с переопределенной процедурой формирования отчета (переопределен обработчик кнопки «Сформировать» или в обработчике модуля отчета ПриКомпоновкеРезультата устанавливается СтандартнаяОбработка = Ложь ).
    • и формирование которых, как правило, занимает длительное время.

    Поведение таких отчетов должно быть максимально похожим на поведение отчетов на базе СКД, а именно:

    • форму отчета не следует блокировать на время его формирования;
    • пользователь может изменить настройки и переформировать отчет, не дожидаясь окончания его формирования;
    • при закрытии формы отчета, формирование отчета прерывается.

    3. При использовании в конфигурации Библиотеки стандартных подсистем в распоряжении разработчика имеются вспомогательные функции и процедуры общих модулей ДлительныеОперации , ДлительныеОперацииКлиент , а также процедура УстановитьСостояниеПоляТабличногоДокумента общего модуля ОбщегоНазначенияКлиентСервер .


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

    Функция ОпределитьНастройкиУчетнойЗаписи(АдресЭлектроннойПочты, Пароль) Экспорт
    .
    Возврат Настройки;
    КонецФункции

    В форме объекта выполняется вызов этой функции в фоновом задании в три этапа:
    1) запуск фонового задания на сервере,
    2) подключение обработчика завершения фонового задания на клиенте,
    3) обработка результата выполнения фонового задания.

    // 2. Подключение обработчика завершения фонового задания.
    ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
    Оповещение = Новый ОписаниеОповещения(«ПриЗавершенииПоискаНастроек», ЭтотОбъект);
    ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыОжидания);
    КонецПроцедуры

    // 3. Обработка результата выполнения фонового задания.
    &НаКлиенте
    Процедура ПриЗавершенииПоискаНастроек(Результат, ДополнительныеПараметры) Экспорт

    Если Результат = Неопределено Тогда // Пользователь отменил задание.
    Возврат;
    КонецЕсли;

    Если Результат.Статус = «Ошибка» Тогда
    ВызватьИсключение Результат.КраткоеПредставлениеОшибки;
    КонецЕсли;

    Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
    УстановитьНастройкиУчетнойЗаписи(Настройки);

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

    Если МонопольныйРежим() Тогда
    Возврат;
    КонецЕсли;

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

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

    На время выполнения этого фонового задания следует блокировать весь интерфейс приложения, открывая форму ожидания завершения операции в режиме РежимОткрытияОкна = БлокироватьВесьИнтерфейс. Блокировать интерфейс приложения требуется потому, что на время выполнения задания полноценная работа пользователя с приложением уже невозможна:

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

    * Примечание: ошибки записи также возникают в тех случаях, когда объекты записываются программно, например, из обработчиков ожидания. В них также следует проверять монопольный режим согласно п.5.

    CAMOKAT-BETEPAHA › Блог › Программирование микроконтроллеров. Прерывание

    Очередная тема для новичков: прерывание.

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

    Рассмотрим микроконтроллер от Атмел ATtiny13A, как самый простой и доступный. Среда разработки — CodeVisionAVR.

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

    Из жизненной ситуации можно описать так:
    Сидит офисный работник, выполняет определенную ежедневную задачу каждый день, например пишет отчеты, составляет графики — обычная рутинная работа. И тут звонит телефон — сработал сигнал прерывания для работника. Работник сразу откладывает в сторонку документы (микроконтроллер в это время подготавливается и сохраняет нужные данные и запоминает место остановки) и начинает разговаривать по телефону (микроконтроллер при этом выполняет подпрограмму, описанную в прерывании). Дальнейшие действия сотрудника зависят от самого разговора. Но в итоге он опять возвращается к выполнению своей рутинной ежедневной работы ( у микроконтроллера это выполнение основного цикла while(1)).

    У микроконтроллера есть много разных прерываний. срабатывающих от разных условий. Когда есть много прерываний, то необходимы правила их выполнения при одновременном срабатывании условий их выполнения — приоритет. Если одновременно наступают события одновременно вызывающие разные прерывания, то выполняться начнет то, у которого выше приоритет — которое главнее. Приоритет прерываний описывается цифрой. Чем меньше число приоритета пррывания, тем приоритетней выполнение прерывания. По-английски это называется Interrupt Vectors — вектор прерываний.

    Из жизненной ситуации можно описать так:

    Сидит офисный работник, выполняет определенную ежедневную задачу каждый день, например пишет отчеты, составляет графики — обычная рутинная работа. И тут звонит телефон и заходит бля директор одновременно. У телефона приоритет прерывания равен 3, у директора единице. Телефон идет лесом — директор во внимании, выполняются его указания.

    Сидит офисный работник, выполняет определенную ежедневную задачу каждый день, например пишет отчеты, составляет графики — обычная рутинная работа. И тут звонит телефон и заходит бля директор одновременно. По телефону звонит Путин — у телефона приоритет прерывания равен 0, у директора единице. Директор идет лесом или даже тайгой — Путин на проводе весь во внимании — работник выполняет его указания.

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

    Вектор прерываний описывается в таблице Interrupt Vectors, заодно опишем, что они значат:

    Самое главное прерывание нулевое — RESET. Адрес его нулевой — вектор номер один. Источник прерывания — сброс микроконтроллера по ресету от входа RESET, от провала напряжения по питанию, если ативен фьюз Brown-out Reset и от срабатывания сторожевого таймера. Тут все и так понятно.

    Вектор два: INT0 — прерывание по внешнему входу INT0. У ATTiny13 это пятая ножка PB0.
    Ножку INT0 можно настроить на срабатывание на выполнение прерывания, насколько я помню, по фронту сигнала, по спаду или по изменению сигнала — и фронт и спад. Я, например, применяю это прерывание при необходимости выполнить точный подсчет длительности импульса для выполнения алгоритма деления или умножения частоты.

    Вектор три: PCINT0 — прерывание по изменению состояния по входам PB0 — PB5( PCINT0 — PCINT5), короче говоря все ножки микроконтроллера при этом можно применить для выполнения этого прерывания. Один из моих любимых прерываний, использую его в основном для пробуждения из сна по изменению на входах, когда микроконтроллер спит.

    Прервать выполнение программы в консоли

    Уважаемые программисты, подскажите, каким образом можно прервать консольную программу на C# ?

    3 ответа 3

    Самый правильный способ прервать выполенение кода на каком-либо его учатске — это оператор return . В Вашем случае его просто необходимо вставить в нужное место в методе main .

    Если по каким-либо причинам он Вам не подходит, то есть ещё несколько способов:

    1. System.Environment.Exit() — завершение текущего процесса.
    2. System.Threading.Thread.CurrentThread.Abort() — заврешение текущего потока исключением System.Threading.ThreadAbortException .

    Первый из предложенных вариантов Вам вполне подойдёт, но подумайте ещё раз о структуре программы.

    ОБОРУДОВАНИЕ
    ТЕХНОЛОГИИ
    РАЗРАБОТКИ

    Блог технической поддержки моих разработок

    Урок 18. Система прерываний STM32. Организация и управление прерываниями.

    В уроке изучим систему прерываний микроконтроллеров STM32. Разберемся, как управлять ей, как организовывать обработку аппаратных прерываний.

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

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

    Аппаратные прерывания и события.

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


    С точки зрения программы прерывание это вызов функции по внешнему, не связанному напрямую с программным кодом, событию.

    При определении понятия “прерывание” я употребил слово “событие” в общепринятом значении. Т.е. происшествие, нечто случившееся. Но в системе STM32 наряду с прерыванием (interrupt) существует еще одно строгое понятие – аппаратное событие (event).

    Событие – это нечто происшедшее с аппаратным узлом микроконтроллера. Например, переполнился таймер, в порт UART пришло данное, на внешнем входе изменился уровень сигнала и т.п.

    Аппаратное событие – это то, что вызывает прерывание. Вернее может вызвать прерывание.

    • Без события прерывание невозможно. Именно аппаратное событие инициирует прерывание.
    • События без прерываний могут происходить.

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

    Контроллер прерываний STM32.

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

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

    • Контроллер приоритетный. Т.е. обработка прерывания может быть прервана другим прерыванием с более высоким приоритетом. Прерывания с таким же или более низким приоритетом будут ожидать окончания обработки активного прерывания. Приоритеты можно разбивать на группы и подгруппы.
    • Как следствие предыдущего пункта для каждого прерывания может быть задан приоритет. Это число от 0 до 15. 0 — самый высокий приоритет. Для установки приоритетов существует специальный блок регистров. На каждое прерывание в нем отведен один байт.
    • Могут быть запрещены сразу все прерывания – глобальный запрет.
    • Могут быть запрещены или разрешены отдельные прерывания. Для этого существует регистр разрешения или маски прерываний. Его отдельные биты определяют разрешение для каждого прерывания.
    • Существует блок регистров ожидания обработки прерываний, каждый бит которых соответствует конкретному прерыванию и показывает, ожидает ли оно обработки. Биты регистров могут быть установлены, для принудительного перевода прерываний в состояние ожидания или сброшены для удаления.
    • Есть регистры действующих прерываний, которые показывают, находятся ли прерывания в стадии обработки.
    • Любое прерывание может быть вызвано программно. Для этого существует регистр программного вызова прерываний. Прерывание вызывается записью в него соответствующего номера.
    • Каждому из прерываний соответствует свой фиксированный адрес-вектор, по которому передается управление для обработки прерывания.

    Формально обработкой и управлением прерываниями занимается контроллер прерываний. Но для возникновения прерывания необходимо выполнение нескольких условий связанных как с контроллером прерываний, так и с периферийными устройствами микроконтроллера. Поэтому будем рассматривать задачу в комплексе.

    Программное управление прерываниями STM32.

    Для работы с аппаратными прерываниями необходимо:

    • Разрешить нужное прерывание в контроллере прерываний. Если необходимо, то задать для него приоритет.
    • Разрешить глобальные прерывания микроконтроллера.
    • Настроить устройство, в нашем случае таймер, на формирование запроса прерывания – события.
    • Создать функцию обработки прерывания.

    Разрешение и запрет прерываний.

    Для этого существуют функции библиотеки CMSIS.

    void NVIC_EnableIRQ(IRQn_Type IRQn) – разрешение прерывания с номером IRQn.

    void NVIC_DisableIRQ(IRQn_Type IRQn) – запрет прерывания с номером IRQn.

    В файле stm32f103xb.h есть символьные имена, соответствующие номерам прерываний. Они описаны в структуре IRQn_Type . Я ее значительно сократил.

    typedef enum <
    . . . . . . . . . . . . . . . . . . . . . . . .
    TIM1_BRK_IRQn = 24, /*!
    TIM1_UP_IRQn = 25, /*!
    TIM1_TRG_COM_IRQn = 26, /*!
    TIM1_CC_IRQn = 27, /*!
    TIM2_IRQn = 28, /*!
    TIM3_IRQn = 29, /*!
    TIM4_IRQn = 30, /*!
    > IRQn_Type;

    Команда разрешения прерывания перезагрузки таймера TIM1 будет выглядеть так.

    Установка приоритетов прерываний.

    По состоянию сброса для всех прерываний устанавливается самый высокий приоритет (0). Для его изменения существует функция библиотеки CMSIS.

    void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

    • IRQn – номер прерывания , можно в символьном виде типа IRQn_Type ;
    • priority – приоритет (0 … 15), 0 – наивысший.

    Например, если мы хотим для таймера TIM1 установить самый низкий приоритет, то необходимо выполнить команду.

    Глобальные разрешение и запрет прерываний.

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

    __disable_irq (); // запретить прерывания

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

    __enable_irq (); // разрешить прерывания

    Настройка устройства на формирование события и прерывания.

    Это действие касается настройки конкретного периферийного устройства и индивидуально для каждого из них. Будем рассматривать для каждого устройства отдельно. В следующем уроке настроим таймер.

    Функции обработки прерываний STM32.

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

    В микроконтроллерах STM32 поддерживается до 68 аппаратных прерываний. Каждому из них соответствует свой адрес – вектор. По этому адресу передается управление программы при возникновении прерывания.

    Конкретные адреса для каждого источника можно посмотреть в документации на микроконтроллер. Выглядит это примерно так.

    Из таблицы видно, что наш таймер TIM1 при перезагрузке формирует прерывания по адресу 00A4.

    В файле startup\startup_stm32f103xb.s таблица векторов преобразуется в символьные имена функций обработки прерываний.

    .word TIM1_BRK_IRQHandler
    .word TIM1_UP_IRQHandler
    .word TIM1_TRG_COM_IRQHandler
    .word TIM1_CC_IRQHandler
    .word TIM2_IRQHandler
    .word TIM3_IRQHandler
    .word TIM4_IRQHandler

    Для нашего таймера это TIM1_UP_IRQHandler .

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

    void TIM1_UP_IRQHandler(void) <

    // код обработки прерывания


    // код или функция завершения прерывания

    В начале файла c/cpp или h надо объявить функцию, разместить прототип.

    void TIM1_UP_IRQHandler(void);

    При выходе из функции, еще необходимо выполнить определенные действия для завершения прерывания. Как правило, это сброс флага прерывания.

    Иначе может произойти следующее. Устройство сформировало событие. Как следствие стал активным флаг прерывания. Произошло, и было обработано прерывание. Программа вернулась к месту, на котором была прервана. А флаг прерывания остался активным. Произойдет новое прерывание, вызванное ошибкой алгоритма. Перед возвратом надо сбросить флаг. Об этом подробно в следующем уроке.

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

    В следующем уроке будем настраивать таймеры.

    Обработка прерываний в M-профиле

    Обработка прерываний в M-профиле кардинально отличается от таковой в других профилях архитектуры ARM.

    Документация на M-профиль различает несколько видов прерываний.

    • Сброс (reset) является особым видом прерывания, немедленно прекращающим выполнение текущей операции и переводящим процессор в предопределённое состояние без возможности возвращения управления ранее выполнявшемуся коду.
    • Синхронный вызов супервизора (SVCall) выполняется по команде SVC.
    • Асинхронный вызов супервизора (PendSV) выполняется с помощью механизма отложенного вызова супервизора через регистр ICSR.
    • Отказ (fault) возникает при обнаружении какой-либо ошибки при выборке или выполнении команды. Отказы могут быть синхронными (прямо связаны с определённой командой) или асинхронными (вызываться какой-либо из ранее выполненных команд, если ошибка не могла быть выявлена сразу). Асинхронным в M-профиле является лишь неточный отказ шины (imprecise BusFault), возникающий при неудачной попытке записи в память. Процессор ради увеличения производительности может не дожидаться фактического завершения записи и продолжать выполнять команд дальше, поэтому при позднем обнаружении отказа установить, какая именно команда стала причиной ошибки, и выполнить «откат» к ней в общем случае невозможно.

    К отказам технически относятся также синхронные события, связанные с отладкой (асинхронные отладочные события обрабатываются как внешние прерывания).

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

    Каждое прерывание имеет следующие характеристики:

    • номер прерывания;
    • приоритет;
    • вектор в памяти, где хранится адрес точки входа в обработчик прерывания.

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

    • неактивно (inactive) — прерывание не запрошено и не обслуживается;
    • ожидает (pending) — прерывание запрошено, но его обработка ещё не начата;
    • активно (active) — прерывание обрабатывается в данный момент либо его обработка была начата, но в настоящее время прервана для обработки более приоритетного прерывания;
    • активно и ожидает (active and pending) — обработка прерывания была начата, однако запрос на это же прерывание продолжает присутствовать и ожидать обслуживания. В таком состоянии могут находиться лишь асинхронные прерывания.

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

    Примечание. «Существенность» превосходства приоритета запроса прерывания над приоритетом выполнения определяется механизмом группировки приоритетов, о котором будет сказано ниже.

    M-профиль оптимизирован для «цепочечной» обработки прерываний: если при завершении текущего обработчика окажется, что своей обработки ожидает запрос примерно такого же или несколько более низкого приоритета (существенно выше, чем приоритет ранее прерванного кода, но не существенно выше, чем приоритет обработчика, который завершает своё выполнение), то процессор сразу перейдёт к обработке ожидающего запроса, при необходимости скорректировав текущий приоритет выполнения. Возврат к прерванному ранее коду произойдёт лишь тогда, когда не останется достаточно приоритетных запросов, ожидающих обработки. Благодаря такому подходу исключается время, необходимое на восстановление и повторное сохранение контекста прерванного процесса между завершением одного и началом следующего обработчика.

    Номера и векторы прерываний

    Таблица векторов прерываний имеет размер N+1 слов, где N — число различных прерываний, поддерживаемых данной реализацией архитектуры. По смещению 0 относительно начала таблицы находится значение, загружаемое в указатель основного стека SP_main при сбросе. За ним располагаются собственно векторы, т. е. адреса точек входа в соответствующие обработчики прерываний (заметим, что младший бит адреса точки входа всегда должен быть равен единице, задавая использование системы команд Thumb). Для прерывания с номером N вектор в таблице располагается по смещению 4*N. Базовый адрес таблицы векторов в памяти находится в регистре VTOR.

    Архитектурой определены следующие стандартные номера прерываний:

    • Сброс (reset) — номер 1. Имеет фиксированный приоритет –3 (высший) и не может быть запрещён. Возобновление выполнения прерванного сбросом кода невозможно. Хотя формально сброс отнесён к прерываниям, реально таковым он не является; по этой причине описание выполняемых по нему действий вынесено в отдельный раздел.
    • Немаскируемое прерывание (NMI, Non Maskable Interrupt) — номер 2. Имеет фиксированный приоритет –2 (наибольший, не считая сброса) и не может быть запрещено. Немаскируемые прерывания могут запрашиваться аппаратно либо программно через регистр ICSR.
    • Серьёзный отказ (HardFault) — номер 3. Имеет приоритет –1 и не может быть запрещён. Серьёзный отказ фиксируется каждый раз, когда возникшее прерывание не может быть обработано «родным» обработчиком, и обычно является признаком невосстановимой ошибки. В частности, это прерывание возникает, если отказ обнаруживается в то время, когда его обработка запрещена установкой бита FM регистра FAULTMASK.

    В архитектуре ARMv6-M многие другие прерывания отсутствуют, и вместо них возникает серьёзный отказ.

    • Управление памятью (MemManage) — номер 4. Приоритет этого прерывания настраивается и оно может быть запрещено, однако его возникновение в запрещённом состоянии приведёт к серьёзному отказу. Это прерывание происходит, если программа обращается к той или иной ячейке памяти недопустимым образом (нарушает права доступа либо стандартные ограничения на доступ к определённым областям адресного пространства).

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

    • Отказ шины (BusFault) — номер 5. Приоритет этого прерывания настраивается и оно может быть запрещено, однако его возникновение в запрещённом состоянии приведёт к серьёзному отказу. Это прерывание возникает при ошибках во время попытки доступа к памяти, не связанных с нарушением прав доступа и иных чётко определённых правил, приводящим к возникновению прерывания MemManage. Например, к отказу шины может привести ошибка чётности в считанной из памяти информации. Прерывания этого типа могут быть как синхронными, так и асинхронными.

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

    • Ошибка использования (UsageFault) — номер 6. Приоритет этого прерывания настраивается и оно может быть запрещено, однако его возникновение в запрещённом состоянии приведёт к серьёзному отказу. Это прерывание связано с разного рода ошибками в программе:
    • недопустимым кодом команды или попыткой выполнить привилегированную команду в непривилегированном режиме;
    • неверным состоянием выполнения (например, попыткой перейти на систему команд ARM, которая в M-профиле не поддерживается);
    • ошибкой, возникшей при возврате из обработчика прерывания;

    • попыткой доступа к отключённому или отсутствующему сопроцессору;
    • попыткой невыровненного доступа, если включён контроль выравнивания;
    • попыткой выполнить деление на 0.

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

    • Прерывания с номерами 7—10 зарезервированы.
    • Вызов супервизора (SVCall) — номер 11. Это прерывание имеет настраиваемый приоритет и происходит при выполнении команды SVC, а поэтому не может быть запрещено.

    Команда SVC и связанное с ней прерывание отсутствуют, если конкретная реализация процессора не поддерживает ОС.

    • Отладочный монитор (Debug monitor) — номер 12. Приоритет этого прерывания настраивается. В общем случае прерывания, генерируемые отладочным монитором, являются синхронными и обрабатываются как отказы, однако точки слежения (debug watchpoints) порождают асинхронные события, обрабатываемые аналогично внешним прерываниям.

    В версии ARMv6-M это прерывание отсутствует.

    • Прерывание с номером 13 зарезервировано.
    • Отложенный вызов супервизора (PendSV) — номер 14. Это прерывание имеет настраиваемый приоритет и всегда разрешено. Оно управляется с помощью регистра ICSR и происходит асинхронно по отношению к выполняемому программному коду.
    • Системный таймер (SysTick) — номер 15. Это прерывание с настраиваемым приоритетом всегда разрешено. Его аппаратная генерация может быть запрещена, однако его всегда можно вызвать программно через регистр ICSR. Оно связано со стандартным таймером, входящим в процессоры M-профиля, и является асинхронным.

    В версии ARMv6-M это прерывание является необязательным (отсутствует, если в конкретной реализации нет системного таймера).

    • Внешние прерывания (external interrupts). Нумерация источников этих прерываний является двоякой: номера отведённых для них векторов, а соответственно, и номера прерываний с точки зрения процессора, начинаются с 16, однако номера источников запросов, поступающих на контроллер прерываний NVIC, начинаются с нуля (это объясняется тем, что логически NVIC работает исключительно с внешними прерываниями, в то время как все описанные выше прерывания обрабатываются непосредственно процессором). Эти прерывания имеют настраиваемый приоритет и могут запрещаться. Все они являются асинхронными.

    Максимальный номер прерывания определяется реализацией, но не может превышать 511, что ограничивает количество возможных внешних прерываний 496-ю. В версии ARMv6-M может быть реализовано не более 32 внешних прерываний.

    Приоритеты прерываний

    Приоритет прерывания тем выше, чем алгебраически меньше обозначающее его число. Три самых приоритетных прерывания — сброс, NMI и серьёзный отказ — имеют фиксированные приоритеты, равные соответственно –3, –2 и –1. Все остальные прерывания имеют программно назначаемые приоритеты (через соответствующие регистры блока управления системой и контроллера прерываний), причём наименьшее значение, а соответственно, наибольший приоритет будет равен нулю. Благодаря последнему обстоятельству все три прерывания с фиксированными приоритетами всегда являются более приоритетными, чем любые другие прерывания.

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

    Сброс устанавливает все программно настраиваемые приоритеты в нуль.

    Программируемые приоритеты

    Как уже отмечалось, почти все прерывания имеют программируемый приоритет. В версии ARMv7-M эта величина в зависимости от реализации занимает от 3 до 8 разрядов; в версии ARMv6-M – всегда два бита. Для обеспечения максимальной программной совместимости реализованные биты приоритета всегда являются старшими разрядами байта, при этом младшие разряды, соответствующие нереализованным битам, считаются равными нулю. Таким образом, минимальный приоритет в зависимости от реализованного числа разрядов может быть равен 192, 224, 240, 248, 252, 254 или 255 (C0, E0, F0, F8, FC, FE или FF); максимальный приоритет всегда равен нулю. Запись единиц в нереализованные разряды игнорируется; при чтении они будут равны нулю.

    При программном изменении приоритета в версии ARMv6-M соответствующее прерывание должно быть запрещено и не обрабатываться в момент изменения, иначе последствия будут непредсказуемыми (требование запрещённости не распространяется на прерывания SVCall и PendSV, которые не могут быть запрещены). Версия ARMv7-M позволяет изменять приоритеты прерываний в любое время, однако в общем случае после этого необходимо выполнить следующие подряд команды DSB и ISB, обеспечивающие синхронизацию изменения приоритета с выполнением кода.

    Версия ARMv7-M делит приоритеты (не считая прерываний с фиксированными приоритетами) на группы в соответствии со значением поля PRIGROUP регистра AIRCR. 8-разрядное поле приоритета делится на две части: приоритет группы и подприоритет (приоритет внутри группы). Приоритет группы имеет длину от 7 до 0 битов для значений PRIGROUP от 0 до 7 соответственно; оставшуюся часть поля приоритета (1–8 разрядов) занимает подприоритет. Приоритет группы используется для того, чтобы определить, достаточно ли приоритетен запрос, чтобы прервать выполнение текущего кода (приоритет запроса существенно выше текущего приоритета выполнения, если приоритет группы данного запроса численно меньше приоритета группы текущего выполняющегося кода). Подприоритет используется только для того, чтобы выбрать порядок обработки одновременно поступивших запросов прерываний, относящихся к одной группе приоритетов.

    Система приоритетов в версии ARMv6-M намного проще: в ней поддерживается только четыре уровня приоритетов без возможности их группировки (каждый уровень образует отдельную группу).

    Каждое из трёх прерываний с фиксированным приоритетом образует отдельную группу.

    Приоритеты стандартных прерываний задаются в регистрах SHPR, приоритеты внешних прерываний — в регистрах контроллера прерываний NVIC_IPR.

    Приоритет выполнения

    На минимально возможном приоритете процессор работает в режиме потока. «Арифметически» можно считать, что этот приоритет равен минимально возможному приоритету прерывания плюс 1. Например, если реализация поддерживает все 8 разрядов приоритета прерывания (максимальный — 0, минимальный – 255), минимально возможным приоритетом выполнения будет 256. Эта величина называется в документации базовым уровнем приоритета выполнения (base level of execution priority) или просто базовым приоритетом.

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

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

    • Ненулевое значение в регистре BASEPRI (отсутствует в версии ARMv6-M) задаёт приоритет, который будет использован в качестве приоритета выполнения, если он выше (численно меньше), чем самый высокий приоритет среди активных прерываний. В частности, если выполняется поток, BASEPRI повышает его приоритет до заданного в BASEPRI значения. Нулевое значение в BASEPRI означает, что этот регистр в определении текущего приоритета выполнения не участвует.
    • Установленный бит PM регистра PRIMASK повышает текущий приоритет выполнения до нуля, т. е. запрещает все прерывания с программируемым приоритетом (разрешёнными остаются лишь HardFault, NMI и сброс). Если этот бит сброшен, он не влияет на определение текущего приоритета выполнения. Заметим, что установленный бит PM не препятствует прерыванию вывести процессор из ожидания, начатого командой WFI, но запрещает после пробуждения переходить к обработке данного прерывания: вместо этого процессор продолжит выполнять команды, следующие за WFI.
    • Установленный бит FM регистра FAULTMASK (отсутствует в версии ARMv6-M) повышает текущий приоритет до –1, запрещая все прерывания, кроме сброса и NMI. Он может быть установлен лишь при текущем уровне приоритета, численно равным или большим нуля; попытка установить этот бит в обработчике HardFault или NMI игнорируется. Если этот бит сброшен, он не участвует в определении текущего приоритета. Завершение обработки прерывания, за исключением возврата из NMI, автоматически сбрасывает бит FM.

    Таким образом, текущий приоритет выполнения равен численно наименьшей из следующих величин:

    • –1, если установлен бит FM регистра FAULTMASK;
    • 0, если установлен бит PM регистра PRIMASK;
    • приоритету, заданному в регистре BASEPRI, если его содержимое отлично от нуля и оно численно меньше, чем самый высокий из приоритетов активных прерываний;
    • высшему из приоритетов активных прерываний;
    • базовому приоритету выполнения потока.

    При анализе приоритетов учитывается лишь приоритет группы, но не подприоритет; последний влияет лишь на очерёдность обслуживания прерываний внутри одной приоритетной группы.

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

    В версии ARMv6-M изменение приоритета активного или разрешённого прерывания приведёт к непредсказуемым последствиям, а поэтому производиться не должно.


    Повышение приоритета запроса прерывания

    Когда текущий приоритет выполнения ниже, чем HardFault (–1), процессор может поднять приоритет до этого уровня и войти в обработчик серьёзного отказа, если:

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

    Если любое из этих событий произошло в обработчике HardFault или NMI, вызов обработчика серьёзного отказа невозможен; вместо этого процессор входит в состояние блокировки. Предполагается, что при нормальной работе подобные ситуации возникать не должны.

    Заметим, что приоритет запросов внешних прерываний никогда не повышается: если прерывание запрещено, его запрос запоминается, но не влияет на выполнение программы, а если разрешено – ожидает, пока текущий приоритет выполнения не окажется существенно ниже приоритета данного запроса, после чего последний начинает обрабатываться.

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

    Адрес возврата из обработчика прерывания HardFault, вызванного в результате повышения приоритета запроса другого прерывания, определяется по правилам, относящимся к исходному запросу, а не к серьёзному отказу (например, для UsageFault он будет соответствовать команде, вызвавшей отказ, а для SVCall – команде, следующей за командой SVC).

    Если процессор располагает сопроцессором с плавающей запятой, правила повышения приоритета во время сохранения контекста сопроцессор отличаются от вышеописанных (см. ниже).

    Управление прерываниями

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

    Первую группу образуют входящие в состав ядра процессора регистры IPSR, PRIMASK, FAULTMASK и BASEPRI (два последних в версии ARMv6-M отсутствуют). Все они доступны привилегированному коду с помощью команд MSR и MRS; кроме того, состояние битов масок в регистрах PRIMASK и FAULTMASK может изменяться командой CPS. Первый из перечисленных регистров доступен только для чтения и содержит номер текущего обрабатываемого прерывания, три остальных позволяют изменить текущий приоритет выполнения.

    Во вторую группу входят регистры пространства управления системой (SCS), из которых к управлению прерываниями относятся следующие:

    • VTOR — содержит базовый адрес таблицы векторов прерываний;
    • ICSR — позволяет получить информацию об активных и ожидающих прерываниях, а также программно запросить прерывания NMI, SysTick и PendSV и сбросить запросы двух последних прерываний;
    • AIRCR — управляет группированием приоритетов и поведением при сбросе, а также позволяет узнать порядок следования байтов, используемый для хранения информации в памяти;
    • SCR — управляет влиянием прерываний на режимы сна;
    • CCR — позволяет разрешить или запретить генерацию прерываний при делении на 0 и нарушении выравнивания, а также BusFault при текущем уровне привилегий –1 и выше;
    • SHPR — управляют приоритетами стандартных прерываний;
    • SHCSR — хранит информацию об активных и ожидающих прерываниях, а также разрешает или запрещает прерывания UsageFault, BusFault и MemManage;
    • CFSR, HFSR, DFSR, MMFAR, BFAR — содержат информацию об обслуживаемых отказах и управляют ими;
    • STIR — позволяет программно вызвать появление запроса внешнего прерывания.

    Третья группа представлена регистрами контроллера прерываний NVIC, а четвёртая — регистрами системного таймера SysTick. Они применяются для управления прерываниями от внешних устройств и от таймера соответственно.

    Начало и завершение обработки прерывания

    Вход в обработчик прерывания

    Перед входом в обработчик прерывания производится сохранение контекста прерванного процесса. Для этого:

    • в текущем стеке путём уменьшения значения указателя стека резервируется место под область сохранения контекста. Длина этой области определяется по следующим правилам:
    • если FPU используется (бит FPCA регистра CONTROL установлен), резервируется 104 байта (26 слов). Кроме того, если SP не кратен 8, для обеспечения выравнивания на границу двойного слова он дополнительно уменьшается на 4;
    • если процессор не имеет FPU либо если он не используется (бит FPCA сброшен), резервируется 32 байта. Кроме того, если установлен бит STKALIGN регистра CCR, а SP не кратен 8, он дополнительно уменьшается на 4. В версии ARMv6-M бит STKALIGN всегда установлен; конкретные реализации версии ARMv7-M также могут иметь его постоянно установленным;
    • в выделенной области, начиная с её младшего слова (новой вершины стека), сохраняются регистры R0–R3, R12 и LR прерванного процесса, адрес возврата к нему (см. ниже) и содержимое регистра XPSR, всего 8 слов. В сохранённом значении XPSR дополнительно устанавливается бит 9, если при резервировании места потребовалось дополнительное уменьшение SP на 4 для обеспечения выравнивания;
    • если FPU используется, то:
    • при отключённом отложенном сохранении контекста FPU (бит LSPEN регистра FPCCR равен 0) выполняется его немедленное сохранение, начиная со смещения 32 от новой вершины стека (сразу вслед за сохранёнными на предыдущем этапе значениями). В область сохранения записываются регистры S0–S15 и FPSCR, всего 17 слов;
    • при включённом отложенном сохранении контекста FPU (бит FPCCR.LSPEN равен 1) немедленное сохранение не выполняется. Вместо этого в регистр FPCAR заносится адрес новой вершины стека плюс 32, т. е. адрес начала области сохранения контекста FPU, а в регистре FPCCR устанавливается бит LSPACT (признак активности отложенного сохранения контекста FPU). Кроме того, в регистре FPCCR устанавливаются или сбрасываются биты USER, THREAD, HFRDY, BFRDY, MMRDY, MONRDY, отражающие состояние процессора на момент сохранения контекста, т. е. перед входом в новый обработчик прерывания. Если окажется необходимым, контекст FPU будет сохранён позже.

    Формат сохранения контекста в зависимости от поддержки FPU и необходимости выравнивания приведён на следующих рисунках.

    Формат области сохранения контекста без FPU

    Формат области сохранения контекста с FPU

    После сохранения контекста прерванного процесса производится переход к обработчику прерывания. На момент входа в него:

    • процессор находится в режиме обработчика;
    • используется основной стек, указатель которого (SP_main, он же MSP) содержит последнее занесённое в него значение: если контекст сохранялся в стеке процесса (указатель SP_process, он же PSP), SP_main не изменился по сравнению с моментом начала перехода к обработке прерывания, если же контекст сохранялся в основном стеке, последний был уменьшен на размер области сохранения контекста, как описывалось выше;
    • регистры R4–R11 содержат значения, находившиеся там на момент начала входа в обработчик. Если последний желает использовать эти регистры, он должен сначала сохранить их, а перед возвратом – восстановить;
    • регистры R0–R3 и R12 имеют в общем случае непредсказуемые значения (исходные значения на момент возникновения первого из прерываний записываются в стек прерванного кода и остаются в регистрах в момент входа в обработчик, однако при вызове любых последующих обработчиков до возврата управления изначально прерванному коду там будут находиться непредсказуемые значения);
    • счётчик команд содержит адрес точки входа в обработчик, считанный из таблицы векторов прерываний. Младший бит в нём принудительно сбрасывается;
    • регистр LR содержит значение, определяющее способ возврата к прерванному коду (так называемый EXC_RETURN). Оно формируется по следующим правилам:
    • биты 31:5 всегда содержат единицы;
    • бит 4 равен 0, если у процессора есть FPU и он используется (бит CONTROL.FPCA установлен), и равен 1 в противном случае;
    • бит 3 равен 0, если на момент начала перехода к обработке прерывания процессор находился в режиме обработчика, и равен 1, если в режиме потока;
    • бит 2 равен 0, если на момент начала перехода к обработке прерывания использовался основной стек, и равен 1, если использовался стек процесса;

    • биты 1:0 всегда содержат 01;
    • если было выполнено сохранение контекста FPU, то содержимое его регистров S0–S15, FPSCR и FPCAR не определено, иначе они содержат значения на момент начала входа в обработчик прерывания. Регистры S16–S31 не изменяются;
    • состояние битов регистра APSR является непредсказуемым;
    • регистр IPSR содержит номер текущего обслуживаемого прерывания;
    • регистр EPSR равен нулю, за исключением бита T, который равен младшему биту адреса точки входа, считанной из таблицы векторов. Если этот бит равен нулю, то сразу после входа в обработчик возникнет прерывание UsageFault (HardFault для архитектуры ARMv6-M);
    • биты регистра CONTROL содержат следующие значения:
    • nPRIV не меняется и находится в состоянии на момент начала входа в обработчик прерывания. Поскольку процессор к данному времени уже находится в режиме обработчика, значение этого бита игнорируется (выполняемый код считается привилегированным);
    • бит SPSEL равен нулю (активен основной стек);
    • бит FPCA сброшен (FPU не используется);
    • регистры состояния в блоке управления системой отражают причину возникновения прерывания;
    • локальный монитор синхронизации, используемый командами LDREX и STREX, сброшен;
    • установлен регистр события, влияющий на выполнение команды WFE;
    • выполнен барьер синхронизации команд.

    Адрес возврата, сохраняемый вместе с контекстом в стеке прерванного процесса, зависит от причины возникновения прерывания:

    • для NMI, неточного серьёзного отказа или отказа шины, вызова супервизора, асинхронного отладочного события и внешнего прерывания (включая PendSV и SysTick) он равен адресу команды, с которой должно продолжиться выполнение;
    • для точного серьёзного отказа или отказа шины, MemManage, UsageFault и точного отладочного события он равен адресу команды, ставшей причиной прерывания.

    Заметим, что в случае вызова супервизора командой SVC её адрес может быть получен вычитанием 2 из адреса возврата. Неточные отказы не позволяют определить адрес команды, выполнение которой стало первопричиной ошибки, и обычно приводят к невозможности корректного продолжения работы.

    Завершение обработчика прерывания

    Завершение обработчика прерывания и возврат к прерванному коду происходит, когда в режиме обработчика значение, содержащее 1 в четырёх старших разрядах, загружается в счётчик команд с помощью одной из следующих команд: POP, LDM, LDR или BX. Такое специальное значение носит название EXC_RETURN. Загрузка численно идентичного значения любым другим способом или в режиме потока не является завершением обработчика прерывания, а трактуется как обычный переход. Поскольку все адреса в диапазоне от F0000000 до FFFFFFFF не являются обычной памятью и не допускают выборку команд для исполнения, переход на любой подобный адрес вызывает прерывание UsageFault (HardFault в архитектуре ARMv6-M).

    Разряды EXC_RETURN имеют следующие функции:

    • биты 31:28, равные 1, являются признаком операции возврата из обработчика прерывания;
    • биты 27:5 зарезервированы и должны быть равны 1. Если какой-либо из них будет равен нулю, результат окажется непредсказуемым;
    • бит 4 равен нулю, если при сохранении контекста в стеке выделялось место под регистры FPU, и равен единице, если место выделялось лишь под основной контекст;
    • бит 3 указывает, в каком режиме должен находиться процессор после завершения обработчика: 0 соответствует режиму обработчика, 1 — режиму потока;
    • бит 2 выбирает стек, в котором был сохранён контекст и который будет использован после выхода из данного обработчика: 0 соответствует основному стеку, 1 — стеку процесса. Если возврат происходит в режим обработчика, этот бит должен быть равен нулю;
    • бит 1 всегда равен нулю;
    • бит 0 всегда равен единице.

    При завершении обработчика процессор версии ARMv7-M выполняет ряд проверок корректности возврата:

    • текущее прерывание (его номер находится в регистре IPSR) должно быть отмечено в соответствующем системном регистре как активное;
    • если активно несколько прерываний, после возврата из текущего обработчика процессор обычно должен оставаться в режиме обработчика. Если необходимо нарушить это правило, необходимо сначала установить бит NONBASETHRDENA регистра CCR;
    • при возврате в код режима потока восстанавливаемый IPSR должен иметь нулевое значение, а при возврате в код режима обработчика — ненулевое;
    • младшие четыре разряда EXC_RETURN должны быть выставлены корректно: допустимыми являются только комбинации 0001, 1001 и 1101.

    Нарушение любого из этих правил вызывает прерывание UsageFault, при этом прерывание, нормально завершить обработчик которого не удалось, всё равно считается завершённым.

    В версии ARMv6-M проверки не выполняются, а нарушение правил возврата из обработчика имеет непредсказуемые последствия.

    После успешного возврата из обработчика прерывания:

    • регистры R0–R3, R12, LR, PC и XPSR восстановлены из области сохранения контекста в стеке. Если считанное содержимое PC (адрес возврата) не выровнено на границу полуслова, поведение процессора непредсказуемо;
    • регистры FPU S0–S15 и FPSCR восстановлены из стека, если под них выделялась память (EXC_RETURN[4] равен нулю) и сохранение действительно имело место (бит LSPACT регистра FPCCR сброшен). Если бит LSPACT на момент выхода из обработчика установлен, это означает, что сохранение контекста не потребовалось, поскольку при выполнении завершающегося обработчика обращений к FPU не было; в этом случае LSPACT просто сбрасывается. Если же EXC_RETURN[4] равен единице, это означает, что память в стеке под контекст FPU не выделялась;
    • указатель стека, активного после выхода из обработчика, скорректирован таким образом, чтобы удалить область сохранения контекста, из которой были восстановлены другие регистры, при этом учитывается факт дополнительного уменьшения SP на 4, когда оно выполнялось (бит 9 сохранённого значения XPSR установлен);
    • бит FM регистра FAULTMASK сброшен, за исключением возврата из обработчика NMI, когда он не изменяется;
    • разряды регистра CONTROL находятся в состоянии, соответствующем значению EXC_RETURN: FPCA = not EXC_RETURN[4], SPSEL = EXC_RETURN[2]. Состояние nPRIV не изменяется;
    • локальный монитор синхронизации, используемый командами LDREX и STREX, сброшен;
    • выполнен барьер синхронизации команд;
    • если необходимо, процессор переведён в сон (см. описание команды WFI и бита SLEEPONEXIT регистра CCR).

    Сцепление прерываний

    Сцепление прерываний (tail-chaining) — это механизм, позволяющий сократить время переключения с одного обработчика прерывания на другой в момент завершения первого обработчика. Это достигается тем, что, обнаружив наличие ожидающего запроса прерывания с групповым приоритетом более высоким, чем приоритет выполнения кода, к которому осуществляется возврат (с учётом состояния регистров масок), процессор не выполняет возврат из прерывания с немедленным повторным входом в новый обработчик, а сразу передаёт управление новому обработчику, при этом в LR на момент входа в обработчик нового прерывания будет находиться значение EXC_RETURN, заданное при завершении предыдущего обработчика.

    Возникновение прерывания во время входа в обработчик прерывания

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

    • асинхронное внешнее прерывание от какого-либо устройства ввода-вывода;
    • отладочная точка наблюдения (при запрещённом отладочном останове);
    • прерывания MemManage и BusFault, связанные с попыткой сохранения контекста прерванного кода в его стеке;
    • прерывание BusFault, связанное с попыткой выборки адреса точки входа из таблицы векторов прерываний.

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

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

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


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

    Два последних случая указывают на ошибку в процессе входа в обработчик. Ошибкам MemManage и BusFault, связанным с сохранением контекста, будет присвоен класс MSTKERR и STKERR соответственно, что найдёт своё отражение в регистрах состояния прерываний. Прерывание BusFault, связанное с попыткой считывания адреса обработчика из таблицы векторов прерываний, всегда рассматривается как серьёзный отказ и обрабатывается не как BusFault, а как HardFault.

    Если приоритет прерывания, порождённого в результате ошибки, ниже или равен приоритету прерванного кода, т. е. если обработчик порождённого прерывания в соответствии с обычными правилами приоритетов немедленно вызван быть не может, произойдёт его повышение до уровня HardFault (приоритет –1). Исходное прерывание получит статус ожидающего и произойдёт вход в обработчик серьёзного отказа.

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

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

    Возникновение прерывания при выходе из обработчика прерывания

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

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

    Прерывание по точке наблюдения будет проигнорировано, если его приоритет ниже либо равен приоритету кода, к которому производится возврат; в противном случае произойдёт сцепление прерываний и управление получит обработчик отладочного прерывания.

    Для прерываний MemManage и BusFault, связанных с попыткой восстановления контекста, в регистрах состояния прерываний будет установлен класс MUNSTKERR и UNSTKERR соответственно. Если приоритет соответствующего обработчика выше, чем приоритет кода, к которому осуществляется возврат, произойдёт сцепление прерываний и управление получит обработчик ошибки. Если же его приоритет ниже или равен приоритету кода, к которому выполняется возврат, произойдёт повышение приоритета до уровня HardFault (–1), после чего с помощью сцепления прерываний будет вызван обработчик серьёзного отказа.

    Блокировка при невозможности входа в обработчик прерывания

    Если при выполнении кода с приоритетом –1 или выше (обработчика серьёзного отказа или NMI, а также любого кода при установленном бите FM регистра FAULTMASK) возникнет прерывание, оно не сможет быть обработано, поскольку приоритет его обработчика не может быть выше 0, а с помощью повышения его приоритета нельзя получить приоритет выше –1. В этом случае процессор выполняет следующие действия:

    • устанавливает бит S_LOCKUP в регистре состояния и управления отладочными остановами DHCSR;
    • устанавливает бит регистра состояния прерываний, отвечающий за причину, приведшую к возникновению прерывания, которое невозможно обработать;
    • зацикливается на команде, послужившей причиной возникновения прерывания, а если причиной была не команда, а выполнение какого-либо другого действия, например, попытка сохранения или восстановления контекста, — на «команде», выбираемой по адресу FFFFFFFE. Адрес, на котором произошло зацикливание, называется адресом блокировки (lockup address).

    В архитектуре ARMv6-M зацикливание всегда происходит на адресе FFFFFFFE.

    Блокировка с зацикливанием по адресу FFFFFFFE происходит по следующим причинам:

    • неудачная попытка считывания адреса или начального значения SP при сбросе;
    • неудачная попытка считывания вектора NMI или HardFault;
    • BusFault при попытке сохранения или восстановления контекста;
    • MemManage при попытке сохранения или восстановления контекста;
    • UsageFault при возврате из прерывания в связи с недопустимым значением PC.

    Блокировка с зацикливанием по адресу команды, вызвавшей ошибку, происходит по следующим причинам:

    • BusFault при попытке выборки команды. Если через некоторое время причина возникновении ошибки будет устранена (например, первопричиной ошибки шины послужило «сонное» состояние памяти), эта ошибка будет автоматически устранена, и процессор, выбрав команду, продолжит нормальную работу;
    • точный BusFault при обращении к данным. Эта ошибка будет проигнорирована, если установлен бит BFHFNMIGN в регистре CCR (процессор ограничится лишь установкой индикатора ошибки в соответствующем регистре состояния). Как и в предыдущем случае, блокировка может быть снята, если ошибка через некоторое время исчезнет;
    • MemManage при попытке выборки команды. Эта ошибка всегда приведёт к зацикливанию по адресу команды, если производится попытка её выборки из адресного пространства, недоступного для исполнения, однако может быть проигнорирована в остальных случаях, если установлен бит HFNMIENA регистра MPU_CTRL;
    • MemManage при попытке доступа к данным. Эта ошибка игнорируется, если установлен бит HFNMIENA регистра MPU_CTRL;
    • попытка выполнения команды SVC. Сама команда в этом случае рассматривается как неопределённая и никаких действий, кроме зацикливания, не вызывает;
    • UsageFault, связанный с какой-либо конкретной командой;
    • срабатывание точки останова.

    Вывод из блокировки, за исключением автоматического продолжения выполнения при устранении причины отказа шины при выборке команды или обращении к данным, возможен лишь следующими способами:

    • если зацикливание имеет место при приоритете –1, NMI вызовет обычный вход в обработчик NMI, имеющий более высокий приоритет (–2). Адресом возврата из этого обработчика будет адрес блокировки;
    • с помощью сброса, в том числе от сторожевого таймера;
    • путём останова внешним отладчиком.

    Дополнительная информация

    Прерываемые команды

    Некоторые команды могут быть реализованы как прерываемые. В случае поступления прерывания во время выполнения такой команды она будет прервана, причём информация о том, какая часть уже проделана, будет сохранена в поле ICI регистра EPSR. К числу потенциально прерываемых относятся команды LDM, STM, POP, PUSH, VLDM, VSTM, VPOP и VPUSH (последние четыре относятся к набору команд FPU). После возврата из прерывания выполнение прерываемой команды возобновится с точки, где оно было прервано. В других реализациях при возникновении прерывания выполнение перечисленных команд может прекращаться, а после возврата из прерывания — начинаться с самого начала.

    Если прерываемая команда встречается внутри блока IT, в регистре EPSR будет сохранено состояние выполнения этого блока (поле IT), а не состояние прерываемой команды. В этом случае выполнение последней после возврата из обработчика прерывания начнётся с самого начала.

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

    Энергосбережение

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

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

    Если в процессоре реализованы средства энергосбережения, управление ими осуществляется с помощью следующих разрядов регистра SCR:

    • SEVONPEND — если установлен, появление ожидающего прерывания будет считаться пробуждающим событием для команды WFE, даже если само по себе это прерывание замаскировано;
    • SLEEPONEXIT — если установлен, вызывает переход процессора в сон, если производится выход из последнего активного обработчика прерывания. Функционально аналогично исполнению сразу после возврата из последнего обработчика команды WFI;
    • SLEEPDEEP — когда установлен, разрешает переход в глубокий сон с большим временем возвращения к режиму работы, чем когда сброшен. В частности, при переходе в глубокий сон может быть автоматически выключен главный тактовый генератор. Точный смысл глубокого сна и его отличия от обычного сна определяются реализацией.

    Событиями, выводящими процессор из сна после выполнения команды WFE, являются:

    • сброс;
    • выполнение команды SEV на каком-либо другом процессоре многопроцессорной системы;
    • появление ожидающего прерывания, если установлен бит SEVONPEND регистра SCR;
    • появление асинхронного прерывания с более высоким групповым приоритетом, чем текущий приоритет «спящего» кода;
    • возникновение отладочного события, если отладка разрешена.

    Событиями, выводящими процессор из сна после выполнения команды WFI, являются:

    • сброс;
    • асинхронное прерывание с приоритетом, превышающим приоритет «спящего» кода без учёта маски PM (она в данном случае игнорируется);
    • отладочное событие, если отладка разрешена;
    • определяемые реализацией дополнительные события.

    Abort сбросить выполнение программы

    Обычно Abort Handler срабатывает, когда произошло некорректное обращение к данным (чтение или запись) — программа попыталась что-то сделать с данными по адресу, который не существует.

    При этом срабатывает исключение Data Abort, которое заставляет процессор ARM перейти по фиксированному адресу 0x00000010, где, в свою очередь, стоит безусловный переход в обработчик Abort_Handler. Например, по адресу 0x00000010 может быть команда LDR PC, [PC, #+20], загружающая в счетчик команд адрес из таблицы векторов переходов по исключению (адрес находится по смещению +20 относительно текущего счетчика команд. Назовем этот адрес меткой Abort Handler:). По этому месту компилятор ставит тупое зацикливание:
    Abort Handler:
    B Abort_Handler

    При срабатывании Abort Handler можно посмотреть, откуда это произошло (какой код вызвал ошибку). Для этого нужно в отладчике остановить выполнение программы (курсор текущего местоположения окна Disassembler должен показывать на Abort_Handler), и посмотреть содержимое регистра LR (Link Register — в нем сохраняется содержимое программного счетчика при вызове подпрограмм) — в нем будет находится адрес, где сработало исключение Data Abort.

    Несмотря на то, что есть такое удобное средство, чтобы выявить источник ошибки, иногда разобраться в ошибке бывает нелегко, особенно если она возникает случайно или в том месте, где работает чужой код. У меня такое произошло в обработчике прерывания, обслуживающее прерывание по изменению уровня на ножках ввода/вывода. Этот обработчик я взял из примеров IAR, так как там было очень удобно сделана обработка изменения уровней на отдельных ножках — для каждой ножки можно назначить свой обработчик. Вот код, который у меня вызывал Data Abort (pio_it.c):
    //——————————————————————————
    /// Handles all interrupts on the given PIO controller.
    /// \param id PIO controller ID.
    /// \param pBase PIO controller base address.
    //——————————————————————————
    void PioInterruptHandler (unsigned int id, AT91S_PIO *pBase)
    <
    unsigned int status;
    unsigned int i;

    // Check PIO controller status
    status = pBase->PIO_ISR;
    status &= pBase->PIO_IMR;
    if (status != 0)
    <
    trace_LOG(trace_DEBUG, «-D- PIO interrupt on PIO controller #%d\n\r», id);

    // Check all sources
    i = 0;
    while (status != 0)
    <
    // There cannot be an unconfigured source enabled.
    SANITY_CHECK(i

    Ошибка происходила случайно, и локализовать её обычными средствами не удавалось. Причина была в переполнении массива static InterruptSource pSources[MAX_INTERRUPT_SOURCES] (pio_it.c). У меня при задании нового источника прерывания количество прерываний numSources превышало MAX_INTERRUPT_SOURCES (стало 8, а MAX_INTERRUPT_SOURCES было равно 7), и происходило обращение к переменной вне массива (if (pSources[i].pPin-> >

    [Общая схема — как ловить ошибки при зависании Abort_Handler]

    1. В отладчике нужно посмотреть содержимое LR (адрес) — оттуда произошло зависание.
    2. В подпрограмме (которую находим по адресу в LR), где произошло зависание, нужно поставить условную точку останова. Условие останова нужно подобрать такое, при котором должно произойти зависание (чтобы оно сработало до зависания). После попадания в точку останова нужно изучить неверные параметры вызова функции, являющиеся причиной зависания. Потом нужно изучить код, который стал причиной появления таких неверных параметров.
    3. Если создать условие останова трудно (условие сложное), то подготавливают глобальные переменные, куда сохраняют все параметры исследуемой (вызывающей зависание) функции. После того, как произошло исключение Abort_Handler, изучают содержимое сохраненных параметров функции, и по их содержимому вычисляют причину ошибки.

    Системные прерывания | Аппаратное прерывание | Обработка прерываний

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

    Таблица 1.1. Классы прерываний

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

    Такое положение дел проиллюстрировано на рис. 1.5,а. Программа пользователя содержит ряд вызовов процедуры записи WRITE, в промежутках между которыми расположены другие команды. В отрезках 1, 2 и 3 находятся последовательности команд кода, в которых не используется ввод-вывод. При вызове процедуры WRITE управление передается системной утилите ввода-вывода, которая выполняет соответствующие операции. Программа ввода-вывода состоит из трех частей.

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

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

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

    Рис. 1.5. Ход выполнения программы без прерываний и с их использованием

    Из-за того что для выполнения операции ввода-вывода может потребоваться сравнительно длительный промежуток времени, программа замедляет работу, ожидая завершения операции. Таким образом, там, где встречается вызов WRITE, производительность программы существенно уменьшается.

    Прерывания и цикл команды

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

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

    С точки зрения программы пользователя, прерывания — это не что иное, как нарушение обычной последовательности исполнения. После завершения обработки прерывания работа возобновляется (рис. 1.6). Таким образом, программа пользователя не должна включать в себя какой-нибудь специальный код, чтобы приспосабливаться к прерываниям. За приостановку программы пользователя и возобновление ее работы с того самого места, в котором она была прервана, отвечают процессор и операционная система.

    Рис. 1.6. Передача управления через прерывание

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

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

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

    Рис. 1.7. Цикл команды с прерываниями

    Чтобы оценить выигрыш в эффективности, рассмотрим временную диаграмму (рис. 1.8), иллюстрирующую ход процессов, показанных на рис. 1.5,а и б. В ситуации, показанной на рис. 1.5,6 и 1.8, предполагается, что для выполнения операций ввода-вывода требуется сравнительно короткое время, т.е. меньшее, чем время обработки команд, которые расположены в программе пользователя между операциями записи. Более типичным, особенно для таких медленных устройств, как принтер, является случай, когда операции ввода-вывода занимают намного больше времени, чем требуется для выполнения последовательности команд пользователя. Такая ситуация показана на рис. 1.5,в. В этом случае программа пользователя дойдет до следующего вызова WRITE еще до завершения операции ввода-вывода, порожденной предыдущим вызовом. В результате в этом месте программа пользователя будет приостановлена. После завершения обработки предыдущей операции ввода-вывода придет очередь обработать новое обращение к процедуре WRITE, и будут запущены новые операции ввода-вывода. На рис. 1.9 представлена диаграмма выполнения программы в среде без прерываний и с прерываниями для описанного случая. Как видно, в такой ситуации выигрыш в эффективности все равно существует, так как часть времени, в течение которого выполняются операции ввода-вывода, перекрывается выполнением команд пользователя.

    Рис. 1.8. Временная диаграмма программы: быстрый ввод-вывод

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

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

    Устройство посылает процессору сигнал прерывания.

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

    а) без прерываний
    Рис. 1.9. Временная диаграмма программы: медленный ввод-вывод

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

    Рис. 1.10. Обработка простого прерывания

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

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

    • Содержимое программного счетчика и слово состояния прерываемой программы уже хранятся в системном стеке. Однако это еще не вся информация, имеющая отношение к состоянию исполняемой программы. Например, нужно сохранить содержимое регистров процессора, так как эти регистры могут понадобиться обработчику прерываний. Поэтому необходимо сохранить всю информацию о состоянии программы. Обычно обработчик прерываний начинает свою работу с записи в стек содержимого всех регистров. Другая информация, которая должна быть сохранена, обсуждается в главе 3, «Описание процессов и управление ими». На рис. 1.11,а показан простой пример, в котором программа пользователя прерывается после выполнения команды из ячейки N. Содержимое всех регистров, а также адрес следующей команды (N+1), в сумме составляющие М слов, заносятся в стек. Указатель стека при этом обновляется, указывая на новую вершину стека. Обновляется и программный счетчик, указывая на начало программы обработки прерывания.
    • Теперь обработчик прерываний может начать свою работу. В процесс обработки прерывания входит проверка информации состояния, имеющая отношение к операциям ввода-вывода или другим событиям, вызвавшим прерывание. Сюда может также входить пересылка устройствам ввода-вывода дополнительных инструкций или уведомляющих сообщений.
    • После завершения обработки прерываний из стека извлекаются сохраненные ранее значения, которые вновь заносятся в регистры, возобновляя таким образом то состояние, в котором они пребывали до прерывания (см., например, рис. 1.11,6).
    • Последний этап — восстановление из стека слова состояния программы и содержимого программного счетчика. В результате следующей будет выполняться команда прерванной программы.

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

    Множественные прерывания

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

    Рис. 1.11. Изменение памяти и регистров при обработке прерывания

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

    б) Вложенная обработка прерываний
    Рис. 1.12. Передача управления при множественных прерываниях

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

    При втором подходе учитывается приоритет прерывания, что позволяет приостановить обработку прерывания с более низким приоритетом в пользу прерывания с более высоким приоритетом (рис. 1.12,6). Как пример применения этого подхода рассмотрим систему с тремя устройствами ввода-вывода: принтером, диском и коммуникационной линией, которым присвоены приоритеты в возрастающей последовательности — 2, 4 и 5, соответственно. На рис. 1.13 показана очередность обработки прерываний, поступивших от этих устройств. Программа пользователя запускается в момент времени t = 0. В момент t = 10 происходит прерывание принтера. Информация о программе пользователя заносится в системный стек, и в действие вступает стандартная программа обслуживания прерывания (interrupt service routine — ISR). Во время ее работы в момент t = 15 происходит коммуникационное прерывание. Из-за того что его приоритет выше, чем приоритет прерывания принтера, процессор приступает к его обработке. ISR принтера прерывается, информация о ее состоянии заносится в стек, а управление передается коммуникационной ISR. Далее, пока эта программа выполняется, происходит прерывание диска (в момент времени t = 20). Так как его приоритет ниже, коммуникационная ISR продолжает свою работу, пока не закончит ее.

    Рис. 1.13. Пример последовательности обработки множественных прерываний [TANE90]

    После выполнения ISR коммуникационной линии (t = 25) восстанавливается предыдущее состояние процессора, т.е. работа с ISR принтера. Однако прежде чем успеет выполниться хоть одна команда этой программы, процессор приступает к обработке прерывания диска, которое обладает более высоким приоритетом, и управление передается ISR диска. Только после завершения этой программы (t = 35) возобновляет работу ISR принтера. И, наконец, после завершения обработки этого прерывания управление передается программе пользователя.

    Вернуться в оглавление:Операционные системы

    abort прерывать выполнение программы

    Copying entries

    Please select your target glossary

    Moving entries

    Please select your target glossary

    Language pair: английский => русский
    Discipline:
    Definition / notes: аварийно завершаться
    URL:

    Public glossaries

    My glossaries

    Copyright © 1999-2020 ProZ.com — All rights reserved. Privacy — Распечатать страницу

    You have native languages that can be verified

    You can request verification for native languages by completing a simple application that takes only a couple of minutes.

    Review native language verification applications submitted by your peers. Reviewing applications can be fun and only takes a few minutes.

    Илон Маск рекомендует:  Довольно предвзятая история HTML5
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL