Обсуждаем контроллеры компании Atmel.
Ответить

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Вт сен 26, 2017 08:52:40

Можно ради интереса и тренировки мозгов подумать как организовать вложенность прерываний на AVR. Хотя на практике это скорее всего будет ни к чему и рисует грабли на горизонте.

Предположим что есть три прерывания. Для примера пускай будут вектора что выложил knyaz*. Int0, ADC и Т0CompB. При том что последний по каким-то соображениям надо обслуживать всегда, даже если находишься в других обработчиках прерывания, а первые два не должны друг друга перебивать.

Думаю обрабтчики должны быть написаны на ассме.

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

Вроде должно работать, но такое чувство что что-то упустил. При написании проекта на ЯВУ, думается мне что вложенность лучше совсем не делать.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Вт сен 26, 2017 08:54:32

Всего - то разрешить вложенные прерывания установкой флага I в SREG сразу за входом в первую из процедур обработки.
8)

флаг I разрешает все прерывания, а не вложенные. В атмеге одноуровневая система прерываний


Вот как раз он и выполняет роль разрешения/запрета -
при входе в любое прерывание сбрасывается и по RETI восстанавливается АППАРАТНО.
Для разрешения вложенных прерываний этот флаг должен быть установлен программно (SEI) внутри исполнителя того прерывания, которое мы сочтем более "низкоуровневым".
Для атмег/тинек нет аппаратного контроллера приоритета (как в mcs51/PIC18), однако программное обеспечение подобного алгоритма никто не отменял.
8)
Можно еще "позаимствовать" метод определения вектора для прерываний от внешних устройств у Z80 (вектор предоставляет внешнее устройство при том, что используется всего одна линия прерывания для всех имеющихся).
:roll:
Последний раз редактировалось BOB51 Вт сен 26, 2017 09:01:46, всего редактировалось 1 раз.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Вт сен 26, 2017 08:59:48

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

ИМХО: не нужны вложенности на МК где они не предусмотрены.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Вт сен 26, 2017 09:07:53

ДЫК...
Ничего сверхестественного - весьма часто применяемо.
НО... в большинстве случаев...
Это удел ассемблера.
:hunger:

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 04:40:57

При наличии нескольких необработанных событий МК уйдёт в прерывание с более высоким приоритетом. Обработав его прмется за другое, если конечно за это время опять не произойдёт событие с высоким приоритетом. Как правило обработчик прерывания делается с максимально быстрым кодом.


а что становится с прерываниями с более низким приоритетом, когда они наполовину уже выполнились?? продолжит выполнятся с того места на котором их остановило прерывание с более высоким приоритетом?? или вовсе не выполнится? или выполнится заново после прерывания с высоким приоритетом?

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 06:41:39

fulky писал(а):

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

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 08:53:14

fulky писал(а):а что становится с прерываниями с более низким приоритетом, когда они наполовину уже выполнились?? продолжит выполнятся с того места на котором их остановило прерывание с более высоким приоритетом?? или вовсе не выполнится? или выполнится заново после прерывания с высоким приоритетом?

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

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 13:20:29

fulky писал(а):а что становится с прерываниями с более низким приоритетом, когда они наполовину уже выполнились?? продолжит выполнятся с того места на котором их остановило прерывание с более высоким приоритетом?? или вовсе не выполнится? или выполнится заново после прерывания с высоким приоритетом?

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

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 15:25:19

fulky писал(а):а что становится с прерываниями с более низким приоритетом, когда они наполовину уже выполнились?? продолжит выполнятся с того места на котором их остановило прерывание с более высоким приоритетом?? или вовсе не выполнится? или выполнится заново после прерывания с высоким приоритетом?

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


Спасибо, теперь всё стало ясно

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 15:40:45

knyaz* писал(а):Ну как то так, если в чем то не прав поправьте.

Для программирования на ЯВУ может и достаточно такого объяснения.Но лучше понимать аппаратную реализацию работу прерываний.

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

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

Тут кончено лучше на ассме попрогать немного, чтобы прочувствовать как это.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 16:02:19

RETI - return + установка флага I (interrupt).
RET - return без установки флага I (но и не сброс флага, если он установлен). Бывают ситуации, когда из прерывания нужно выйти, не включая прерывания. Тогда в обработчиках прерываний ставят эту команду.

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

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

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Чт сен 28, 2017 16:18:01

Demiurg писал(а):Возможно, что есть специальные директивы, указывающие ставить команду RET.
Помню что есть макрос прерывания для (gnu-avr) не сохраняющий контент. Кажется есть и макрос возврата по ret, не уверен.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Пт сен 29, 2017 06:58:39

Z_h_e писал(а):Помню что есть макрос прерывания для (gnu-avr) не сохраняющий контент
такого нет, но есть ISR(VECTOR, ISR_NACKED), что вынуждает программиста написать ВЕСЬ ОБРАБОТЧИК САМОМУ, включая сохранение и восстановление контекста.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Пт сен 29, 2017 07:00:53

Ну значит не совсем верно запомнил из-за невостребованности.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Вс окт 01, 2017 17:18:58

Можно ради интереса и тренировки мозгов подумать как организовать вложенность прерываний на AVR.


В AVR GCC какбэ уже есть директива ISR_NOBLOCK. Но пользоваться ей, особенно без опыта, я б не советовал, ибо
на практике это скорее всего будет ни к чему и рисует грабли на горизонте.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Вс окт 01, 2017 20:17:01

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

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Пн окт 02, 2017 10:33:24

Проблема вложенных прерываний в том, что теряется сам смысл прерываний.

Re: Вопрос к знатокам, почему не работают 2 прерывания совме

Пн окт 02, 2017 10:42:17

philosoraptor писал(а):Проблема вложенных прерываний в том, что теряется сам смысл прерываний.
???
Ответить