v_sshuryk
1

Сброс обработчика прерывания из более приоритетного прер-я

22.09.2016, 22:17. Показов 5329. Ответов 14
Метки нет (Все метки)

Здравствуйте спецы!

Столкнулся с задачей, с которой ранее дел не имел и даже не интересовался.

Вот в чем суть: выполняется основной цикл программы и периодически возникает прерывание, которое обрабатывается соответствующим образом. Но реже возникает более приоритетное прерывание, которое также обрабатывается. Возникают моменты, когда более приоритетное прерывает обработку менее приоритетного. При выходе из более приоритетного необходимо как-то сбросить продолжение обработки менее приоритетного, т.е. перейти сразу к основному циклу. Запрещать обработку более высокого, при входе в менее приоритетное, с целью обработки первого по завершении обработки менее приоритетного - нельзя. Контролировать в обработчике менее приоритетного события, а не было ли у нас прерывания более высокого, и оперативно его завершать тоже не вариант.

Вот и интересует вопрос нет ли какого-нибудь механизма для решения данного вопроса.

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.09.2016, 22:17
Ответы с готовыми решениями:

Выход из обработчика прерывания
Задача: По прерыванию (нажатие кнопки) нужно покинуть рабочий цикл и передать управление некой...

Возврат из обработчика прерывания.
Продублирую вопрос сюда, ибо в "Мелких вопросах" висит он неприкаянно: Как осуществить возврат...

Выход из обработчика прерывания
Есть обработчик прерывания, который проверяет состояние кнопки и в зависимости от состояния кнопки...

Выгрузка резидента из обработчика прерывания
Здравствуйте! Вопрос такой: Как в программе выгрузить из памяти резидент , в конце обработчика...

14
1 / 1 / 0
Регистрация: 30.12.2013
Сообщений: 192
22.09.2016, 22:49 2
Цитата Сообщение от v_sshuryk
Здравствуйте спецы!
Контролировать в обработчике менее приоритетного события, а не было ли у нас прерывания более высокого, и оперативно его завершать тоже не вариант.

Вот и интересует вопрос нет ли какого-нибудь механизма для решения данного вопроса.
Механизм есть - пересмотр алгоритма обработки, возможно - объединения, возможно - вытаскивание алгоритма из основного цикла так же в прерывание (программное), чтобы сразу после выполнения самого приоритетного - обработать то, что нужно сделать (сейчас у вас) в основном цикле.

В ином случае вдумайтесь в свой же вопрос: как выйти из функции без изменения логики переходов программы. Прерывание - обычная функция, вызываемая по событию. Как из неё сделать return то на ровном месте.
0
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,113
22.09.2016, 23:19 3
Цитата Сообщение от v_sshuryk
При выходе из более приоритетного необходимо как-то сбросить продолжение обработки менее приоритетного, т.е. перейти сразу к основному циклу.
Для обычного MCU это сделать нельзя. (Написание собственной RTOS не рассматриваем)
Если вам так уж надо вернуться в main, я бы предложил два варианта:
- расставить в обработчике низкоуровнего прерывания множество контрольных точек, где проверять статус. Если установлен флаг прерывания, то выйти (игнорировать все остальные действия).
- на выходе из обработчика высокого уровня проверять, что сейчас выполнялось низкоуровневое прерывание и перед выходом вызвать программное (или эмулированное аппаратное) прерывание с высоким приоритетом. Т.о. после выхода из обработчика не произойдет возврат к низкоуровневому, а начнется выполнение вставленного прерывания. И вот в нём вы можете сделать то, что захотите (кусок main). По выходу из него продолжится обработка низкоуровневого прерывания .
0
v_sshuryk
22.09.2016, 23:42 4
В том то и дело, что из старшего прерывания нужно сразу выйти в основной цикл. В более низком прерывании ставить кучу точек контроля совсем не вариант. return все понятно, но чтобы им воспользоваться опять же нужно контролировать, а не было ли у нас выполнено более приоритетное и потом действовать.

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

Когда у нас вызывается более приоритетное, наверняка в каком-нибудь регистре контроля ставится флаг, что нужно после завершения старшего обработчика вернуться к выполнению младшего. Узнать бы где он такой прячется и можно ли его сбросить!?
0 / 0 / 0
Регистрация: 26.01.2009
Сообщений: 3
23.09.2016, 01:19 5
Есть, только это не регистр а стек. А еще, возможно, регистр LR. Если при входе в низкоприоритетного прерывания сохранять, где вершина стека, то высокоприоритетное сможет сразу при выходе прыгнуть туда. Но нетривиально.
0
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,113
23.09.2016, 03:13 6
Поставьте RTOS и обрабатывайте настройки/исполнения в отдельных тредах, без прерываний.
Чтобы модуль мог работать с внешним конфигурированием, в этом модуле _должна_быть_ поддержка копирования настроек на момент начала обработки (начала обработчика прерывания). В этом случае атомарность не нарушается и настройка-исполнение не обязаны следовать строго друг-за-другом.
И вообще, ваше ТЗ нуждается в полном переосмыслении. Ради кривого алгоритма применять хакерские приемы в виде выкидывания работающего обработчика - это, очень мягко говоря, нонсенс. Дикий.
0
v_sshuryk
23.09.2016, 17:31 7
Вот именно - нонсенс, но деваться некуда, надо что-то придумывать. Возиться со стеком, выгружать (смещать) из него все данные, которые соответствуют низкоприоритетному прерыванию, с целью восстановления состояния контролера, которое было до прерывания основного цикла - возня серьезная. Поднимать RTOS и переносить весь проект - может и пойдет, но опять же возни, а как всегда хочется красиво и просто. Алгоритм может и кривой, но другого ничего оптимальнее не приходит в голову, не один месяц над ним трудимся. Если относительно простого решения не найдется, то со временем придется все перерабатывать, вот и все.
0 / 0 / 0
Регистрация: 18.04.2014
Сообщений: 4
23.09.2016, 18:04 8
Есть подозрение, что у ТС обработчик каждого из упомянутых прерываний - "простыня" на пол-экрана. Ни для кого не секрет, что тело обработчика прерывания должно быть максимально коротким. Буквально, прилетели - пару флажков поставили - улетели. А вся логика, которую ТС желает, при наличии данных флажков спокойно решается в основном бесконечном цикле. Поправьте, если не прав.
0
0 / 0 / 0
Регистрация: 11.06.2010
Сообщений: 351
23.09.2016, 20:55 9
А что должно быть когда низко-приоритетное прерывание частично выполнилось со старыми настройками? Когда наступает эффект от его выполнения?

Пока мне кажется, где-то нужно делать корректную синхронизацию. Например, низко-приоритетное прерывание забирает копию настроек и работает с ними до конца, даже если произошло прерывание которое их обновит. Копию обычно берут подменой указателей с помощью атомарных инструкций и других lock-free методов синхронизации.
0
v_sshuryk
23.09.2016, 23:03 10
Естественно, что низкоприоритетный обработчик максимально короткий, задали пару адресов, выполнили синхронизацию и в основной цикл. Более приоритетной также минимизировано - задается период возникновения младшего прерывания, адреса и некоторые параметры, по которым выполняется синхронизация в менее приоритетном. Низкоприоритетное возникает по строгому периоду, а вот более приоритетное от внешнего события, период которого плавает. Допустим - вошли в обработчик низкоприоритетного, только начали его выполнять - возникло более серьезное прерывание и там мы изменили период (уменьшили его значительно) возникновения низкоприоритетного. вернулись в низкоприоритетное и продолжаем в нем завершать все свои действия и пока закончим может возникнуть необходимость снова вызова низкоприоритетного, а мы то его еще и не выполнили, висим в нем, а времени нет, необходини оперативная синхронизация. Вот и требуется задали новые параметры для низкоприоритетного и сразу выскакивать в основной цикл. Помимо этого есть и другие моменты. Проц загружен по самые уши и время впритык, разгуляться негде.
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
23.09.2016, 23:31 11
Теоретически наверно возможно, но практически я этого конечно не делал.
У кортексов на самом деле два указателя стека - msp (main sp) и psp (process sp) - которые мэппируются на регистр sp.
По ресету sp - это msp, при прерываниях процессор переключается на msp автоматически.
Если программу переключить на использование psp, то на дне msp всегда будет восемь нужных слов для возврата в программу.
Но будет правда ещё нюанс с регистром lr - в случае вложенного прерывания надо будет не только смещать sp, но перед этим ещё и доставать из стека lr.
0
1 / 1 / 0
Регистрация: 30.12.2013
Сообщений: 192
25.09.2016, 22:17 12
Цитата Сообщение от v_sshuryk
Естественно, что низкоприоритетный обработчик максимально короткий, задали пару адресов, выполнили синхронизацию и в основной цикл. Более приоритетной также минимизировано - задается период возникновения младшего прерывания, адреса и некоторые параметры, по которым выполняется синхронизация в менее приоритетном. Низкоприоритетное возникает по строгому периоду, а вот более приоритетное от внешнего события, период которого плавает. Допустим - вошли в обработчик низкоприоритетного, только начали его выполнять - возникло более серьезное прерывание и там мы изменили период (уменьшили его значительно) возникновения низкоприоритетного. вернулись в низкоприоритетное и продолжаем в нем завершать все свои действия и пока закончим может возникнуть необходимость снова вызова низкоприоритетного, а мы то его еще и не выполнили, висим в нем, а времени нет, необходини оперативная синхронизация. Вот и требуется задали новые параметры для низкоприоритетного и сразу выскакивать в основной цикл. Помимо этого есть и другие моменты. Проц загружен по самые уши и время впритык, разгуляться негде.
У вас на столько длинное низкоуровневое прерывание, что во время его выполнения может потребоваться выполнить его снова и времени не хватит?) Нет, что-то тут не чисто. Либо вы задачу не так формулируете, либо ваша схема не заработает даже если вы сделаете это костыли. Вот в то, что в высокоуровневом прерывании вы можете переписать адреса, а потом вернуться вниз и обработать "не то" - это да. Но для этого существуют флаги или просто запреты прерывания. Я читал ваше сообщение о недопустимости этого, но какой-то уж больно быстрый процесс, если нельзя пару тактов подождать. Иными словами -> правильно ли подобрана аппаратура? Если да, то пересматривайте алгоритм: не может быть такого, чтобы нельзя было решить задачу без костылей.
0
v_sshuryk
26.09.2016, 21:06 13
Время выполнения может не хватить в том случае, если в высокоприоритетном прерывании настройки изменятся таким образом, что низкоприоритетное должно возникнуть практически сразу после выхода из высокоприоритетного, а мы еще не завершили низкоприоритетное. Да процесс очень быстрый и контроллер справляется с задачей на гране, но переделывать все под другой контроллер времени нет. Возможно просто применим более старшего собрата и будем отслеживать было ли прерывание или нет. Простого выхода не видится, будем искать золотую середину сейчас, а позже пересмотрим проект.

Спасибо!!!
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 918
26.09.2016, 22:16 14
Я бы выровнял приоритеты.
Тогда буде следующее:
мы находимся в том прерывании, которое у вас сейчас менее приоритетное. Пришел сигнал на более приоритетное. Менее приоритетное прерывание доделалось и запустилось более приоритетное.
Если там действительно"обработчик максимально короткий", то мы потеряли 3-4 такта. Если не так, то можно младшее прерывание написать как nacked функцию -ассемблерную вставку и гарантировано иметь там ~15 циклов исполнения:
5 циклов на первый адрес
2 на второй
4-8 на синхронизацию
0
1 / 1 / 0
Регистрация: 30.12.2013
Сообщений: 192
26.09.2016, 22:40 15
Цитата Сообщение от v_sshuryk
низкоприоритетное должно возникнуть практически сразу после выхода из высокоприоритетного, а мы еще не завершили низкоприоритетное
Посмотрите, какие есть инструменты по управлению запросами прерываний: может можно предотвратить появление повторного НУ прерывания в тот момент, пока он не завершил первое? (В зависимости от того, кто источник прерывания - разные флаги и механизмы).

PS: прерывания я бы тоже выровнял, но выше автор сильно противился предложению - сделать запрет ВУ прерывания, пока НУ не отработает. По сути это тоже. Оно только даст удобство при работе с флагами и блокировками (они попросту не нужны тогда).
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.09.2016, 22:40

Выход из цикла в функции обработчика прерывания
Здравствуйте. Понадобилась программа работающая по прерыванию, а именно по приему данных через...

Прерывания в ОСи: прототип функции-обработчика
Как реализовать прерывания на C++. Какой должен быть прототип функции-обработчика. Как делать выход...

Не работает эмуляция обработчика прерывания Print Screne
Задание такое - эмуляция обработчика прерывания Print Screen (INT 5) c выводом копии экрана в файл\...

Задержки на SysTick внутри обработчика прерывания, дребезг
Доброго времени суток. 1. Пытаюсь прикрутить delay на SysTick. При вызове из main все работает...

Аппаратный сброс флага прерывания
Интересную штуку накопал. Не совсем очевидную. Работаю (мега48) с прерываниями по совпадению:...

Извлечение сегмента кода в процессе работы резидентного обработчика прерывания
Здравствуйте. Имеется TSR-программа для ДОС, отображающая регистры процессора. Вопрос в том, можно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.