Інструкція AVR SEI


13

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

Якщо я використовую іншу інструкцію для встановлення прапора I у SREG, це також буде чекати 1 інструкції?

Іншими словами: Чи є функція очікування інструкцією SEI чи реєстром статусу?

Якщо це особливість інструкції SEI, то в який момент фактично встановлюється прапор, в циклі, який виконує SEI або з наступною інструкцією?


Це велике запитання, але це не повинно бути занадто важким для перевірки та бути впевненим.
Vorac

1
@Vorac Чи можете ви навести приклад того, як це можна перевірити? Це була б моя прийнята відповідь точно.
jayjay

1
Це може бути особливістю реалізації архітектури AVR, і там, де можна обробляти переривання. IIRC, архітектура AVR використовувала 3-ступінчастий трубопровід. Отже, наступна інструкція може бути вже "під час польоту" (тобто на стадії конвеєра або далі), перш ніж зміна прапора I може бути використана для перевірки на наявність перерв. Я давно не шукав, але не думаю, що дизайнери архітектури AVR надмірно обмежували б себе. Отже, тестування переривання для інструкції на етапі 1 трубопроводу, а не перед наступною інструкцією (на етапі 2) надає їм певної гнучкості.
габлмер

Відповіді:


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 або реєстром статусу?

Відповідь: Здається, що зміна Iбіта на " SREGa" 0на " 1" дозволить наступній інструкції виконати наступну, навіть якщо є очікуване переривання, незалежно від того, яка інструкція використовується для встановлення біта.

Примітки

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

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


2
Коли специфікація неоднозначна, виникає проблема з "Емпіричними результатами". Просто тому, що конкретний апарат, який ви перевірили, працює певним чином, не означає, що інші частини працюватимуть таким чином. Atmel можуть вільно змінити реалізацію, якщо це не змінить специфікацію. Отже, "Там, де документація неоднозначна, ..." залишається саме те, що після експерименту та тестування воно все одно неоднозначне.
gbulmer

@gbulmer Я згоден на 100%. Той, хто використовує недокументовані функції у виробництві, неодмінно буде сумним. Все ж цікаве емпіричне запитання (і відповідь), і, мабуть, гаразд, щоб залежати від разового особистого проекту.
bigjosh

Так, ви провели захоплююче розслідування.
габлмер

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

@jayjay дивіться моє оновлення.
Том Карпентер

1
Зауважте, що SBIне можна використовувати для встановлення Iбіта, SREGтому жоден код, який робить це, швидше за все, не був перевірений у реальному житті, оскільки він навіть не збирається. SBIможе працювати лише на 32-х нижчих регістрах, а SREG знаходиться на слоті 63.
bigjosh

@bigjosh Приклад SBI був таким, про який я думав пізніше - outбув тим, яким я користувався спочатку. Я думав, що я натрапив на AVR (можливо, це ATTiny), який містить SREG в нижньому 32 регістрі, але я можу це уявити.
Том Карпентер

1

IMHO робить написання до 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);
}

На жаль, мені не вистачає часу на це :(


0

Це не те, що сказано. У документації йдеться

Інструкція після SEI буде виконана перед будь-якими очікуваними перервами.

не те, що він чекає наступної інструкції. Я читаю це, оскільки прапор встановлюється негайно, але, незважаючи на те, що він увімкнено, не буде оброблятися переривань, поки не буде виконана наступна інструкція.


Це все правда, але моє запитання таке: чи така поведінка є специфічною для SEI?
jayjay

@jayjay Я підозрюю, що це пов’язано з довжиною трубопроводу з інструкцією
аварійно
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.