Цитата(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. Но жизнь намного сложнее, чем мы ее представляем. Случаи -- они всякие бывают, и дать конкретный совет на все случаи жизни -- ну просто не возможно.
Кроме того, учтите, что флаг некоторых прерываний сбрасывается как только вызывается их обработчик, а у иных флаг нужно сбрасывать программно -- записью в соответствующий регистр.