Обработка прерываний в MIPS-процессорах
Сегодня, дорогие мои, я расскажу вам про обработку исключений в процессорах MIPS-архитектуры. Но вначале - предисловие:
- Если вы считаете, что "только идиот будет рассказывать такие элементарные вещи" - что ж, простите, что не угодил вашему притязательному вкусу. Имею надежду, что это хоть как-то кому-то поможет.
- Все описанное - из личного опыта. Но из MIPS-архитектур довелось поработать только с процессорами серии "Мультикор". Это российские процы, подробнее - на http://multicore.ru/index.php?id=43 (не реклама!). Вообще-то они DSP, но управляющее ядро у них как раз MIPS32. К чему это я? Ах да, к тому, что все рассказанное ниже было испробовано только с этими процами и возможно, при работе с другими MIPS-совместимыми архитектурами надо будет что-то менять.
- Могу иногда быть некорректен, например в терминологии. В этом случае - с удовольствием принимаю поправки и предложения.
Итак, "от печки". В архитектуре MIPS32 реализован механизм исключений. По факту возникновения исключения процессор делает следующее:
- Переходит в режим обработки исключения выставлением бита в регистре Status сопроцессора CP0. При этом прерывания запрещаются.
- Совершается переход на адрес обработчика исключения. В отличие от других архитектур, у MIPS нет таблицы векторов прерываний. То есть, в зависимости от конкретного исключения адрес перехода может варьироваться, но так или иначе это конечное число адресов, причем небольшое. Пример: в процессорах "мультикор" обработчик прерывания от таймера должен находиться по адресу 0xBFC0_0380 или 0x8000_0180. Какой именно это адрес - определяется битом в регистре Status сопроцессора CP0. Переназначить адрес обработчика на какой-нибудь 0x1234_5678 - нельзя. Адрес, на котором мы находились перед исключением, сохраняется в регистр EPC сопроцессора CP0.
- Процессор исполняет инструкции, расположенные по адресу обработчика. Долго исполняет. До тех пор, пока ему не встретится команда ERET. По исполнению этой команды процессор переходит в обычный режим (из режима обработки исключения) и возвращается на адрес, сохраненный в EPC.
Это общий алгоритм. Более подробно уже надо смотреть в даташите на конкретный процессор.
Теперь немного о классификации исключений. Это может быть исключение по ошибке адресации - когда мы обращаемся в тот адрес, в который по каким-то причинам обращаться нельзя. Это может быть исключение по "незнакомой команде" - когда процу попадается незнакомый опкод - например при неправильном переходе, когда проц попадает не на программу и на данные. Исключение по точке останова, и прочее, и прочее. Среди всех этих типов стоит выделить так называемое исключение прерывания. Это то, что в остальных процессорах называется просто прерыванием.
Исключение прерывания - это то исключение, которое возникает при возникновении прерывания от любого устройства процессора - будь это таймер, порт ввода-вывода или, например, DSP-ядро. То есть, еще раз: неважно, от чего прерывание - от таймера, от UART, от другого порта, от DMA, или же это внешнее прерывание - переход будет на один и тот же адрес. И определять, от какого устройства это прерывание возникло - надо программно. Это отличается от привычной (для меня) по AVR и x86 системы, но в этом есть своя прелесть.
В итоге, чтобы использовать прерывания, от программиста требуется:
- Написать обработчики.
- Разместить обработчики по векторам используемых исключений.
- Разрешить прерывания.
Дисклаймер: дальше речь пойдет только про обработку именно исключения прерывания. Обработка других исключений, в общем-то, слабо отличается.
Что должен делать обработчик.
- Определить "причину" исключения.
- Сделать непосредственно обработку - это уже зависит сугубо от целевой задачи.
- "Устранить" причину исключения и выполнить ERET.
Не упоминаю о такой мелочной вещи, как сохранение используемых регистров и восстановления "как было" - но это, естественно, надо сделать.
Итак, определение "причины". В первую очередь, надо анализировать регистр Cause сопроцессора CP0. В нем есть поле, которое называется ExcCode. Если оно равно 0 - это исключение прерывания. Для остальных типов исключений - свое значение.
Далее нам необходимо понять, откуда это прерывание - от внутренних устройств проца, или же внешнее? Для этого дальше читаем регистры Cause и Status. Поля в них называются IP[7:0] и IM[7:0] соответственно. Поле IP - это запросы прерывания, а IM - маска. Биты IP[1:0] - это программные прерывания. Они выставляются записью непосредственно в это поле. IP[5:2] - это биты, соответствующие прерываниям nIRQ[3:0]. И бит IP[7] - это бит, объединяющий прерывания от всех внутренних устройств по ИЛИ - то есть, этот бит однозначно сигнализирует о прерывании от накристалльного устройства. Разумеется, при условии, что это прерывание разрешено в поле IM регистра Status.
В случае, если это программное или внешнее прерывание - "причина" однозначно установлена и можно приступать непосредственно к обработке. Если же это прерывание от внутреннего устройства - необходимо анализировать регистры QSTR и MASKR. В первом, согласно названию, отображаются запросы прерывания, а во втором - их маски. Соответственно, если какой-то бит в обоих регистрах выставлен в единицу - значит, прерывание от соответствующего устройства разрешено и активно.
После этого, опять же, можно приступать к обработке прерывания.
- блог пользователя lost_embedder
- 23558 просмотров
Новые записи в блогах
- Устранение дребезга контактов на основе вертикальных счетчиков
- Диагностика Imprecise Bus Faults в микроконтроллерах Cortex-M3/M4/M4F
- Self-powered камера
- Фоновый модулятор: беспроводная связь из ничего (перевод)
- Texas Instruments Analog Applications Journal SLYT612 "Снижение искажений в аналоговых КМОП ключах" (перевод)
- USB MSD. Часть 6. Команды SCSI (перевод)
- USB MSD. Часть 3. USB класс накопителей данных (перевод)
- Texas Instruments Application Report SBAA042 "Кодовые схемы, используемые в аналогово-цифровых преобразователях" (перевод)
- 10 принципов правильного интерфейса
- Релиз SDK на русский микропроцессор КРОЛИК
Recent comments
2 недели 17 часов назад
2 недели 1 день назад
5 недель 6 дней назад
7 недель 18 часов назад
5 лет 45 недель назад
6 лет 8 недель назад
6 лет 18 недель назад
6 лет 20 недель назад
6 лет 28 недель назад
7 лет 2 дня назад