Инструкция AVR SEI

13

Инструкция AVR SEI ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html ) ожидает завершения следующей инструкции перед включением прерываний.

Если я использую другую инструкцию для установки флага I в SREG, будет ли это ждать 1 инструкцию?

Другими словами: ожидание - это особенность инструкции SEI или регистра состояния?

Если это особенность инструкции SEI, то в какой момент фактически устанавливается флаг, в цикле, который выполняет SEI или со следующей инструкцией?

Джей Джей
источник
Это отличный вопрос, но его не должно быть слишком сложно проверить и убедиться.
Vorac
1
@Vorac Можете ли вы привести пример того, как это можно проверить? Это был бы мой принятый ответ наверняка.
Джей Джей
1
Это может быть особенностью реализации архитектуры AVR, и где прерывания могут быть обработаны. IIRC, архитектура AVR использует 3-х ступенчатый конвейер. Таким образом, следующая команда может быть уже «в полете» (т. Е. На первом этапе конвейера или далее), прежде чем изменение флага I можно будет использовать для проверки прерываний. Я давно не искал, но не думаю, что разработчики архитектуры AVR чрезмерно ограничились бы. Таким образом, тестирование прерывания для инструкции на этапе 1 конвейера, а не перед следующей инструкцией (на этапе 2) дает им некоторую гибкость.
gbulmer

Ответы:

8

Эмпирические результаты!

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

Этот вопрос заслуживает окончательного ответа, поэтому давайте вытащим AVR и начнем устанавливать некоторые биты!

Процедура

Для тестирования я сделал небольшую программу Arduino (ATMEGA328P), которая ...

  1. установить ISR, который никогда не вернется ( while (1))
  2. назначил ISR источнику, который я мог вызвать в программном обеспечении ( INT0понижается)
  3. отключенные прерывания
  4. включил и вызвал прерывание, так что оно будет в ожидании

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

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

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

Результаты

SEI инструкция (базовый вариант)

Код:

sei

Результат: светодиод включен. Следующая инструкция выполнена.

OUT инструкция

Код:

in  r16,0x3f   // Get SREG
ori r16,128    // Set I bit 
out 0x3f,r16   // Save back to SREG

Результат:

Светодиод включен. Следующая инструкция выполнена.

ST инструкция

Код:

   clr r29        // Clear Y high byte
   ldi r28,0x5f   // Set Y low byte to point to SREG
   ld r16, Y      // Get SREG
   ori r16,128    // Set I bit 
   st Y,r16       // Put SREG

Результат:

Светодиод включен. Следующая инструкция выполнена.

Вывод!

В: Ожидание - это функция инструкции SEI или регистра состояния?

A: Похоже, что изменение Iбита в SREGis с a 0на a 1позволит следующей команде выполнить следующую, даже если есть ожидающее прерывание, независимо от того, какая команда используется для установки бита.

Примечания

Это на самом деле превратилось в очень интересный вопрос с множеством осложнений. Если вы заинтересованы в деталях, проверьте ...

http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/

bigjosh
источник
2
Когда спецификация неоднозначна, возникает проблема с «эмпирическими результатами». Просто потому, что конкретная часть оборудования, которую вы тестировали, работает определенным образом, не означает, что другие части будут работать таким образом. Atmel может изменить реализацию, если она не меняет спецификацию. Итак, «Там, где документация неоднозначна,…» остается точно, что после экспериментов и испытаний она остается двусмысленной.
gbulmer
@gbulmer Я согласен на 100%. Тот, кто использует недокументированные функции в производстве, обязательно будет грустным. По-прежнему интересный эмпирический вопрос (и ответ), и, вероятно, можно рассчитывать на разовый личный проект.
bigjosh
Да, вы провели увлекательное расследование.
gbulmer
4

seiНасколько я понимаю из документации, выполнение инструкции ничем не отличается от прямой записи 1 в I бит SREG. Преимущество инструкции в том, что вам не нужно сначала загружать значение 1<<Iв рабочий регистр, чтобы изменить SREG, что экономит время.

Разработать, используя sei:

sei ; One cycle

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

sbi SREG,7 ; Two cycles

Пишу я немного в SREG:

in  r24,SREG ;
ori r24,0x80 ;
out SREG,r24 ; Three cycles

IБит должен быть установлен в SREG как только seiинструкции (или sbiили out) Завершает. Однако любые ожидающие прерывания не будут обрабатываться до тех пор, пока не будет выполнена следующая инструкция - бит будет установлен, но для включения прерываний требуется дополнительный цикл. Поскольку прерывание не может быть обработано в середине инструкции, а для выполнения некоторых инструкций требуется более одного цикла, в качестве одной инструкции указывается время, необходимое для включения. Это должно иметь место для всех версий кода - то есть каждая из вышеупомянутых причин приведет к задержке инструкции.


После небольшого поиска я нашел эту ветку на форуме Arduino, в которой было проведено несколько различных тестов для проверки поведения. Кажется, согласен с тем, что я сказал выше.

Кроме того, согласно этому потоку, если Iфлаг уже установлен, то отсроченный отклик прерывания не вызывается, из seiчего следует, что отсроченный отклик вызван не самой инструкцией, а скорее во внутреннем оборудовании, контролируемом Iфлагом - поэтому любая операция , которая изменяет флаг в SREG, будь то seiили outили stsбудет иметь точно такое же поведение.

Том Карпентер
источник
Таким образом, нет никакого аспекта задержки операции, специфичной для SEI, но не для OUT, которая позволяет выполнить следующую инструкцию?
Брайан Драммонд
В случае вашего второго примера, когда обрабатывается ожидающее прерывание? Есть ли задержка цикла, как в первом?
Джей Джей
@jayjay посмотри мое обновление.
Том Карпентер
1
Обратите внимание, что SBIэтот Iбит не может использоваться для установки бита, SREGпоэтому любой код, который делает это, скорее всего, на самом деле не тестировался в реальной жизни, потому что он даже не будет собираться. SBIможет работать только на нижних 32 регистрах, а SREG находится в слоте 63.
bigjosh
@bigjosh Пример SBI, о котором я подумал позже, - outтот, который я использовал изначально. Я думал, что я столкнусь с AVR (может быть ATTiny), который имеет SREG в нижних 32 регистрах, но я могу себе это представить.
Том Карпентер
1

ИМХО делает запись в SREG все еще с задержкой 1 инструкция может быть проверена так (псевдокод):

ISR() { PORTA = 0; while(1); }
main() 
{
    cli();
    DDRA = 0xff;
    configure_isr_for_level_interrupt_that_will_trigger_immediately();
    SREG = 0xff;
    cli();
    PORTA = 0xff;
    while(1);
}

К сожалению, мне не хватает времени, чтобы сделать это :(

Vorac
источник
0

Это не то, что он говорит. Документация говорит

Инструкция, следующая за SEI, будет выполнена перед любыми ожидающими прерываниями.

не то чтобы он ждал следующей инструкции. Я прочитал это, поскольку флаг установлен немедленно, но даже если он включен, никакие прерывания не будут обрабатываться до тех пор, пока не будет выполнена следующая инструкция.

patthoyts
источник
Это все правда, но мой вопрос: это поведение специфично для SEI?
Джей Джей
@jayjay Я подозреваю, что это связано с длиной конвейера инструкций
сбой