Страница 1 из 3
Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 09:43:54
Pika4u
Как сделать так, чтобы в прерывании передать управление в функцию, но чтобы произошел выход из обработчика прерывания? То есть, как разумно вызвать функцию из обработчика?
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:08:33
ibiza11
а зачем это? чтобы могло произойти другое прерывание?
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:10:23
Pika4u
Нет, скажем, чтобы сделать будильник. Время совпало с временем будильника(время считается таймером) и опа-идем в функцию будилки и из прерывания выходим.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:21:01
Аlex
А вне прерывания, когда программа освободится от других задач, нельзя сравнивать время с установленным ? Или если программа задержится на пару-тройку миллисекунд (да хоть на секунду), то человек проспит на работу ?
100 раз обсуждалось подобное на форуме, вывод один - если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы. Любую задачу можно решить без подобных финтов.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:23:11
Pika4u
Основное время работы программа занята опросом кнопки и выводом текущего времени. Как-то не хочется прописывать в каждой функции(вывод времени, даты) условие срабатывания будильника. В прерывании легче было бы.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:28:17
Аlex
Это на какой же частоте у Вас работает процессор, если кроме опроса кнопок и вывода информации на дисплей ни на что не остаётся процессорного времени ?
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:34:17
Pika4u
Я не про это...Если делать, как говорите вы, то мне придется в каждую функцию вписывать проверку времени будилки. А функции связаны так:
Код: Выделить всё
void Func1()
{
while(1)
{
if(....)
{
Func2();
break;
}
.......
}
}
void Func2()
{
while(1)
{
if(....)
{
Func3();
break;
}
.....
}
}
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:39:37
Аlex
мне придется в каждую функцию вписывать проверку времени будилки
Зачем ? Программа из этих функций не возвращается что-ли никогда ? Прошла по всем всем функциям и зашла в функцию проверки будильника.
Что там за функции такие, которые тратят всё процессорное время ? Откройте секрет...
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:46:41
Pika4u
А теперь представьте, пусть последняя функция это Func4(). А если программа висит в Func2? И опрашивает кнопки?
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:51:21
Аlex
А если программа висит в Func2? И опрашивает кнопки?
Вы сейчас прикалываетесь или издеваетесь ?

Сколько нужно тактов, что бы опросить кнопку ?
Задам ещё раз свой вопрос
Это на какой же частоте у Вас работает процессор, если кроме опроса кнопок и вывода информации на дисплей ни на что не остаётся процессорного времени ?
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:52:13
Pika4u
Работает на 10 MHz. А теперь посмотрите код выше. while(1) ни на какие мысли не наводит?
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:55:40
Аlex
ни на какие мысли не наводит?
Наводит, о чём я уже говорил выше :
если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы
Не наводит ни на какие мысли ?
Работает на 10 MHz.
Это Вы с частотой 10Мгц опрашиваете кнопки ?

Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 11:58:14
Pika4u

На самом деле нет. Происходит все так-нажали кнопку-висит в функции 1-нажали ещё раз-во 2-нажали третий раз-в 3...нажали n-раз-break.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 12:03:32
_Alex
Может, тогда в прерывании написать кусочек кода, который сравнивает переменные установки будильника и если равны, устанавливает флаг Будильник.
потом, везде где вы сидите в циклах, сделать условие выхода по этому флагу.
На самом деле, программа не должна сидеть в циклах, иначе нужно организовывать. Вплоть до применения ОС.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 12:05:23
Аlex
Ну вот видите, у Вас программа весит попросту, а Вы пытаетесь гемор нажить, выкраивая немного процессорного времечка...
Освободите программу от глупых висов и зацикливаний.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 13:08:55
Pika4u
Хм, спасибо за советы, с флагом надо попытаться.....Идея сама по себе неплохая

Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 15:21:46
Arlleex
Идея не неплохая - а из многих тех необходимых, нежели чем у Вас, Pika4u.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 16:18:12
brutal
Pika4u писал(а):Как сделать так, чтобы в прерывании передать управление в функцию, но чтобы произошел выход из обработчика прерывания?
Суть данного мазохизма в следующем. Немного ликбеза: перед вызовом обработчика прерывания cpu в стэке сохраняет адрес инструкции, которая должна выполняться после завершения обработчика прерывания. Таким образом, подменив адрес возврата (и занеся в стэк параметры функции, если она таковые принимает!!!) и завершив обработчик, вы перескочите на вашу функцию. Обратите внимание, что первоначальный адрес, который хранился в стэке как точка возврата, нельзя ни в коем случае затирать! В вашей функции вы должны также подменить адрес возврата на первоначальный адрес из стэка!
Реализовывать сие оставляю вам, ибо на разных платформах код будет соответствено разным.
Лично моё мнение - я думаю что для вашего будильника использовать такие премудрости ето черезчур брутально.
Предлагаю компромиссное решение: в прерывании устанавливать флаг звонка. А уже выйдя из прерывания, по сути в фоновой задаче, воспроизводить звонок. По-моему это более простое и разумное решение.
Кнопку же вашу можно посадить на внешнее прерывание и не тратить впустую процессорное время.
Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 16:28:24
Arlleex
Вообще-то в стек занесется адрес возврата в место, откуда вызвалось прерывание. Дело в том, что при возникновении прерывания в стек пакуется содержимое регистров, в том числе и SREG. А вместе с ним еще и адрес следующей инструкции. В прерывании, если идет вызов функции - мы в стек сохраняем передаваемые параметры этой функции. В самой функции происходит их извлечение, и указатель стека будет указывать уже на последний записанный байт в прерывании - выход из прерывания. Но не всегда такое прокатит. Разные компиляторы по-разному пакуют регистры. И необходимо знать, какие регистры мы точно сохранили и где. НО! А не жирно ли будет столько времени находиться в прерывании? (вопрос никому не адресован, это всего лишь указание)

Re: Передача управления из прерывания в функцию.
Добавлено: Вс окт 28, 2012 17:15:55
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 писал(а):А не жирно ли будет столько времени находиться в прерывании? (вопрос никому не адресован, это всего лишь указание)

Столько это сколько? Модификация стэка - по сути перезапись двух байтов - много не отнимет, уверяю вас =)