Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Время работы прерывания
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
d7d1cd
Привет всем. Возник такой вопрос: что если обработка прерывания занимает много времени. Допустимо ли такое?
zhevak
Цитата(d7d1cd @ Sep 12 2012, 12:38) *
Привет всем. Возник такой вопрос: что если обработка прерывания занимает много времени. Допустимо ли такое?

Дык-ить!
А что не допустимо-то? -- Допустимо!

Ну не приходит долго автобус/троллейбус, и что? -- А ничего. Вы просто сидите на лавочке и тупо ждете. Но ничего в Вашей жизни не меняется.

<МОДЕРАТОРАМ: сюда я хотел поставить тег подката, но не нашел его.>

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

Вы ведь не просто так прерывания вводите в МК? Прерывания должны отрабатывать какие-то события. Вообще-то предполагается, что события возникают в системе не очень часто... поэтому у МК есть огромная куча свободного времени.

Возникшее в системе событие вызывает прерывание. Обычно бывает так, что это событие порождает в системе вторичные события. Вторичные события как правило не требуют мгновенной отработки. Их можно выполнить чуть позже, например, когда проц освободится.

Например, проц следит за коротким замыканием в цепи какого-нибудь источника питания. (Это гипотетический пример. Я его привожу только для того чтобы показать как это делается "по науке".) При возникновении к.з. проц должен отключить некоторую цепь, зажечь светодиод и издать звуковой сигнал. Разберемся, что более важно для обработки.

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

CODE

// Прерывания с датчика короткого замыкания.
// Работаем быстро и четко. Ничего лишнего не делаем. Мы -- спасатели, а не муниципальные буквоеды.
ISR обработчик_прерывания(void)
{
PORT_1 = 0x00; // Быстро отрубить цепь, чтобы ничего не сгрело
flag_short = 1; // Установить в системе флаг, что в источнике питания произошло короткое замыкание
}

int main(void)
{
...
while (1) // бесконечный цикл
{
// Мы -- муниципальные службы. Мы -- бюрократы. Мы можем долго и тщательно обрабатывать поступающуие к нам письма трудящихся.
// Наша задача -- обеспечить правильное функционирование системы, делать упорядоченно, а не делать все быстро.
...
if (flag_short == 1)
{
// Оба-на! Да это же было кз!
// Преступники пойманы, авария ликвидирована спасателями. Наша функция -- сообщить в СМИ и принять меры,
// провести судебные разбирательства.
flag_short = 0; // Депеша (уведомление, сигнал, телеграмма) о кз принят,
PORT_2 = LED; // зажечь ЛЭД
beep(); // Пикнуть
}
// продолжаем фоновую работу
...
}
}


Теперь. если возникает событие, то обработчик прерывания сначала обесточит критические цепи. А уж когда процессор соизволит бибикнуть и зажечь светодиод, это не совсем важно. Это все равно произойдет, но произойдет намного позже. И от того, что произойдет даже на 0.1 секунду позже ничего страшного.

К стати, важно помнить, что прерывания запрещаются, когда программа находится в каком-либо обработчике прерываний. И если в момент выполнения прерывания возникает какое-то другое, то взводится только его флаг, а сам обработчик прерывания не вызывается. Он вызовется только после того, как вы покините обработчик этого (текущего) прерывания. Иначе говоря, если вы надолго зависли в одном прерывании, то другое будет отложено. Ну либо разрешайте вложенные прерывания, хотя это и не совсем правильный подход для таких процов как мсп430. Но жизнь намного сложнее, чем мы ее представляем. Случаи -- они всякие бывают, и дать конкретный совет на все случаи жизни -- ну просто не возможно.

Кроме того, учтите, что флаг некоторых прерываний сбрасывается как только вызывается их обработчик, а у иных флаг нужно сбрасывать программно -- записью в соответствующий регистр.
d7d1cd
Спасибо за столь подробное пояснение. Подскажите как разрешить\запретить вложенные прерывания.
_Артём_
Цитата(d7d1cd @ Sep 12 2012, 18:45) *
Подскажите как разрешить\запретить вложенные прерывания.

Предположу что вложенные прерывания разрешаются также как просто прерывания.
Что-нибудь типа __enable_interrupt();
Но возможно стоит запретить прерывание, обработчик которого выполняется, чтобы исключить его повторное срабатывание.
d7d1cd
А __enable_interrupt(); это установка какого бита в каком байте?
zhevak
Цитата(d7d1cd @ Sep 12 2012, 21:45) *
Спасибо за столь подробное пояснение. Подскажите как разрешить\запретить вложенные прерывания.

В составе ЦПУ MSP430 имеется регистр SR (другое название --R2) -- это регистр состояния процессора. Регистр состоит из множества флагов (бит), которые индицируют и управляют работой ЦПУ. Среди этих флагов есть флаг, отвечающий за глобальное разрешение прерываний. На него как бы сходятся все индивидуальные прерывания -- от портов, от таймеров, от компаратора, от АЦП и т.д. Прерывание от каждого устройства подчиняется своим индивидуальным флагам разрешения. Но все прерывания подчиняются одному глобальному флагу разрешения прерываний. В качестве некоторого аналога такой системы прерываний можно рассматривать как систему электроснабжения -- множество выключателей в комнатах и один общий рубильник. Разница только в направлении распространения воздействия: в электрической разводке энергия поступает от общего рубильника ко индивидуальным выключателям, а в системе прерываний МК -- прерывания транслируются в обратном направлении -- от периферийных устройств к глобальному флагу разрешения прерываний.

Когда этот флаг опущен (бит GIE равен "0") в системе не возникнет ни одно прерывание. Иначе говоря, если процессор выполняет какую-то программу, то она гарантированно не будет прервана, ни один обработчик прерываний не будет вызван. (Правда, в MSPЗ430 есть еще и не маскируемые прерываний, но этот случай лучше рассмотреть как-нибудь потом.)

Допустим, Вы пишите свою прогу. Прежде чем войти в бесконечный цикл (в функции main), Вы должны разрешить прерывания. Тогда Ваша прога, выполняя свою основную (фоновую) задачу, будет способна быстро реагировать на возникающие в системе события. "События" -- это различные внезапные (неожиданные) изменения чего-нибудь, например, счетчик до считал до конца или на входе порта изменился уровень сигнала. События (создают, провоцируют, генерируют) приводят к прерываниям работы основной (фоновой) программы.

Если поднят флаг GIE и разрешено индивидуальное прерывание от события (от устройства), то ход исполнения основной программы прерывается и вызывается код обработчика этого прерывания.

Непосредственно перед входом в обработчик прерывания происходит следующее (упрощено):
- в стеке сохраняется адреса программы, где произошло ее прерывание,
- в стек помещается состояние процессора (регистр SR),
- регистр SR очищается (обратите внимание -- в том числе сбрасывается и флаг глобального разрешения прерываний -- GIE. А это значит, что уже никакие другие прерывания не будут отрабатываться),
- и наконец вызывается обработчик прерывания.

При выходе из обработчика прерывания из стека восстанавливается состояние регистра состояния SR. Но сохраненное в стеке состояние регистра SR имеет поднятый флаг GIE, таким образом получается, что при выходе из прерывания автоматически снова разрешаются прерывания. Но пока исполняется код обработки прерывания другие прерывания запрещены.

Но Вы -- программист. Вы -- автор своего проекта, Вы знаете что вы делаете. И если Вам так необходимо обрабатывать вложенные прерывания, то Вы можете разрешить их -- установив снова флаг глобального разрешения прерываний GIE в своем обработчике прерываний.

Как устанавливается этот флаг -- зависит от компилятора. Например, в msp-gcc я это делаю с помощью команды __bis_SR_register(GIE), в IAR-е это можно сделать командой _EINT(). Вам лучше посмотреть в документацию компилятора, который Вы используете.

Единственное, о чем бы я хотел Вас предупредить, -- не увлекайтесь вложенными прерываниями! Если у Вас возникает такая необходимость -- значит, Вы идете не той дорогой! Это еще не ошибка, но это уже знак "Впереди опасность!"

Извините, что много написал. Рассчитывал не только на Вас. Многим школьникам и студентам, думаю, поможет правильно ориентироваться в прерываниях.
_Артём_
Цитата(zhevak @ Sep 12 2012, 19:47) *
Единственное, о чем бы я хотел Вас предупредить, -- не увлекайтесь вложенными прерываниями! Если у Вас возникает такая необходимость -- значит, Вы идете не той дорогой! Это еще не ошибка, но это уже знак "Впереди опасность!"

В чём опасность состоит?
Вложенные прерывания - штатное средство в том же IAR AVR (думаю и в MSP аналогично).
Создатели процессоров и компиляторов её заложили почему-то...
Отчего же не использовать?

P.S. Жить вообще опасно - все там будем.
d7d1cd
Спасибо за статью! Все доходчиво и понятно.
zhevak
Цитата(_Артём_ @ Sep 13 2012, 06:06) *
В чём опасность состоит?
Вложенные прерывания - штатное средство в том же IAR AVR (думаю и в MSP аналогично).
Создатели процессоров и компиляторов её заложили почему-то...
Отчего же не использовать?

P.S. Жить вообще опасно - все там будем.

Троллите?

Когда вы чините розетку, тоже подвергаете жизнь свою опасности, хотя производители розеток и заложили в них штатную возможность разбирать их. Зачем-то они это сделали? Однако, мы все тут "электрически" грамотные люди и все прекрасно понимаем, что перед тем как лезть отверткой в розетку нужно отключить на щитке электроэнергию. Еще более грамотные электрики повесят на щиток табличку "Не включать! Работают люди." и убедятся с помощью тестера, что отрубили именно эту розетку, а не в соседней комнате. Для нас это все элементарно. Поэтому, никакой опасности в починке розетки -- нет.

А теперь, уважаемый Артем, представьте пацана 3-4 лет, который до прихода мамы решил починить розетку. Сделать, так сказать маме сюрприз.

Надуманно? -- Ничуть! У моего брата пацанёнок примерно того же возраста уронил внутрь ЛАТР солдатика и полез голой рукой его оттуда доставать... У Вас есть дети?

Это вы, Артем, такой грамотный... ну, может быть, ещё я... и Вы понимаете, как работают прерывания, и для Вас всё это -- семечки! Но на форум помимо Вас приходит много "зеленого" народа. Это для них, еще знакомящихся с прерываниями, было сказано. Вы разве не поняли, что Вы съели детское питание? Про опасность я не для Вас писал.

А жить -- жить не опасно! Жить -- прикольно и просто замечательно! Жизнь -- это сумасшедший 3D мега-драйв с персональным участием в качестве главного героя! Все натурально и неповторимо. Где вы еще такое кино получите? Жизнью нужно наслаждаться и не вздрагивать по поводу смерти. Фильм все равно когда-нибудь да закончится. "Momento more" -- помни о смерти! Просто помни об этом, но не бойся её! Никто еще не жил вечно. Все рано или поздно умирали. Поэтому глупо бояться неизбежного. И также глупо передергивать смысл сказанного и троллить.
_Артём_
Цитата(zhevak @ Sep 13 2012, 22:45) *
Это вы, Артем, такой грамотный... ну, может быть, ещё я... и Вы понимаете, как работают прерывания, и для Вас всё это -- семечки!

Да нынче все грамотные, тем более на Форума разработчиков электроники.

Цитата(zhevak @ Sep 13 2012, 22:45) *
Троллите?

Ну ... может и так.
Так уж получилось. Звиняйте.
Dog Pawlowa
Цитата(_Артём_ @ Sep 13 2012, 03:06) *
В чём опасность состоит?

Стоит перечитать "Насморк" Станислава Лема sm.gif
Опасностей море.
Я лично влетел с вложенными прерываниями после появления новых люминесцентных ламп, излучающих и в ИК диапазоне.
Мой самописный IrDA рухнул, прибор нанес прямой материальный ущерб.
_Артём_
Цитата(Dog Pawlowa @ Sep 16 2012, 07:36) *
Я лично влетел с вложенными прерываниями после появления новых люминесцентных ламп, излучающих и в ИК диапазоне.

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

Цитата(Dog Pawlowa @ Sep 16 2012, 07:36) *
Мой самописный IrDA рухнул, прибор нанес прямой материальный ущерб.

Не было запрета на повторный вызов обработчика?
Dog Pawlowa
Цитата(_Артём_ @ Sep 16 2012, 17:18) *
Не было запрета на повторный вызов обработчика?

Запрета не было, частота "нормальных" импульсов была меньше с запасом в 10 раз. Проблема с "ненормальными" импульсами обнаружилась через пять! лет начала производства, в одном помещении новой больницы.
Потом я ввел запреты повтора вхождения, специальный запрет вообще прерывания, но было уже поздно - заказчик увидел, что проблемы растут комом, интерфейс работает неустойчиво, и я грохнул IrDA вообще.
В принципе подоспели нетбуки, которые заменили PDA с IrDA.
_Артём_
Цитата(Dog Pawlowa @ Sep 16 2012, 20:59) *
Потом я ввел запреты повтора вхождения, специальный запрет вообще прерывания,

C асинхронными прерываниями такое возможно - вдруг как попрут с частотой в сколько-то раз больше положенной. Тут и запрет вхождения проблему не решит до конца. Можно пытаться ограничавать число срабатываний за интервал времени, например.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.