Форум РадиоКот https://radiokot.ru/forum/ |
|
AVR прерывание прерывания https://radiokot.ru/forum/viewtopic.php?f=20&t=75806 |
Страница 1 из 3 |
Автор: | sx386 [ Сб июл 21, 2012 23:29:20 ] |
Заголовок сообщения: | AVR прерывание прерывания |
Прочитал что прерывания выполняются в очереди приоритета, если срабатывают одновременно Т.е. при одновременной подаче сигнала на INT0 и INT1 выполниться сначала INT0, а затем INT1 А что будет если подать сигнал на INT0 в то время, когда выполняется код в INT1 Контроллер дождётся выполнения INT1, а затем запустит INT0 или прервёт INT1 и выполнит INT0 ? |
Автор: | brutal [ Вс июл 22, 2012 00:04:13 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
входя в обработчик прерывания, avr микроконтроллер сбрасывает флаг разрешения прерывания поэтому INT1 выполнится до конца. Однако при подаче сигнала на INT0 флаг прерывания INTF0 установится, и, по-видимому, при завершении обработки INT1 сработает переход на обработчик INT0. Поэтому поведение зависит от значения флага I в регистре SREG на момент прихода сигнала INT0. |
Автор: | vitalik_1984 [ Вс июл 22, 2012 00:16:52 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
можно насильно включить флаг глобального разрешения прерываний,а нужно ли?Так окажутся все прерывания запутанными и какой нибудь коллапс нагрянет |
Автор: | coredumped [ Вс июл 22, 2012 06:49:47 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Коллапса не будет, если объем стека позволяет |
Автор: | ILYAUL [ Вс июл 22, 2012 19:01:46 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
А причём здесь объём стека? Колапс , если не иметь мозгов, наступит при любом объёме |
Автор: | BCluster [ Вс июл 22, 2012 19:33:36 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
объем стека как бы при всем))) |
Автор: | Goldsmith [ Вс июл 22, 2012 20:10:53 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
sx386 писал(а): Прочитал что прерывания выполняются в очереди приоритета, если срабатывают одновременно Совершенно верно. Если установлено одновременно несколько флагов запроса прерывания и установлен флаг Global Interrupt Enable, начнет выполняться разрешенное прерывание с наивысшим приоритетом.Приоритетность прерывания определяется адресом его вектора: чем меньше адрес, тем выше приоритет. sx386 писал(а): Т.е. при одновременной подаче сигнала на INT0 и INT1 выполниться сначала INT0, а затем INT1 Согласно старшинству приоритетов (см. выше): чем меньше адрес вектора, тем выше приоритет. Обычно приоритет INT0 выше, чем у INT1, но моделей AVR много, поэтому за все не могу ручаться.sx386 писал(а): А что будет если подать сигнал на INT0 в то время, когда выполняется код в INT1 При входе в прерывание флаг Global Interrupt Enable автоматически сбрасывается, запрещая дальнейшие прерывания. Если он будет явно установлен в программе обработки прерывания, то новый запрос с наивысшим приоритетом прервет текущий обработчик. Приоритет прерывания уже запущенного обработчика при этом не имеет значения: если одновременно выставлены запросы INT0 и INT1 и оба они разрешены, начнет обрабатываться INT0; если далее в обработчике INT0 будет установлен флаг Global Interrupt Enable, то текущий обработчик будет вытеснен обработчиком INT1, а по его завершении будет продолжен (если кто-то еще снова не вытеснит).Контроллер дождётся выполнения INT1, а затем запустит INT0 или прервёт INT1 и выполнит INT0 ? Точно так же уже запущенный обработчик INT1 будет прерван более приоритетным INT0 лишь в том случае, если сам установит Global Interrupt Enable. Приоритет важен лишь в момент выбора одного прерывания из нескольких одновременных запросов. Есть еще одна тонкость: если в данный момент обрабатывается прерывание, а другой запрос уже ожидает своей очереди, то после завершения текущего обработчика производится возврат в прерванную программу, выполняется одна инструкция, и лишь затем запускается новый обработчик. Эту задержку следует учитывать, если время реакции на прерывание очень критично. |
Автор: | ILYAUL [ Пн июл 23, 2012 01:06:39 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
BCluster писал(а): объем стека как бы при всем))) Ну для С наверное, asm более свободен в этом отношении, там всё решает внимательность. |
Автор: | Goldsmith [ Пн июл 23, 2012 10:28:42 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Внимательность не так уж сильно зависит от языка программирования. Помимо переполнения стека, есть еще одни грабли, на которые можно наступить, разрешая прерывания внутри обработчика. Если обработчик прерывания нереентерабелен (что вполне вероятно), то повторное прерывание, возникшее во время обработки предыдущего, приведет к непредсказуемым последствиям. Причем диагностировать такую ситуацию гораздо сложнее, чем переполнение стека. Самый надежный вариант, если нет очень уж жестких требований реального времени, - не допускать вложения прерываний. Если делать в обработчике только минимально необходимую обработку, а завершать ее в фоновом режиме, такая небольшая задержка не должна иметь пагубных последствий. Ну а если уж это невыполнимо, то хотя бы сбрасывать флаг разрешения данного прерывания в начале его обработки. |
Автор: | DrHlus [ Пн июл 23, 2012 22:10:37 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Goldsmith писал(а): Если обработчик прерывания нереентерабелен (что вполне вероятно), то повторное прерывание, возникшее во время обработки предыдущего, приведет к непредсказуемым последствиям. Можете рассказать об этом подробнее или кинуть ссылочку, где об этом можно почитать?
|
Автор: | ILYAUL [ Пн июл 23, 2012 23:16:08 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Цитата: где об этом можно почитать? +1 Насколько я помню , реентерабельность относится к одному и тому же куску кода , которым одновременно могут воспользоваться несколько пользователей не мешая друг другу , при этом на код накладывается куча условий. И как это понятие применимо к вложенным прерываниям? Цитата: Ну а если уж это невыполнимо, то хотя бы сбрасывать флаг разрешения данного прерывания в начале его обработки. Что обычно делается процессором автоматически при входе в обработчик прерывания , если это прерывание разрешено или всё таки нет?
|
Автор: | ploop [ Пн июл 23, 2012 23:38:32 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Хотя вложенных прерываний стоит избегать, бывают случаи, когда без них логика становится ещё запутанней, и больше шансов нарваться на грабли. Тут важно понимать одно: в какой момент какое прерывание может наступить. Редко они используются все и сразу. Например: есть прерывание с относительно длительным обработчиком (и без него никак, либо очень сложно). Есть второе прерывание, которое необходимо обработать моментально, и выполняется оно быстро, при том не модифицирует данные, с которым работает первое. И если больше никаких прерываний не используется, то вполне вариант принудительно разрешить прерывания внутри первого, при этом мы практически ничего не теряем, избавляемся от громоздкости и неповоротливости кода. Но если есть ещё хоть одно (третье) прерывание, способное повлиять на работу первого, этот вариант отпадает. |
Автор: | Goldsmith [ Пн июл 23, 2012 23:43:39 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
DrHlus писал(а): Goldsmith писал(а): Можете рассказать об этом подробнее или кинуть ссылочку, где об этом можно почитать? Arnold S. Berger. Embedded Systems Design: An Introduction to Processes, Tools, and Techniques, раздел "Nested Interrupts and Reentrancy". Bruce Powel Douglass. Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems, раздел 7.2 "Critical Section Pattern". Jean J. Labrosse. Embedded Systems Building Blocks, Second Edition. Complete and Ready-to-Use Modules in C, раздел 2.11 "Reentrancy". Конечно, это не единственные источники, просто первое, что попалось под руку из книг о встроенных системах. Или можно почитать в учебниках по архитектуре операционных систем, там практически те же проблемы с реентерабельностью и во многом схожие методы решения. Или попробую коротко своими словами. Конечно, пример немного притянут за уши, но в целом ситуацию попробую обрисовать. Предположим, у нас есть таймер, генерирующий прерывания с частотой килогерц. Каждую тысячную миллисекунду счетчик миллисекунд обнуляется и увеличивается счетчик секунд: Код: void обработчик_прерывания_1кГц(void) { счетчик_миллисекунд++; if (счетчик_миллисекунд >= 1000) { // прошла секунда счетчик_миллисекунд = 0; счетчик_секунд++; } // еще какие-то действия } Предположим такую последовательность событий:
Итак, имеем все "прелести" вложеннного вызова нереентерабельного обработчика: потеряли миллисекунду (дважды обнулен счетчик), зато получили лишнюю секунду (дважды инкрементировали). Немного сумбурно и громоздко получилось, но, надеюсь, идея все же понятна. |
Автор: | Goldsmith [ Вт июл 24, 2012 00:21:34 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
ILYAUL писал(а): Насколько я помню , реентерабельность относится к одному и тому же куску кода , которым одновременно могут воспользоваться несколько пользователей не мешая друг другу , при этом на код накладывается куча условий. И как это понятие применимо к вложенным прерываниям? Наличие нескольких пользователей вовсе не обязательно, иначе получилось бы, что весь код в однопользовательской системе автоматически становится реентерабельным, а это отнюдь не так. Реентерабельный код может выполняться параллельно несколькими потоками в процессе одного пользователя и даже в одном потоке, если это рекурсивный вызов.Вот вполне корректное определение реентерабельности: Цитата: reentrant adj. Said of software that can be executed multiple times simultaneously. A reentrant function can be safely called recursively or from multiple tasks. The key to making code reentrant is to ensure mutual exclusion whenever accessing global variables or shared registers. Jack Ganssle, Michael Barr. Embedded Systems Dictionary.Вложенное прерывание именно к этому и приводит - поток выполнения инструкций входит в область кода, в которой уже находится другой поток (отложенный, если в системе единственное вычислительное ядро). Вы совершенно правильно заметили, что на этот код должны накладываться определенные условия, и если они не выполнены, программа ведет себя некорректно (пример я привел в предыдущем посте). Цитата: Что обычно делается процессором автоматически при входе в обработчик прерывания , если это прерывание разрешено или всё таки нет? Обычно в известных мне архитектурах (хотя, конечно, известны мне далеко не все) при входе в обработчик прерывания автоматически сбрасывается флаг запроса этого прерывания. Бит (он же флаг) разрешения прерывания остается неизменным, его следует устанавливать/сбрасывать явно в коде.
|
Автор: | Goldsmith [ Вт июл 24, 2012 00:44:16 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
ploop писал(а): Например: есть прерывание с относительно длительным обработчиком (и без него никак, либо очень сложно). Довольно часто (из собственной практики я бы даже сказал: "всегда", но жизнь зачастую оказывается разнообразнее наших представлений о ней) удается все же сократить обработчик прерывания до разумно-минимальных размеров, оставив в нем лишь действительно критичные по времени операции (например, забрать из регистров ввода данные, пока они не затерлись следующей порцией). Затем обработчик помещает событие в очередь и завершает работу. Обработкой данных из очереди займется уже другая задача в соответствии с назначенным ей приоритетом, которая никак не мешает прерываниям.Такой подход и пиковые всплески активности поможет пережить (буфер разумных размеров сгладит пик), и проблемы с битвой приоритетов позволит избежать, если нет требований крайне жесткого реального времени. Еще один бонус - небольшие аппаратно-зависимые функции обработки проще будет портировать на другую платформу при необходимости, если, конечно, они не на ассемблере писаны; обработчик очереди событий, выполняющий основную часть работы, не будет жестко связан с оборудованием. |
Автор: | ploop [ Вт июл 24, 2012 06:32:47 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Да это понятно всё. Я хотел сказать то, что вы в своём примере очень хорошо подчеркнули фразой "тем временем прошла миллисекунда", то есть второй обработчик может (т.е. такая ситуация в принципе возможна) перекрыть по времени первый. Тут да, применять не в коем случае нельзя. |
Автор: | Goldsmith [ Вт июл 24, 2012 08:12:19 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
ploop писал(а): Я хотел сказать то, что вы в своём примере очень хорошо подчеркнули фразой "тем временем прошла миллисекунда", то есть второй обработчик может (т.е. такая ситуация в принципе возможна) перекрыть по времени первый. Точно. К тому же пример-то специально упрощенный, чтобы читателям проще логику отследить. А если к тому же обработчиков не два, а поболее, да к тому же глобально прерывания постоянно разрешены, и любой обработчик в любой момент перебивается другим экземпляром, в том числе самим собой по вложенной обработке, то получим неиссякающий источник непериодических глюков, причем очень трудно воспроизводимых в системе отладки (а то, что возможно в принципе, все равно рано или поздно произойдет).Тут да, применять не в коем случае нельзя. Собственно, вот что имел в виду под фразой, которая и вызвала вопросы: Goldsmith писал(а): Помимо переполнения стека, есть еще одни грабли, на которые можно наступить, разрешая прерывания внутри обработчика. Если обработчик прерывания нереентерабелен (что вполне вероятно), то повторное прерывание, возникшее во время обработки предыдущего, приведет к непредсказуемым последствиям. Причем диагностировать такую ситуацию гораздо сложнее, чем переполнение стека.
|
Автор: | ploop [ Вт июл 24, 2012 08:38:46 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
В последнем проекте была ситуация: 1. Основной цикл. Куча математики, работает очень долго: где-то секунду на одну итерацию. Там же вывод на индикатор, что даёт естественную задержку его обновления около секунды. 2. Таймер, и его прерывание каждые 10мс (100 раз в секунду). Там тоже объёмный код, но работает фиксированное время, около 5-6мс (сам на себя наложиться не может. 3. Внешнее прерывание INTx, внутри которого несколько операций, т.е. считанные микросекунды. Всего два прерывания. Внутри прерывания таймера разрешил вложенные, и убил двух зайцев: таймер корректно работает, не усложняя основной цикл, и отработка внешнего прерывания происходит всегда вовремя. Можно было бы пересмотреть логику (изначально так и хотел), но это сильно бы усложнило код, учитывая, что он чисто на ассемблере, в итоге это вылилось бы в увеличение времени на написание и тестирование. Так что не так страшен чёрт, если подходить с умом. |
Автор: | Goldsmith [ Вт июл 24, 2012 09:22:15 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
ploop писал(а): Так что не так страшен чёрт, если подходить с умом. Тут ключевой момент:ploop писал(а): 2. Таймер ... сам на себя наложиться не может. С таймером проще: вы точно знаете период прерываний, и если так же точно знаете длительность его обработки (в обработчике нет циклов и непредсказуемых условных операторов), то можете дать гарантию, что повторного вхождения в обработчик не будет. Заведомо кратковременный другой обработчик также не создает проблем (если только по INTx гарантированно исключен шквал запросов). В данном частном случае проблема реентерабельности не возникнет, конечно.Если же событие асинхронное и возникает в непредсказуемые моменты, черт станет гораздо страшнее. Единственный способ не попасть в ловушку - запрещать повторное прерывание от этого же источника при входе в обработчик и разрешать (при необходимости) непосредственно перед выходом. Глобально прерывания запрещать не обязательно. Только в этом случае нереентерабельные обработчики не создадут проблем, о которых DrHlus спрашивал в начале темы. |
Автор: | ILYAUL [ Вт июл 24, 2012 11:40:49 ] |
Заголовок сообщения: | Re: AVR прерывание прерывания |
Цитата: ...Затем обработчик помещает событие в очередь и завершает работу. Ну вообще-то это стандартный подход к написанию обработчиков прерываний. Цитата: ...проще будет портировать на другую платформу при необходимости, если, конечно, они не на ассемблере писаны; Это Вы давненько с asm не работали, портировать его с платформы на платформу не так уж и сложно. Главное правильно сразу написать макросы. |
Страница 1 из 3 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |