Передача управления из прерывания в функцию.
Как сделать так, чтобы в прерывании передать управление в функцию, но чтобы произошел выход из обработчика прерывания? То есть, как разумно вызвать функцию из обработчика?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
- Реклама
а зачем это? чтобы могло произойти другое прерывание?
Ставим плюсы: )
Нет, скажем, чтобы сделать будильник. Время совпало с временем будильника(время считается таймером) и опа-идем в функцию будилки и из прерывания выходим.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
А вне прерывания, когда программа освободится от других задач, нельзя сравнивать время с установленным ? Или если программа задержится на пару-тройку миллисекунд (да хоть на секунду), то человек проспит на работу ?
100 раз обсуждалось подобное на форуме, вывод один - если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы. Любую задачу можно решить без подобных финтов.
100 раз обсуждалось подобное на форуме, вывод один - если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы. Любую задачу можно решить без подобных финтов.
Основное время работы программа занята опросом кнопки и выводом текущего времени. Как-то не хочется прописывать в каждой функции(вывод времени, даты) условие срабатывания будильника. В прерывании легче было бы.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
- Реклама
Это на какой же частоте у Вас работает процессор, если кроме опроса кнопок и вывода информации на дисплей ни на что не остаётся процессорного времени ?
Я не про это...Если делать, как говорите вы, то мне придется в каждую функцию вписывать проверку времени будилки. А функции связаны так:
Код: Выделить всё
void Func1()
{
while(1)
{
if(....)
{
Func2();
break;
}
.......
}
}
void Func2()
{
while(1)
{
if(....)
{
Func3();
break;
}
.....
}
}
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Зачем ? Программа из этих функций не возвращается что-ли никогда ? Прошла по всем всем функциям и зашла в функцию проверки будильника.мне придется в каждую функцию вписывать проверку времени будилки
Что там за функции такие, которые тратят всё процессорное время ? Откройте секрет...
А теперь представьте, пусть последняя функция это Func4(). А если программа висит в Func2? И опрашивает кнопки?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Вы сейчас прикалываетесь или издеваетесь ?А если программа висит в Func2? И опрашивает кнопки?
Задам ещё раз свой вопрос
Это на какой же частоте у Вас работает процессор, если кроме опроса кнопок и вывода информации на дисплей ни на что не остаётся процессорного времени ?
Работает на 10 MHz. А теперь посмотрите код выше. while(1) ни на какие мысли не наводит?
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Наводит, о чём я уже говорил выше :ни на какие мысли не наводит?
Не наводит ни на какие мысли ?если Вы захотели сделать такой финт, значит у Вас неправильно составлен алгоритм программы
Это Вы с частотой 10Мгц опрашиваете кнопки ?Работает на 10 MHz.
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Может, тогда в прерывании написать кусочек кода, который сравнивает переменные установки будильника и если равны, устанавливает флаг Будильник.
потом, везде где вы сидите в циклах, сделать условие выхода по этому флагу.
На самом деле, программа не должна сидеть в циклах, иначе нужно организовывать. Вплоть до применения ОС.
потом, везде где вы сидите в циклах, сделать условие выхода по этому флагу.
На самом деле, программа не должна сидеть в циклах, иначе нужно организовывать. Вплоть до применения ОС.
Ну вот видите, у Вас программа весит попросту, а Вы пытаетесь гемор нажить, выкраивая немного процессорного времечка...
Освободите программу от глупых висов и зацикливаний.
Освободите программу от глупых висов и зацикливаний.
Хм, спасибо за советы, с флагом надо попытаться.....Идея сама по себе неплохая 
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
- Сообщения: 4435
- Зарегистрирован: Сб мар 07, 2009 20:44:36
Идея не неплохая - а из многих тех необходимых, нежели чем у Вас, Pika4u.
Не умеешь - не берись, но не взявшись не научишься...
Суть данного мазохизма в следующем. Немного ликбеза: перед вызовом обработчика прерывания cpu в стэке сохраняет адрес инструкции, которая должна выполняться после завершения обработчика прерывания. Таким образом, подменив адрес возврата (и занеся в стэк параметры функции, если она таковые принимает!!!) и завершив обработчик, вы перескочите на вашу функцию. Обратите внимание, что первоначальный адрес, который хранился в стэке как точка возврата, нельзя ни в коем случае затирать! В вашей функции вы должны также подменить адрес возврата на первоначальный адрес из стэка!Pika4u писал(а):Как сделать так, чтобы в прерывании передать управление в функцию, но чтобы произошел выход из обработчика прерывания?
Реализовывать сие оставляю вам, ибо на разных платформах код будет соответствено разным.
Лично моё мнение - я думаю что для вашего будильника использовать такие премудрости ето черезчур брутально.
Предлагаю компромиссное решение: в прерывании устанавливать флаг звонка. А уже выйдя из прерывания, по сути в фоновой задаче, воспроизводить звонок. По-моему это более простое и разумное решение.
Кнопку же вашу можно посадить на внешнее прерывание и не тратить впустую процессорное время.
Tais sa gueule et écoute un silence
- Сообщения: 4435
- Зарегистрирован: Сб мар 07, 2009 20:44:36
Вообще-то в стек занесется адрес возврата в место, откуда вызвалось прерывание. Дело в том, что при возникновении прерывания в стек пакуется содержимое регистров, в том числе и SREG. А вместе с ним еще и адрес следующей инструкции. В прерывании, если идет вызов функции - мы в стек сохраняем передаваемые параметры этой функции. В самой функции происходит их извлечение, и указатель стека будет указывать уже на последний записанный байт в прерывании - выход из прерывания. Но не всегда такое прокатит. Разные компиляторы по-разному пакуют регистры. И необходимо знать, какие регистры мы точно сохранили и где. НО! А не жирно ли будет столько времени находиться в прерывании? (вопрос никому не адресован, это всего лишь указание) 
Не умеешь - не берись, но не взявшись не научишься...
Я забыл уточнить, что имел ввиду assembler. Сохранение регистра SREG если и происходит, то только по желанию компилятора, ибо как сказано в даташите:Arlleex писал(а):Вообще-то в стек занесется адрес возврата в место, откуда вызвалось прерывание. Дело в том, что при возникновении прерывания в стек пакуется содержимое регистров, в том числе и 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.Уточню, что параметры вполне могут передаваться через регистры.Arlleex писал(а):В прерывании, если идет вызов функции - мы в стек сохраняем передаваемые параметры этой функции.
Столько это сколько? Модификация стэка - по сути перезапись двух байтов - много не отнимет, уверяю вас =)Arlleex писал(а):А не жирно ли будет столько времени находиться в прерывании? (вопрос никому не адресован, это всего лишь указание)
Tais sa gueule et écoute un silence


