Подтвердить что ты не робот

Прерывания прерывают другие прерывания на Arduino?

У меня есть Arduino Uno (удивительное небольшое устройство!). Он имеет два прерывания; назовите их 0 и 1. Я подключаю обработчик для прерывания 0, а другой - для прерывания 1, используя attachInterrupt(): http://www.arduino.cc/en/Reference/AttachInterrupt.

Прерывание 0 запускается, и он вызывает его обработчик, который выполняет некоторое количество хрустов. Если прерыватель 0 обработчик все еще выполняется при прерывании 1, что произойдет?

Прервет прерывание прерывания 1 0 или прервет 1 до тех пор, пока не будет выполнен обработчик прерывания 0?

Обратите внимание, что этот вопрос конкретно относится к Arduino.

4b9b3361

Ответ 1

На аппарате Arduino (aka AVR) вложенные прерывания не происходят, если вы не намеренно создаете условия, позволяющие ему произойти.

Из avr-lib:

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

(источник: http://linux.die.net/man/3/avr_interrupts)

Ответ 2

Прервет 1 прерывание прерывания 0 или прервет 1 до тех пор, пока не будет выполнен обработчик прерывания 0?

Если вы специально не активируете прерывания внутри ISR (Interrupt Service Routine), то все прерывания в настоящее время завершаются, плюс еще одна инструкция машинного кода, прежде чем обслуживается следующее прерывание.

Большинство прерываний устанавливают флаг внутри процессора, который проверяется между инструкциями, чтобы проверить, следует ли обслуживать прерывание. Флаги проверяются в порядке приоритета. На Uno:

 1  Reset 
 2  External Interrupt Request 0  (pin D2)          (INT0_vect)
 3  External Interrupt Request 1  (pin D3)          (INT1_vect)
 4  Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
 5  Pin Change Interrupt Request 1 (pins A0 to A5)  (PCINT1_vect)
 6  Pin Change Interrupt Request 2 (pins D0 to D7)  (PCINT2_vect)
 7  Watchdog Time-out Interrupt                     (WDT_vect)
 8  Timer/Counter2 Compare Match A                  (TIMER2_COMPA_vect)
 9  Timer/Counter2 Compare Match B                  (TIMER2_COMPB_vect)
10  Timer/Counter2 Overflow                         (TIMER2_OVF_vect)
11  Timer/Counter1 Capture Event                    (TIMER1_CAPT_vect)
12  Timer/Counter1 Compare Match A                  (TIMER1_COMPA_vect)
13  Timer/Counter1 Compare Match B                  (TIMER1_COMPB_vect)
14  Timer/Counter1 Overflow                         (TIMER1_OVF_vect)
15  Timer/Counter0 Compare Match A                  (TIMER0_COMPA_vect)
16  Timer/Counter0 Compare Match B                  (TIMER0_COMPB_vect)
17  Timer/Counter0 Overflow                         (TIMER0_OVF_vect)
18  SPI Serial Transfer Complete                    (SPI_STC_vect)
19  USART Rx Complete                               (USART_RX_vect)
20  USART, Data Register Empty                      (USART_UDRE_vect)
21  USART, Tx Complete                              (USART_TX_vect)
22  ADC Conversion Complete                         (ADC_vect)
23  EEPROM Ready                                    (EE_READY_vect)
24  Analog Comparator                               (ANALOG_COMP_vect)
25  2-wire Serial Interface  (I2C)                  (TWI_vect)
26  Store Program Memory Ready                      (SPM_READY_vect)

(Обратите внимание, что Reset невозможно замаскировать).

Возможно, будет выполняться прерывание низкого уровня (например, TIMER0_OVF_vect). Хотя он занят своими делами, может произойти несколько других событий прерывания (и установить соответствующие биты в CPU). Они будут обслуживаться в указанном порядке, а не в том порядке, в котором они действительно происходят вовремя.

Есть аппаратные регистры, которые могут быть записаны, чтобы отменить ожидающее прерывание - то есть, чтобы очистить флаг.


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

Это позволяет вам писать код следующим образом:

  interrupts ();             // guarantees next instruction executed
  sleep_cpu ();              // sleep now

Без этого может произойти прерывание перед сном. Это означает, что вы никогда не проснулись, потому что вы полагались на прерывание, возникающее во время сна, а не раньше.


Как удивительно глупость Freescale и Atmel для обоих используют одни и те же имена команд, но с инвертированными значениями

Вот почему я предпочитаю мнемонику interrupts и noInterrupts, потому что намерение там очень ясно. Они реализуются посредством определений в основных файлах include.

Ответ 3

В документации упоминается, что прерывания Arduino имеют приоритет:

Если ваш эскиз использует несколько ISR, одновременно может выполняться только один. Другие прерывания будут выполнены после того, как текущее прерывание завершится в порядке, который зависит от их приоритета.

Он также предоставляет ссылку для дополнительной информации:

Для получения дополнительной информации о прерываниях см. Заметки Ника Гэммона.

В соответствии с разделами Что такое приоритет прерывания? и могут ли прерывания происходить, пока они отключены? мы можем сделать вывод, что:

  1. Прерывания основаны на списке флагов. Когда происходит событие, устанавливается соответствующий флаг.
  2. Если IRS не может выстрелить прямо сейчас, его можно вызвать в любое время позже, потому что флаг сохранен.
  3. Существует список всех доступных прерываний, и он, как правило, зависит от чипа. Чем выше список, тем выше приоритет.

Таким образом, различные прерывания не будут прерывать друг друга. Они будут выполнены в соответствии с их приоритетом.