Zandy 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Организовано системное прерывание по таймеру (каждые 8мс). В нем делаю всякие дела (антидребезг, большие временные интервалы, и т. д). Хочу в этом прерывании организовать программный счетчик таймаута. Но так, чтобы в случае наступления таймаута меня перекидывало в нужную мне точку программы, в начало некого цикла. Предлагать использовать ватчдог-таймер не надо. Он будет перекидывать в начало программы, а мне это не нужно. Я вот что-то призабыл. Когда писал в асме вроде бы можно было сделать любой переход из любой точки. Или по метке, или непосредственно задавая значение (приращение) программного счетчика. Сейчас делаю программу в С, и вот тут, как раз возникли трудности. goto по метке не работает. Работает только в пределах одной функции. А как из прерывания? Ведь прерывание - аппаратная функция и может возникнуть в любой момент выполнения основной программы. Т. е точка входа и выхода неизвестна. Нутром понимаю, что сделать можно. Но как?! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба setjump(), longjump(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slog 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Если в IAR то asm("rjmp имя_функции_куда_переход"); Но вообще-то это то что называется грязный хак. Правильные пацаны так не делают. Проблем можешь поиметь со стеком и ещё неизвестно с чем вплоть до того что программа не будет работать. Таким образом можно переходить только на старт программы инициализации. Даже не main() а то что выполняется перед ней. Какой-нибудь low_level_init. Ищи другой путь. Этот не правильный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Нутром понимаю, что сделать можно. Но как?! В обработчике прерывания устанавливать флажок, а в фоновом процессе его проверять, сбрасывать и выполнять переход, если он установлен. Или же счетчик таймаута определять не в обработчике, а в фоновом процессе. Или вообще (если задача позволяет) реализовать его аппаратно на свободном таймере. Выходить из обработчика прерывания принудительно - почти всегда дурной тон. Если не всегда ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zandy 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба setjump(), longjump(). Здесь я что-то ни хрена не понял, какое отношение к моей задаче. И еще, по ссылке не работают примеры. По поводу грязного хака. Не совсем согласен. В сложных программах с кучей вложенных функций наверное это так. В моем простейшем случае, я думаю, небо не рухнет. Ведь допускает же теория С выход из вложенных циклов по готу. Да тут даже вопрос то не в этом (плохо или хорошо). Пусть плохо. Но как? По поводу проверки флага, установленного в прерывании, в основном цикле. Больно часто его придется проверять, хотя... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба setjump(), longjump(). Здесь я что-то ни хрена не понял, какое отношение к моей задаче. http://electronix.ru/forum/index.php?showt...ngjmp&st=30 В принципе можно сделать, но потребуется сначала "подготовить почву", а после перехода "прибрать за собой" и т.д. Чем сложнее процессор, тем больше ньюансов приходится учитывать. Лучше всё-таки придумать другой способ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба В моем простейшем случае Раз случай простейший, то и решение напрашивается простейшее. А ваше решение: - Сложное - Некорректное - Нестандартное, мягко говоря. Небо не рухнет, конечно. Просто получится халтура, да и все. Будет работать тяп-ляп, ни шатко, ни валко, да и то если постараетесь ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A. Fig Lee 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба По поводу проверки флага, установленного в прерывании, в основном цикле. Больно часто его придется проверять, хотя... А кому сейчас легко? При выходе из прерывания некоторые контроллеры могут автоматически enable/disable interrupt flag. Непонятно, как Вы с этим собираетесь боротся? Надо испонять специальную инструкцию возврата, в общем огород будет мама не горюй. kovigor сказал уже как правильные пацаны делают Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба я что-то ни хрена не понял1) Такие выражения на этом форуме не приняты. 1.1) "нихрена" пишется слитно. Так же как и "ничего", "никого", "никак". 2) Гуглю никто не отменил. По запросу setjump() он дает тонны описаний и примеров. 3) других вариантов решения вашей задачи в языке C нет. какое отношение к моей задачеПрочитайте другие варианты описания. Эта пара макросов делает именно то, что вы просите. Но программа должна сначала хотя бы один раз пробежать то место, куда вы потом захотите вернуться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 49 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Но вообще-то это то что называется грязный хак. еще можно адрес возврата на стэке подправить и выйти из прерывания как обычно, но это еще грязнее :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 30 ноября, 2013 Опубликовано 30 ноября, 2013 · Жалоба Прерывание на то оно и прерывание. Должно прервать, сделать свои дела и вернуться в то же место откуда прервала! На асме можно, делаю это при выключении питания и переходе на питание от батареи. Но на ассемблере написана вся программа и я целиком и полностью представляю всю её работу. На Си незнаю, не пишу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slog 0 30 ноября, 2013 Опубликовано 30 ноября, 2013 · Жалоба По поводу грязного хака. Не совсем согласен. В сложных программах с кучей вложенных функций наверное это так. В моем простейшем случае, я думаю, небо не рухнет. Ведь допускает же теория С выход из вложенных циклов по готу. Да тут даже вопрос то не в этом (плохо или хорошо). Пусть плохо. Но как? По поводу проверки флага, установленного в прерывании, в основном цикле. Больно часто его придется проверять, хотя... Так делать не правильно. Объясняю почему. При возникновении прерывания программа в начале сохраняет состояние регистров и адрес возврата в стеке. Если бы программа обработки прерывания завершилась как положено то по окончании обработки прерывания стек восстановился бы в нормальное состояние и всё бы работало дальше. А если ты просто перейдёшь куда-то там... то в стеке неизвестно что окажется не вынутым. Сосотояние стека в момент безусловного перехода тебе не известно. Восстановить его правильно ты не сможешь. Поэтому после такого перехода либо надо заново инициализировать стек либо рано или поздно "небо упадёт". С выходом из вложенных циклов не сравнивай, там со стеком всё в порядке. Тебе подсказали правильный путь - в прерывании только устанавливать флаг а в основном цикле не торопясь обрабатывать флаги. И вообще, засовывать много длинного кода в прерывания это не правильно. Прерывание должно выполниться максимально быстро. Зашёл в прерывание, установил флаги и вышел. И всё. А в основном цикле обрабатывай флаги. Иначе как только время обработки прерывания превысит время между прерываниями так сразу начинаются неуловимые глюки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 30 ноября, 2013 Опубликовано 30 ноября, 2013 (изменено) · Жалоба ...Нутром понимаю, что сделать можно. Но как?! Сделать то мона, но думаю у Вас консерватория хромает. Консервы пытаетесь открывать ножовкой по металлу. Если хотите поучится как грамотно это делать - как пример(правда тупо копирнуть не получится, да и вставки на азме скорее всего будут) можете глянуть любую вытесняющую ось. как пример - FreeRTOS. Именно так там и сделано. по некой логике делается вывод - переход в контекст другой задачи, либо просто выход из системного таймера. удачи Вам ЗЫ Выше уже прозвучало - что избранный Вами путь как минимум подозрителен. Изменено 30 ноября, 2013 пользователем kolobok0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zandy 0 1 декабря, 2013 Опубликовано 1 декабря, 2013 · Жалоба Спасибо за все, брошенные в меня, тухлые помидоры. Так много откликов! Видать тема больная. :) Конечно, можно было бы, с моей стороны, и дальше "расчесывать" больное место, но я пока этого делать не буду. Потом, как-нибудь. Я понял, что путь этот сложен и тернист. Моя задача позволяет несколько вариантов решения, в том числе и без затрагивания действий сомнительной репутации. Так что, спасибо, тема закрыта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 1 декабря, 2013 Опубликовано 1 декабря, 2013 · Жалоба Я понял, что путь этот сложен и тернист. Он не сложен и не тернист, он просто неправилен. Для применения подобных решений должны быть очень веские основания н6а фоне полного отсутствия разумной алтернативы. Они есть ? Сомневаюсь .... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться