Передача управления из прерывания в функцию.

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

Как сделать так, чтобы в прерывании передать управление в функцию, но чтобы произошел выход из обработчика прерывания? То есть, как разумно вызвать функцию из обработчика?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

а зачем это? чтобы могло произойти другое прерывание?
Ставим плюсы: )
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

Нет, скажем, чтобы сделать будильник. Время совпало с временем будильника(время считается таймером) и опа-идем в функцию будилки и из прерывания выходим.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

А вне прерывания, когда программа освободится от других задач, нельзя сравнивать время с установленным ? Или если программа задержится на пару-тройку миллисекунд (да хоть на секунду), то человек проспит на работу ?
100 раз обсуждалось подобное на форуме, вывод один - если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы. Любую задачу можно решить без подобных финтов.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

Основное время работы программа занята опросом кнопки и выводом текущего времени. Как-то не хочется прописывать в каждой функции(вывод времени, даты) условие срабатывания будильника. В прерывании легче было бы.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Это на какой же частоте у Вас работает процессор, если кроме опроса кнопок и вывода информации на дисплей ни на что не остаётся процессорного времени ?
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

Я не про это...Если делать, как говорите вы, то мне придется в каждую функцию вписывать проверку времени будилки. А функции связаны так:

Код: Выделить всё

void Func1()
{
while(1)
{
if(....)
{
Func2();
break;
}
.......
}
}
void Func2()
{
while(1)
{
if(....)
{
Func3();
break;
}
.....
}
}
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

мне придется в каждую функцию вписывать проверку времени будилки
Зачем ? Программа из этих функций не возвращается что-ли никогда ? Прошла по всем всем функциям и зашла в функцию проверки будильника.
Что там за функции такие, которые тратят всё процессорное время ? Откройте секрет...
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

А теперь представьте, пусть последняя функция это Func4(). А если программа висит в Func2? И опрашивает кнопки?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

А если программа висит в Func2? И опрашивает кнопки?
Вы сейчас прикалываетесь или издеваетесь ? :) Сколько нужно тактов, что бы опросить кнопку ?
Задам ещё раз свой вопрос
Это на какой же частоте у Вас работает процессор, если кроме опроса кнопок и вывода информации на дисплей ни на что не остаётся процессорного времени ?
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

Работает на 10 MHz. А теперь посмотрите код выше. while(1) ни на какие мысли не наводит?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

ни на какие мысли не наводит?
Наводит, о чём я уже говорил выше :
если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы
Не наводит ни на какие мысли ? :)
Работает на 10 MHz.
Это Вы с частотой 10Мгц опрашиваете кнопки ? :))
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

:D На самом деле нет. Происходит все так-нажали кнопку-висит в функции 1-нажали ещё раз-во 2-нажали третий раз-в 3...нажали n-раз-break.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Встал на лапы
Сообщения: 120
Зарегистрирован: Вт дек 12, 2006 07:46:53
Откуда: Пермь

Сообщение _Alex »

Может, тогда в прерывании написать кусочек кода, который сравнивает переменные установки будильника и если равны, устанавливает флаг Будильник.
потом, везде где вы сидите в циклах, сделать условие выхода по этому флагу.
На самом деле, программа не должна сидеть в циклах, иначе нужно организовывать. Вплоть до применения ОС.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Ну вот видите, у Вас программа весит попросту, а Вы пытаетесь гемор нажить, выкраивая немного процессорного времечка...
Освободите программу от глупых висов и зацикливаний.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2064
Зарегистрирован: Пт апр 24, 2009 11:39:16
Откуда: г.Оренбург

Сообщение Pika4u »

Хм, спасибо за советы, с флагом надо попытаться.....Идея сама по себе неплохая :)
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Друг Кота
Сообщения: 4435
Зарегистрирован: Сб мар 07, 2009 20:44:36

Сообщение Arlleex »

Идея не неплохая - а из многих тех необходимых, нежели чем у Вас, Pika4u.
Не умеешь - не берись, но не взявшись не научишься...
Открыл глаза
Сообщения: 47
Зарегистрирован: Вс июн 10, 2012 22:43:19
Откуда: РФ, г. Курск

Сообщение brutal »

Pika4u писал(а):Как сделать так, чтобы в прерывании передать управление в функцию, но чтобы произошел выход из обработчика прерывания?
Суть данного мазохизма в следующем. Немного ликбеза: перед вызовом обработчика прерывания cpu в стэке сохраняет адрес инструкции, которая должна выполняться после завершения обработчика прерывания. Таким образом, подменив адрес возврата (и занеся в стэк параметры функции, если она таковые принимает!!!) и завершив обработчик, вы перескочите на вашу функцию. Обратите внимание, что первоначальный адрес, который хранился в стэке как точка возврата, нельзя ни в коем случае затирать! В вашей функции вы должны также подменить адрес возврата на первоначальный адрес из стэка!
Реализовывать сие оставляю вам, ибо на разных платформах код будет соответствено разным.

Лично моё мнение - я думаю что для вашего будильника использовать такие премудрости ето черезчур брутально.
Предлагаю компромиссное решение: в прерывании устанавливать флаг звонка. А уже выйдя из прерывания, по сути в фоновой задаче, воспроизводить звонок. По-моему это более простое и разумное решение.

Кнопку же вашу можно посадить на внешнее прерывание и не тратить впустую процессорное время.
Tais sa gueule et écoute un silence
Друг Кота
Сообщения: 4435
Зарегистрирован: Сб мар 07, 2009 20:44:36

Сообщение Arlleex »

Вообще-то в стек занесется адрес возврата в место, откуда вызвалось прерывание. Дело в том, что при возникновении прерывания в стек пакуется содержимое регистров, в том числе и SREG. А вместе с ним еще и адрес следующей инструкции. В прерывании, если идет вызов функции - мы в стек сохраняем передаваемые параметры этой функции. В самой функции происходит их извлечение, и указатель стека будет указывать уже на последний записанный байт в прерывании - выход из прерывания. Но не всегда такое прокатит. Разные компиляторы по-разному пакуют регистры. И необходимо знать, какие регистры мы точно сохранили и где. НО! А не жирно ли будет столько времени находиться в прерывании? (вопрос никому не адресован, это всего лишь указание) :)
Не умеешь - не берись, но не взявшись не научишься...
Открыл глаза
Сообщения: 47
Зарегистрирован: Вс июн 10, 2012 22:43:19
Откуда: РФ, г. Курск

Сообщение brutal »

Arlleex писал(а):Вообще-то в стек занесется адрес возврата в место, откуда вызвалось прерывание. Дело в том, что при возникновении прерывания в стек пакуется содержимое регистров, в том числе и SREG. А вместе с ним еще и адрес следующей инструкции.
Я забыл уточнить, что имел ввиду assembler. Сохранение регистра SREG если и происходит, то только по желанию компилятора, ибо как сказано в даташите:

Код: Выделить всё

Note that the Status Register is not automatically stored when entering an interrupt routine, nor restored when returning from an interrupt routine. This must be handled by software.
А в стэк при этом сохраняется только лишь содержимое регистра PC (и оттуда же восстанавливается назад), которое хранит адрес следующей для выполнения инструкции.
Arlleex писал(а):В прерывании, если идет вызов функции - мы в стек сохраняем передаваемые параметры этой функции.
Уточню, что параметры вполне могут передаваться через регистры.
Arlleex писал(а):А не жирно ли будет столько времени находиться в прерывании? (вопрос никому не адресован, это всего лишь указание) :)
Столько это сколько? Модификация стэка - по сути перезапись двух байтов - много не отнимет, уверяю вас =)
Tais sa gueule et écoute un silence
Ответить

Вернуться в «AVR»