Что такое внешние прерывания
Внешние, внутренние и программные прерывания
2. Внешние, внутренние и программные прерывания.
Прерывания возникающие при работе выч. системы можно разделить на внешние и внутренние. Внешние прерывания вызываются асинхронными событиями, которые происходят вне прерываемого процесса. Пример – прерывание от таймера, прерывание от внешних устройств, прерывание по вводу/выводу, прерывание по нарушению питания, прерывание с пульта оператора, прерывание от другого процессора или другой ОС.
Внутренние прерывания вызываются событиями, которые связаны с работой процессора и являются синхронными с его операциями. Например: при нарушении адресации (когда указан запрещенный или несуществующий адрес) либо обращение к отсутствующему сегменту или странице при организации виртуальной памяти; при наличии в поле кода операции незадействованной 2ичной комбинации; при делении на 0; при переполнении или исчезновения порядка; при обнаружении ошибок четности, ошибок в работе различных устройств аппаратуры средствами контроля.
Программные прерывания. Эти прерывания происходят по соответствующей команде прерывания т. е. по этой команде процессор осуществляет те же действия, что и при обычных внутренних прерываниях. Данный механизм был специально введен для того, чтобы переключение на системные программные модули происходило не просто как переход на подпрограмму, а точно таким же образом как и в обычных прерываниях. Этим обеспечивается автоматическое переключения процессора в привилегированный режим с возможностью исполнения любых команд. Сигналы, вызывающие прерывания, формируются вне процессора или в самом процессоре, при этом возникать они могут одновременно. Выбор одного из них для обработки осуществляется на основе приоритета, приписанных к каждому типу прерывания. Учет приоритета прерывания может быть встроен в технические средства, а также определяться ОС.
Распределение прерываний по уровням приоритета:
Средства контроля CPU | Высший приоритете |
Системный таймер | |
Магнитные диски | |
Сетевое оборудование | |
Терминалы | |
Программные прерывания | Низший приоритете |
3. Изобразить диаграмму состояния процесса. Пояснить все возможные переходы из одного состояния в другое.
За время своего существования процесс может осуществить переход из одного состояния в другое. Это обусловлено обращениями к ОС с запросами ресурсов и выполнением системных функций, которые предоставляют ОС взаимодействие с другими процессами, появлением сигналов прерывания от таймера и устройств ввода/вывода. Процесс из состояния бездействия может перейти в состояние готовности в следующем случае:
1 По команде оператора или пользователя, ОС где программа может иметь статус задачи и при этом являться пассивной, а не просто быть исполняемой файлами и только на время исполнения получать статус задачи это характерно для большинства современных ОС.
2 При выборе из очереди на выполнение процесс может перейти от бездействия к готовности. Это характерно для ОС работающих в постоянном режиме.
3 По вызову из другой задачи. По вызову супервизора один процесс может создать, инициировать, приостановить, остановить и уничтожить любой процесс. От прерывания от внешнего устройства. устройства называют инициатором, если по сигналу на прерывание от него должна запустится акая-то задача.
Переход в готовность при поступлении запланированного запроса программы. процесс, который может исполняться или только ему будет предоставлен процессор находится в состоянии готовности. Уже выделены все необходимые ресурсы за исключением процессора.
Из состояния выполнения процесс может выйти по одной из следующих причин:
1 Процесс завершается, при этом он посредством обращения к супервизору передает управление ОС и сообщает ей о своем завершении. В результате их действий супервизор либо переводит его в список бездействующих процессов либо уничтожает. В состояние бездействия процесс может быть переведен принудительно по команде оператора. Действие этой команды реализуется системными процессами. которые транслируют запрос супервизору с требованием перевести соотв. процесс в состояние бездействия.
Из состояния выполнения процесс переводится в состояние готовности к выполнению в связи с появлением более приоритетной задачи или в связи с окончанием выделенного этому процессу кванта времени. Либо вследствие запроса операции ввода/вывода, который должен быть выполнен прежде чем процесс может продолжить исполнение либо в силу невозможности предоставить ему ресурс запрошенный в настоящий момент. При поступлении соответствующего сигнала о завершении операции ввода/вывода, освобождающем требуемый ресурс, в оперативную память загружается необходимая страница виртуальной памяти. Процесс деблокируется и переводится из состояния готовности к исполнению. Итак, движущей силой, меняющей состояния процессов, является механизм прерываний.
AVR Урок 42. EXINT или внешние прерывания
Урок 42
EXINT или внешние прерывания
Вот наконец-то и настало время нам попробовать поработать с внешними прерываниям. Данный урок, во-первых, был очень востребован, хотя он и кажется на первый взгляд несложным. Очень много было просьб и я не мог не откликнуться. Во-вторых, мы сейчас работаем с модулем LAN ENC28J60, у которго имеется выход, по которому мы можем получить прерывания по окончании определённых операций, которые я и хотел обработать. Также, если у меня получится, я хотел этим поделиться и с вами, но без первоначального представления о внешних прерываниях в контроллере AVR это понять, я считаю, будет, мягко говоря, нелегко. Вот поэтому и созрел данный урок.
Так как я случайно залочил свой контроллер ATMega328, расположенный на недорогой плате, то работать мы будем с платой Arduino UNO.
Нет, не пугайтесь, мы не будем работать со средой программирования Arduino IDE, мы также будем работать с тем же самым Atmel Studio, только Arduino мы будем использовать в качестве отладочной платы и будем его программировать через разъём ISP.
Так что вы можете использовать по-прежнему любые отладочные платы. Но если вдруг кто-то решит использовать так же, как и я, Arduino UNO или любую другую Arduino, то предупреждаю заранее – после этого уже работать с ней Вы не сможете через стандартную среду программирования – Arduino IDE, так как загрузчик мы в случае прошивания через ISP затираем. Но это не смертельно, так как его можно будет впоследствии восстановить. Правда это занятие не из лёгких, но если есть интерес к восстановлению загрузчиков Arduino после их затирания программированием через ISP, то я могу по этому поводу написать статью и дать видеоурок.
Вообщем, пока не приедут платы более мелкие, я буду свои уроки писать с применением Arduino UNO, также и с модулем LAN я также буду работать с той же платой.
Также чем оказался хорош Arduino, что к нему не требуется переходник TTL-USB, так как он там уже прекрасно аппаратно реализован. Причём, мало того, мы через штатный USB-разъём Arduino не только будем пользоваться USART-ом, но и питать наш Arduino будем через него же.
В качестве программатора мы также будем использоваь дешёвый USBASP. Так как он у меня с переключателем пиания 3,3В/5В, то убрав с него совсем перемычку, мы вообще отключим питание с программатора на плату и будем через ISP исключительно только программировать нашу плату.
Так как на плате Arduino находится 6-контактный разъём ISP, то будем использовать стандартный ISP-переходник
После подключения программатора к плате мы получим вот такую картину
Подключим раъём USB к компьютеру – теперь у нас есть готовый выход USART на ПК, а также и питание
Вернёмся к нашим прерываниям. Внешние прерывания – это такие прерывания, которые обрабатываются вследствие возникновения некоторых событий на определённой ножке порта микроконтроллера. Таких событий существует несколько. Прерывания у контроллера AVR могут срабатывать как по уровню, так и по фронту. По уровню они срабатывают, когда будет замечен определённый логический уровень. То есть, если будет настроено срабатывание по уровню логической единицы, то если данный уровень будет оставаться на ножке внешнего прерывания, то прерывание будет срабатыать циклично, пока не установится другой логический уровень. А по фронту – когда будет замечен переход из одного логического состояния в другое. Фронт, как известно бывает восходящий или нисходящий. Говорят ещё вместо восходящего просто фронт, а вместо нисходящего – спад. Также ещё называют передний и задний фронт. Вообщем – это кому как удобно.
Ножек для отслеживания внешних прерываний у контроллера существует две – INT0 и INT1. Первая ножка совпадает с ножкой порта PD2, а вторая – с PD3
Теперь немного по аппаратной организации внешних прерываний. Вышеуказанные ножки назначены по умолчанию, но их можно и менять. Для этого есть в контроллере определённые регистры. Но данная тема сегодня рассматриваться не будет, мы будем работать именно с ножками вышеуказанными, поэтому и регистры мы рассмотрим только нужные нам.
Первый регистр – это регистр управления типом обрабатываемого события – EICRA
Пара битов ICS01 и ICS00 управляет типом событий на ножке INT0, а вторая – ICS11 и ICS10 – INT1
Вот зависимость типов событий от включения битов ICS01 и ICS00
А это для ICS11 и ICS10
Соответственно получим мы следющую зависимость:
00 – Низкий уровень на ножке,
01 – Любое изменение на ножке,
10 – нисходящий фронт на ножке,
11 – восходящий фронт на ножке.
Второй регистр – это регистр включения ножки прерываний EIMSK
В данном регистре существует всего два бита, разрешающих прерывания на соответствующих ножках – INT1 и INT0. Биты так и называются, поэтому не перепутаем.
Третий регистр – регистр флагов EIFR, устанавливаемых и сбрасываемых при определённых событиях
Напрямую мы к данному регистру не обращаемся, так как работать будем с функцией-обработчиком.
Теперь вроде что-то прояснилось по вопросу внешних прерываний.
Осталось дело за малым. Создать и прошить проект, который будет как-то наглядно демонстрировать работу внешних прерываний.
Запустим Atmel Studio 7, создадим проект с именем EXTI01, выберем контроллер ATmega328P, добавим в main.c функцию инициализации портов port_ini, в которой включим ножку светодиода на выход. Светодиод на плате располагается на ножке B6
void port_ini ( void )
//Включим ножку светодиода на выход
DDRB |= 0b00100000;
Вызовем данную функцию в main()
int main ( void )
port_ini ();
while (1)
Подключим кнопку между ножкой PD2 (D2) и общим проводом
Вернёмся в проект и напишем функцию инициализации внешних прерываний. Настроим нисходящий фронт, так как резистор для исключения неопределённого состояния на ножке мы можем подтянуть программно только к питанию и у нас в обычном состоянии на ножке будет логический 1
void int_ini ( void )
//включим прерывания INT0 по нисходящему фронту
EICRA |= (1 ISC01 );
//разрешим внешние прерывания INT0
EIMSK |= (1 INT0 );
Вызовем данную функцию в main(), а также не забываем включить глобальные прерывания
int_ini ();
sei ();
Давайте ещё на всякий случай настроим данную ножку на вход и подтянем резистор к питанию. В данной ситуации лучше резистор подтянуть, так как может возникнуть неопределённое состояние. Для этого добавим соответствующий код в функцию port_ini
//Включим ножку INT0 (PD2) на вход
//Подтянем резистор на ножке INT0 (PD2) к питанию
PORTD |= 0b00000100;
Также ещё нам необходимо добавить сам обработчик прерывания, в котором мы по возникновению настроенного события на ножке порта будем зажигать наш светодиод
ISR ( INT0_vect )
PORTB |= 0b00100000;
Соберём код, прошьём контроллер и попробуем нажать кнопку
Как мы видим, светодиод у нас загорелся.
Теперь давайте попробуем также испытать и другую ножку – INT1.
Для этого сначала настроим данную ножку в port_ini()
//Включим ножки INT0 и INT1 (PD2 и PD3) на вход
(0b00001100);
//Подтянем резисторы на ножках INT0 и INT1 (PD2 и PD3) к питанию
PORTD |= 0b00001100;
Затем перенастроим прерывания с учётом данной ножки и в функции int_ini()
//включим прерывания INT0 и INT1 по нисходящему фронту
EICRA |= (1 ISC11 )|(1 ISC01 );
//разрешим внешнее прерывание INT0 и INT1
EIMSK |= (1 INT1 )|(1 INT0 );
А вот обработчик у данной ножки свой отдельный, поэтому добавим его и светодиод в нём будем гасить
ISR ( INT1_vect )
Теперь мы можем подключить ещё кнопку на ножку PD3 (D3), воторым проводм также подключив её к общему проводу, собрать код, прошить контроллер и понажимать кнопки и отследить результаты изменения уровней по светодиоду
Теперь, если мы соберём код и прошьём контроллер, то первая кнопка будет у нас светодиод зажигать, а вторая тушить.
Казалось бы, что тут такого? А то, что происходит это уже независимо от хода самой программы, не в бесконечном цикле, когда во время там написанного обработчика по нажатию кнопки мы можем вообще не находиться и будет уже не ясно, обработается ли наше событие. Поэтому, изучив внешние прерывания, мы сделали большой шаг вперёд к независимости обработки тех или иных событий на ножках портов микроконтроллера. Конечно, учитывая наш уже теперь очень богатый опыт, нам было это проделать не очень тяжело.
Приобрести плату Arduino UNO R3 можно здесь.
Смотреть ВИДЕОУРОК (нажмите на картинку)
Электроника для всех
Блог о электронике
ARM. Учебный курс. Внешние прерывания
Внешние прерывания активизируются по изменению логического уровня на ноге контроллера. Удобно для обработки срочных событий от внешней периферии, иногда на них делают обработку кнопок. Т.к. они могут будить контроллер из глубокой спячки.
У STM32 за внешние прерывания отвечает EXTI контроллер. Его основные возможности:
До 20 линий прерываний (в реальности несколько меньше, зависит от контроллера)
Независимая работа со всеми линиями. Каждой линии присвоен собственный статусный бит в спец регистре
Улавливает импульсы длительность которых ниже меньше периода частоты APB2
EXTI Может генерировать:
Сама структура связи EXTI следующая:
Т.е. у нас есть 16 EXTI линий к которым мы можем подключать выводы порта. Причем группируются они по номерам пинов. Т.е. мы не можем на разные прерывания навесить, например, PA0 и PB0 либо одно, либо другое. Придется выбирать. Мультиплексоры управляются из группы регистров AFIO_EXTICR*.
Кстати, интересный факт. Даташит утверждает следующее:
Т.е. для записи в регистры AFIO_EXTICRx должно быть включено тактирование AFIO. Проверил без него — все работает, значения записываются, прерывания работают. Может я где то ошибся? Прогнал под JTAG в Keil — нет, AFIO CLOCK Disabled, а все работает. Странно.
Но после выяснилось, что без включения AFIO мультиплексоры не работают. Т.е. сигнал будет передаваться ТОЛЬКО от порта А, т.к. это дефолтное значение мультиплексоров. Причем вне зависимости от того, что вы там себе настроили в программе. Прикиньте какие грабли! Забыл включить AFIO и привет! Ладно бы прерывания тупо не работали, а они будут работать, но совсем не от того вывода который вы выставили. А если там что-то дрыгается, то прерывание у вас срабатывать будет, но совсем не тогда, когда вы ждете. Попробуйте выловить такую фигню!
Так что AFIO надо включать до выбора канала мультиплексора! У меня же все работало потому, что выбранные линии порта совпали с портом А, стоящим по умолчанию. ВСЕГДА затактирывайте AFIO если используете альтернативные функции портов, избежите кучи глюков.
Есть еще четыре EXTI линии которые подключены не к GPIO, а к разной периферии.
● EXTI 16 — PVD выход
● EXTI 17 — событие от RTC Alarm
● EXTI 18 — событие от USB Wakeup
● EXTI 19 — событие от Ethernet Wakeup (там где есть эзернет на борту)
EXTI_IMR — Регистр масок прерываний. Единичка в этом регистре в соответствующем бите разрешает прерывание на соответствующий канал EXTI. После сброса там нули. Т.е. все прерывания внешние локально запрещены.
EXTI_EMR — Регистр масок событий. Единичка тут разрешает событие на канал. События отличается от прерывания тем, что контроллер только сигнализирует о нем, но никуда, ни по какому вектору, не бежит выполнять код. Еще события умеют чуять некоторые периферийные устройства.
EXTI_RTSR и EXTI_FTSR — Регистры определяющие когда срабатывать. По какому фронту? Единичка в EXTI_RTSR даст событие по восходящему фронту, а единичка в EXTI_FTSR по спадающему. Можно поставить оба бита и ловить прерывание на подъеме и спаде.
EXTI_SWIER — Регистр софтверного запуска прерывания.
Т.е. если нам надо вручную, принудительно, его запустить, то надо сюда записать в конкретный бит. Записываем в EXTI_SWIER 1 и у нас вскакивает бит в EXTI_PR, а контроллер генерирует событие и, если разрешено, уходит на прерывание.
EXTI_PR — Ну и бит собственно флажка события, по которому происходит вызов прерывания. Обратите внимание на обозначение обращения с ним — rc_w1. Это следует читать как read/clear = write 1. Т.е. мы этот бит можем читать, а чтобы его сбросить надо в него записать единичку. Как на AVR прям 🙂 При переходе в прерывание его надо сбрасывать вручную! Иначе на выходе с прерывания будет «и снова здравствуйте!».
Теперь покажу пример кода работы с прерыванием. Отдельный пример создавать мне лень, возьму кусок кода из прошлого примера про NVIC там как раз были внешние прерывания:
(GPIO_CRL_CNF5 | GPIO_CRL_CNF1 | GPIO_CRL_CNF0); // Выставляем режим для 0,1,5 пина. Режим MODE 01 = Max Speed 10MHz Ставим нулевой бит MODE GPIOB->CRL &=
(GPIO_CRL_MODE5 | GPIO_CRL_MODE1 | GPIO_CRL_MODE0); // Занулим заранее GPIOB->CRL |= GPIO_CRL_MODE5_0 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE0_0; // Выставим бит 0 // Настройка входных портов. Те что на кнопки. // Конфигурируем CRL регистры. // Выставляем режим порта в CNF для битов 1,2 Режим 10 = PullUp(Down) Ставим первый бит CRL GPIOA->CRL &=
(GPIO_CRL_CNF1 | GPIO_CRL_CNF2); // Занулим заранее GPIOA->CRL |= GPIO_CRL_CNF1_1 | GPIO_CRL_CNF2_1; // Выставим бит 1 // Выставляем режим для 1,2 пина. Режим MODE_00 = Input GPIOA->CRL &=
Вот, собственно, и все. Ничего сложного.
Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!
А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.
31 thoughts on “ARM. Учебный курс. Внешние прерывания”
Здравствуйте.
А будет ли урок по отладке с помощью CoLinkEX?
Что такое внешние прерывания
Система прерываний 32-разрядных микропроцессоров i 80 x 86.
Работа системы прерываний в реальном режиме
1. Понятие прерывания
2. Классификация прерываний
3. Система прерываний.
· Программные средства системы прерываний
· Таблица векторов прерываний
4. Обработка прерывания в реальном режиме
Прерывание означает временное прекращение основного процесса вычислений для выполнения некоторых запланированных или незапланированных действий, вызываемых работой аппаратуры или программы.
Т.е. это процесс, временно переключающий микропроцессор на выполнение другой программы с последующим возвратом к прерванной программе.
Нажимая клавишу на клавиатуре, мы инициируем немедленный вызов программы, которая распознает клавишу, заносит ее код в буфер клавиатуры, из которого он считывается другой программой. Т.е. на некоторое время микропроцессор прерывает выполнение текущей программы и переключается на программу обработки прерывания, так наз. обработчик прерывания. После того, как обработчик прерывания завершит свою работу, прерванная программа продолжит выполнение с точки, где было приостановлено ее выполнение.
Адрес программы-обработчика прерывания вычисляется по таблице векторов прерываний.
Механизм прерываний поддерживается на аппаратном уровне.
В зависимости от источника, прерывания делятся на
Общая классификация прерываний
Внешние прерывания возникают по сигналу какого-нибудь внешнего устройства.
Внешние прерывания подразделяются на немаскируемые и маскируемые.
Маскируемые прерывания генерируются контроллером прерываний по заявке определенных периферийных устройств. Контроллер прерываний (выполнен в виде специальной микросхемы i8259A) поддерживает восемь уровней (линий) приоритета; к каждому уровню “привязано” одно периферийное устройство. Именно маскируемые прерывания часто называют аппаратными прерываниями.
В ПК, начиная с IBM PC AT, построенных на базе микропроцессора i80286, используются два контроллера прерываний i8259A; они соединяются последовательно каскадным образом, что увеличивает количество внешних источников прерываний до 15 (каждая по 8).
Немаскируемые прерывания (говорят, что оно одно, т.к. подается на вывод микропроцессора NMI ) инициируют источники, требующие безотлагательного вмешательства со стороны микропроцессора.
В реальном и защищенном режиме работы микропроцессора обработка прерываний осуществляется принципиально разными методами.
Система прерываний. Аппаратные и программные средства системы прерываний
К аппаратным средствам системы прерываний относятся:
· программируемый контроллер прерываний 8259А (предназначен для фиксирования сигналов прерываний от восьми различных внешних устройств; он выполнен в виде микросхемы; обычно используют две последовательно соединенные микросхемы, поэтому кол-во возможных источников внешних прерываний до 15 плюс одно немаскируемое прер.; именно он формирует номер вектора прерывания и выдает его шину данных);
· внешние устройства (таймер, клавиатура, магнитные диски и т.п.)
К программным средствам системы прерываний Реального режима относятся:
Таблица векторов прерываний инициализируется при запуске системы, но в принципе может быть изменена и перемещена.
Каждый вектор имеет свой номер и называется номером прерывания.
· два флага в регистре флагов flags/eflags :
Обработка прерывания в реальном режиме
производится в три этапа:
1) прекращение выполнения текущей программы;
Должно произойти так, чтобы потом вернуться и продолжить работу. Для этого необходимо сохранить содержимое регистров, так как они являются ресурсами, разделяемыми между программами.
Наиболее удобным местом хранения регистров является стек.
2) переход к выполнению и выполнение программы обработки прерывания;
Здесь определяется источник прерывания и вызывается соответствующий обработчик прерывания.
смещение эл-та таблицы векторов прерываний = N * 4
Итак на втором этапе микропроцессор
1. По номеру источника прерывания определяет смещение в таблице векторов прерываний
2. Помещает первые два байта в регистр IP
3. Помещает вторые два байта в регистр CS
4. Передыет управление по адресу CS:IP
Далее выполняется сама программа обработки прерывания.
(Она тоже может быть прервана поступлением запроса от более приоритетного источника. Все источники прерывания имеют приоритеты.)
3) возврат управления прерванной программе.