Возврат из прерывания в месте, отличном от того, где произошло прерывание. (PIC16F877A)

Есть ли способ вернуться из прерывания в другое место, где произошло прерывание в Microchip PIC16F877A?

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

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

Почему бы не получить следующую инструкцию после того, как ISR отправит вас туда, куда вы хотите?
Потому что я не знаю, какая следующая инструкция после ISR. Это зависит от того, где находился счетчик программ в момент прерывания.
К сожалению, серия PIC16 не дает вам доступа к регистрам стека, поэтому у вас нет возможности манипулировать адресом возврата. Если вам действительно нужна эта функциональность, вам придется перейти на PIC18.
Что именно вы пытаетесь сделать?
Вы не можете делать то, о чем просите на этом PIC, но это звучит как деталь реализации, которую вы вообразили, а не ваша истинная проблема. Это также звучит как неуклюжая программная архитектура, если вы хотите это сделать.

Ответы (2)

Вы правы, PIC до PIC18 не давали возможности изменить вершину стека.

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

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

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

См. AN818 Управление стеком микроконтроллера PIC18, чтобы узнать, как изменить адрес возврата. Обратите внимание, что это документ PIC18.

К сожалению, ПОДУМАЙТЕ, что PIC на это не способен.

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

Есть ли способ принудительно выполнить RESET?

Привет, гбулмер! Я пытался найти способ изменить вершину стека, чтобы избежать упомянутой вами худшей альтернативы. Но если нет возможности манипулировать стеком, у меня не будет выбора.
@stdio.h - я очень сочувствую. Желание сделать это вполне разумно. Много лет назад мой приятель написал что-то вроде основного переключения задач для ОС реального времени на C++, где всего около 4 строк ассемблера для управления указателем стека и выполнения этой замены стека. Это была просто библиотека, которая работала внутри обычного процесса. Я полагаю, нет никакого способа обновить MCU?
Это студенческое задание. Я думаю, мой учитель скажет мне, что лучше написать плохой код, чем обновлять MCU в реальных жизненных ситуациях. Но я действительно склонен обновлять MCU, потому что ненавижу проверять флаги во всем своем коде. Это похоже на быстрое решение.

Нет, то, о чем вы просите, невозможно и нелогично.

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

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

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

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

Семейство PIC16F87XA имеет 8-уровневый аппаратный стек шириной 13 бит. Пространство стека не является частью ни программы, ни пространства данных, а указатель стека недоступен для чтения или записи. PC помещается в стек, когда выполняется инструкция CALL или прерывание вызывает переход. Стек выталкивается в случае выполнения инструкции RETURN, RETLW или RETFIE. На PCLATH не влияют операции PUSH или POP.