Когда нужно использовать метод опроса и когда нужно использовать основанный на прерывании метод? Есть ли сценарии, в которых оба могут использоваться?
Если интересующее событие:
, то обработчик на основе прерывания имеет смысл.
Если интересующее событие:
, тогда опрос может быть более подходящим.
Также необходимо учитывать, пишете ли вы драйвер устройства для ОС или просто пишете код без поддержки потоков. В ситуациях с голым железом процессор часто просто зацикливается, когда он не занят, поэтому он может что-то опрашивать.
Короткий ответ - использовать метод прерывания, когда опрос слишком медленный. (под слишком медленным, я имею в виду, что если опрос теряет данные, метод прерывания необходим)
В основном, режим опроса используется в том случае, если режим прерывания недоступен по каким-то аппаратным или программным причинам. Таким образом, режим прерывания более предпочтителен с точки зрения энергопотребления, производительности и т.д. (согласен с Paul R). Опрашиваемый режим также может быть использован при создании прототипов, для ядер без периферии и для некоторых целей тестирования.
Иногда вам действительно нужно использовать оба варианта. Например, если события спорадические, но приходят с высокой скоростью; вам может потребоваться сначала ответить на прерывание, а затем перед повторным включением прерывания опросить, не произошло ли уже другое событие, избегая некоторых накладных расходов на переключение контекста прерывания. Я полагаю, что сетевой интерфейс Linux работает в этом режиме.
Прерывания предпочтительнее, когда требуется низкая задержка. Если вы опрашиваете какое-либо условие N раз в секунду, то в среднем вы обнаружите это условие через половину 1 / N после того, как оно действительно произошло.
Иногда предпочтение отдается опросу, когда требуется абсолютная детерминированная синхронизация. По самой своей природе прерывания могут происходить в непредсказуемое время и значительно усложнять временной анализ, тогда как с системами с опросом относительно легко сделать доказуемые утверждения об удовлетворении крайнего срока.
По возможности следует избегать опроса, поскольку он, как правило, потребляет много циклов ЦП без надобности (кроме случаев (а) вы собираетесь проводить опрос только на короткое время или (б) вы можете позволить себе поспать в течение разумного времени в ваш цикл опроса). Потеря циклов ЦП вредна не только с точки зрения производительности, но также приводит к увеличению энергопотребления, что вполне может быть проблемой для встроенных приложений с батарейным питанием.
Всегда используйте прерывание. Так вы никогда не потеряете данные. В приложениях, управляемых событиями или потоками, даже самые медленные сигналы должны управляться прерываниями.
Единственный случай, когда следует использовать опрос - это когда вы используете планировщик и буферы вашего оборудования достаточно глубоки, чтобы не потерять данные.
Принимая решение об опросе или прерывании, вы должны полностью понимать природу события, за которым вы пытаетесь следить, и свой ответ на него.
Прерывания не требуют обработки, когда ничего не происходит, но требуют всего вашего внимания, когда что-то происходит. Если событие является внешним и имеет шумные фронты или быстрые импульсы, это может вызвать серьезные проблемы с прерываниями, вы должны быть осторожны с настройкой прерываний.
В этом примере процедура прерывания реагирует на прохождение лазерного луча и настраивается на событие, при котором он блокируется:
BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/
/*Set the beam interrupt for the next clear to blocked event*/
BEAM_INTR_EDGE = CLEAR_TO_BLOCKED;
BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/
У этого кода есть 2 слабых места: 1) Если лазерный луч снова заблокировался до сброса флага прерывания (BEAM_INTR_FLAG = FALSE;). Прерывание будет пропущено, и код будет не синхронизирован с состоянием лазерного луча.
2) При настройке прерываний либо в фоновой программе, либо для более высокого приоритета, чем приоритет этого кода, необходимо соблюдать осторожность при разрешении прерывания. Если флаг прерывания был уже установлен (неправильно) до его включения, процедура прерывания будет вызываться неправильно, как только она будет включена, и, возможно, для неправильного фронта.
Самый простой способ исправить 1) - это дважды проверить после установки прерывания, если оно произошло, принудительно прервать его. Чтобы исправить 2) переместите разрешение прерываний на после двойной проверки:
/*Set the beam interrupt for the next clear to blocked event*/
BEAM_INTR_EDGE = CLEAR_TO_BLOCKED;
BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/
/*Double check beam state to see if it has already gone blocked*/
if (BEAM_STATE == BEAM_BLOCKED)
{
BEAM_INTR_FLAG = TRUE; /*Force the interrupt to re-enter the ISR after exiting*/
}
BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/
Форсирование прерывания заставляет систему работать с тем же конечным автоматом, просто заставляя его вручную обходить слепое пятно.
В основном:
Set the edge to detect the next interrupt event
Clear the interrupt flag
if (the event has already occurred)
{
Set the interrupt flag to force the interrupt
}
Enable the interrupt
Если время ответа на событие должно быть согласованным (например, 1 мс +/- 10 мсек после того, как линия ввода перейдет в высокий уровень, передать сигнал события), то обычно лучше всего использовать прерывания.
Если время реакции на событие должно быть в пределах определенного времени (например, в пределах 1 мс после того, как входная линия перейдет в высокий уровень, передать сигнал события), то лучше всего будет прерывание.
Проблема с прерываниями заключается в том, что вы должны начать думать о многопоточности и о том, что два фрагмента кода могут получить доступ к одним и тем же данным одновременно.
Прерывания также хороши для того, чтобы позволить процессорам перейти в режимы низкого энергопотребления (спящий / бездействующий и т. Д.), Ожидая, что что-то произойдет.
С учетом всего сказанного, опрос может дать очень сжатые по времени ответы на события, если процессор должен сделать только одну вещь, часто аппаратному обеспечению прерывания требуется несколько циклов, чтобы отреагировать на событие, в то время как жесткий цикл опроса подойдет.
Если событие не является критическим по времени и потенциально шумным (например, кто-то нажимает переключатель), то опрос позволяет выполнять простую фильтрацию без пропуска долгосрочных переходов. Распространенной ошибкой является многократный опрос при настройке:
void fnInitialiseSystem(void)
{
if (MODE_INPUT == MODE_A) /*First polling of the MODE_INPUT*/
{
PR2 = PR2_MODE_A;
}
else
{
PR2 = PR2_MODE_B;
}
OpenTimer2( TIMER_INT_ON &
T2_PS_1_1 &
T2_POST_1_8 );
if (MODE_INPUT == MODE_A) /*Second polling of the MODE_INPUT*/
{
CurrentMode = MODE_A;
PROBE_INT_EDGE = CLEAR_TO_BLOCKED;
}
else
{
CurrentMode = MODE_B;
PROBE_INT_EDGE = BLOCKED_TO_CLEAR;
}
}
В приведенном выше примере MODE_INPUT является внешним переключателем, если два раза опрашивается MODE_INPUT, различаются, то поведение является неожиданным. При чтении таких сигналов лучше всего использовать фильтрацию, чтобы определить долгосрочное состояние входа и выполнить действия с отфильтрованной версией.
Например, с отключением переключателя просто проверяйте переключатель регулярно (каждые 1 мс?), И если их количество (скажем, 16) отличается (переключатель закрыт) от фильтрованной версии (переключатель открыт), обновите результат и выполните требуемое действие. Будьте осторожны с наложением сигналов, колебательный сигнал может выглядеть стабильным!
Примером использования опроса и прерываний, опять же, является использование входа, который не часто меняется, но при этом шумит.И снова переключатель является хорошим примером этого: код может настроить прерывание для проверки изменения состояния переключателя, когда происходит прерывание, тогда переключатель может регулярно опрашиваться, пока состояние переключателя не станет «стабильным» (либо изменено состояние или вернуться к тому, что было). Это дает преимущество в виде низких накладных расходов на обработку, когда ничего не происходит, и фильтрации шума, когда что-то происходит.
Режим опроса может быть полезен в системах с высокочастотными событиями, где накладные расходы связаны с вход и выход из обработчиков прерываний требует больше циклов ЦП, чем простой опрос. Например, в IP-маршрутизаторе может использоваться опрос, чтобы максимизировать пропускную способность ЦП, доступную для обработки пакетов.
Есть много конструктивных ограничений, которые могут повлиять на решение. В моем приложении есть комбинация прерывания и опроса:
Вот несколько интересных ссылок, на которые я наткнулся при анализе методов опроса и прерывания -
http://web.engr.oregonstate.edu/~traylor/ece473/lectures/interrupts.pdf - Очень интересная ссылка
http://www.atarimagazines.com/compute/issue149/60_Interrupts_made_easy.php
http://www.electro-tech-online.com/micro-controllers/8440-interrupt-vs-polling.html
http://www.microchip.com/forums/m397196-print.aspx
http://www.cs.huji.ac.il/course/2006/67630/Lectures/interrupts.pdf
http://sunsite.nus.edu.sg/LDP/LDP/tlk/node86.html
Надеюсь, это будет полезно.