Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/28: Рейтинг темы: голосов - 28, средняя оценка - 4.75
v_sshuryk

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

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

Студворк — интернет-сервис помощи студентам
Здравствуйте спецы!

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

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

Вот и интересует вопрос нет ли какого-нибудь механизма для решения данного вопроса.
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.09.2016, 22:17
Ответы с готовыми решениями:

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

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

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

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

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

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

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

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

Пока мне кажется, где-то нужно делать корректную синхронизацию. Например, низко-приоритетное прерывание забирает копию настроек и работает с ними до конца, даже если произошло прерывание которое их обновит. Копию обычно берут подменой указателей с помощью атомарных инструкций и других lock-free методов синхронизации.
0
v_sshuryk
23.09.2016, 23:03
Естественно, что низкоприоритетный обработчик максимально короткий, задали пару адресов, выполнили синхронизацию и в основной цикл. Более приоритетной также минимизировано - задается период возникновения младшего прерывания, адреса и некоторые параметры, по которым выполняется синхронизация в менее приоритетном. Низкоприоритетное возникает по строгому периоду, а вот более приоритетное от внешнего события, период которого плавает. Допустим - вошли в обработчик низкоприоритетного, только начали его выполнять - возникло более серьезное прерывание и там мы изменили период (уменьшили его значительно) возникновения низкоприоритетного. вернулись в низкоприоритетное и продолжаем в нем завершать все свои действия и пока закончим может возникнуть необходимость снова вызова низкоприоритетного, а мы то его еще и не выполнили, висим в нем, а времени нет, необходини оперативная синхронизация. Вот и требуется задали новые параметры для низкоприоритетного и сразу выскакивать в основной цикл. Помимо этого есть и другие моменты. Проц загружен по самые уши и время впритык, разгуляться негде.
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
23.09.2016, 23:31
Теоретически наверно возможно, но практически я этого конечно не делал.
У кортексов на самом деле два указателя стека - 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
Цитата Сообщение от v_sshuryk
Естественно, что низкоприоритетный обработчик максимально короткий, задали пару адресов, выполнили синхронизацию и в основной цикл. Более приоритетной также минимизировано - задается период возникновения младшего прерывания, адреса и некоторые параметры, по которым выполняется синхронизация в менее приоритетном. Низкоприоритетное возникает по строгому периоду, а вот более приоритетное от внешнего события, период которого плавает. Допустим - вошли в обработчик низкоприоритетного, только начали его выполнять - возникло более серьезное прерывание и там мы изменили период (уменьшили его значительно) возникновения низкоприоритетного. вернулись в низкоприоритетное и продолжаем в нем завершать все свои действия и пока закончим может возникнуть необходимость снова вызова низкоприоритетного, а мы то его еще и не выполнили, висим в нем, а времени нет, необходини оперативная синхронизация. Вот и требуется задали новые параметры для низкоприоритетного и сразу выскакивать в основной цикл. Помимо этого есть и другие моменты. Проц загружен по самые уши и время впритык, разгуляться негде.
У вас на столько длинное низкоуровневое прерывание, что во время его выполнения может потребоваться выполнить его снова и времени не хватит?) Нет, что-то тут не чисто. Либо вы задачу не так формулируете, либо ваша схема не заработает даже если вы сделаете это костыли. Вот в то, что в высокоуровневом прерывании вы можете переписать адреса, а потом вернуться вниз и обработать "не то" - это да. Но для этого существуют флаги или просто запреты прерывания. Я читал ваше сообщение о недопустимости этого, но какой-то уж больно быстрый процесс, если нельзя пару тактов подождать. Иными словами -> правильно ли подобрана аппаратура? Если да, то пересматривайте алгоритм: не может быть такого, чтобы нельзя было решить задачу без костылей.
0
v_sshuryk
26.09.2016, 21:06
Время выполнения может не хватить в том случае, если в высокоприоритетном прерывании настройки изменятся таким образом, что низкоприоритетное должно возникнуть практически сразу после выхода из высокоприоритетного, а мы еще не завершили низкоприоритетное. Да процесс очень быстрый и контроллер справляется с задачей на гране, но переделывать все под другой контроллер времени нет. Возможно просто применим более старшего собрата и будем отслеживать было ли прерывание или нет. Простого выхода не видится, будем искать золотую середину сейчас, а позже пересмотрим проект.

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

PS: прерывания я бы тоже выровнял, но выше автор сильно противился предложению - сделать запрет ВУ прерывания, пока НУ не отработает. По сути это тоже. Оно только даст удобство при работе с флагами и блокировками (они попросту не нужны тогда).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.09.2016, 22:40
Помогаю со студенческими работами здесь

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

Подмена обработчика прерывания клавиатуры
Добрый день, изучаю асслемблер, преподавателем поставлена задача: "Должна быть написана программа, реализующая подмену обработчика...

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

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

Вызов обработчика прерывания в резидентной COM-программе
Всем доброго времени суток. Немного запутался. речь идёт о вызовах подпрограмм. В переменной old_08h (объявлена как dd )сохраняется адрес...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru