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

Scott Holden запись в блоге на том, когда к (и если не к) GC.Collect вызова характерен для .NET Компактная Платформа , но правила обычно относятся ко всей управляемой разработке.

22
задан Peter Mortensen 27 February 2011 в 14:12
поделиться

3 ответа

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

Из avr-lib:

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

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

25
ответ дан 29 November 2019 в 05:18
поделиться

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

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

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

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

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

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

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

1
ответ дан 29 November 2019 в 05:18
поделиться

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

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

Большинство прерываний устанавливают флаг внутри процессора, который проверяется между инструкциями, чтобы увидеть, нужно ли обслуживать прерывание. Флаги проверяются в приоритетном порядке. На 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)

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

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

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


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

Это позволяет вам написать код, подобный этому:

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

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


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

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

4
ответ дан 29 November 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: