AVR - это архитектура RISC, поэтому он имеет довольно простую аппаратную обработку прерываний. Большинство процессоров связываются со стеком во время прерываний, хотя есть пара, особенно ARM и PowerPC, которые используют разные методы.
В любом случае, это то, что AVR делает для прерываний:
При возникновении прерывания аппаратное обеспечение процессора выполняет следующие действия, которые не являются простым GOTO:
- Завершите текущую инструкцию.
- Отключить глобальный флаг прерывания.
- Вставьте адрес следующей инструкции в стек.
- Скопируйте адрес в правильном векторе прерывания (в соответствии с возникшим прерыванием) в программный счетчик.
Теперь на этом этапе оборудование сделало все, что оно собирается сделать. Программное обеспечение должно быть написано правильно, чтобы не сломать вещи. Как правило, следующие шаги идут по этим направлениям.
Вставьте регистр состояния в стек. (Это должно быть сделано в первую очередь, прежде чем он будет изменен).
Вставьте любые регистры процессора, которые будут (или могут быть) изменены в стек. Какие регистры, которые необходимо сохранить таким образом, определяются моделью программирования. Модель программирования определяется компилятором.
Теперь рабочий код прерывания можно запустить. Чтобы ответить на вопрос о вызове функции, она просто делает то, что всегда делает, помещает возвращаемое значение в стек, а затем возвращает его обратно, когда все готово. Это не влияет ни на одно из этих предыдущих значений, которые мы сохраняли в стеке до сих пор.
- Запустите ISR рабочий код.
Теперь мы закончили и хотим вернуться от прерывания. Сначала мы должны сделать очистку программного обеспечения.
- Вставьте регистры процессора, которые мы выдвинули на шаге 6.
- Вставьте сохраненное значение статуса обратно в регистр состояния. После этого мы должны быть осторожны, чтобы не выполнять никаких инструкций, которые могли бы изменить регистр состояния.
Выполните инструкцию РТИ. Аппаратное обеспечение выполняет эти шаги для этой инструкции:
а. Включить глобальный флаг прерывания. (Обратите внимание, что, по крайней мере, одна инструкция должна быть выполнена до того, как будет выполнено следующее прерывание. Это препятствует тому, чтобы тяжелые прерывания полностью блокировали фоновую работу.)
б. Вставьте сохраненный обратный адрес в ПК.
Теперь мы вернулись к нормальному коду.
Обратите внимание, что есть некоторые моменты, в которых мы должны быть очень осторожны, особенно в отношении регистра состояния и сохранения регистров, которые могут быть изменены. К счастью, если вы используете компилятор C, все это обрабатывается под прикрытием.
Кроме того, вы должны следить за глубиной стека. В любой момент, когда разрешены прерывания, ISR может использовать больше стека, чем очевидно, если посмотреть на локальный код. Конечно, это мало что дает, если вы не используете свою память до предела.
Вот ссылка, описывающая этот процесс, если вы хотите ссылку.