У чому різниця між системою переривань FIQ та IRQ?


Відповіді:


63

Особливість сучасних процесорів ARM (та деяких інших).

З патенту:

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

Іншими словами, FIQ - це просто запит на переривання вищого пріоритету, який має пріоритет, відключаючи IRQ та інші обробники FIQ під час обслуговування запитів. Отже, ніякі інші переривання не можуть відбуватися під час обробки активного переривання FIQ.


1
Щоб не відірвати відповіді, але те, що є в патенті, не обов’язково говорить про те, що впроваджено, тому я б не вважав це авторитетним посиланням.
abc

166

ARM викликає FIQна швидке переривання , маючи на увазі , що IRQє нормальним пріоритетом . У будь-якій реальній системі буде набагато більше джерел переривань, ніж просто два пристрої, і тому буде якийсь зовнішній апаратний контролер переривань, який дозволяє маскувати, визначати пріоритети тощо цих кількох джерел і який спрямовує лінії запитів на переривання до процесора.

Певною мірою це робить різницю між двома режимами переривання надлишковим, і багато систем взагалі не використовують nFIQабо використовують його способом, аналогічним немаскуваному ( NMI) перериванню, що зустрічається на інших процесорах (хоча FIQпрограмне забезпечення маскується на більшості ARM процесори).

То чому ARM називає FIQ "швидким"?

  1. Режим FIQ має свої власні виділені складовані регістри, r8-r14. R14 - це регістр посилань, який містить адресу повернення (+4) з FIQ. Але якщо ваш обробник FIQ може бути записаний таким чином, що він лише використовує r8-r13, він може скористатися перевагами цих банківських реєстрів двома способами:
    • Одне з них полягає в тому, що це не спричиняє накладних витрат на натискання та видалення будь-яких регістрів, які використовуються підпрограмою обслуговування переривань (ISR). Це може заощадити значну кількість циклів як на вході, так і на виході до ISR.
    • Крім того, обробник може покладатися на значення, що зберігаються в регістрах від одного виклику до наступного, так що, наприклад, r8може використовуватися як вказівник на апаратний пристрій, і обробник може покладатися на те саме значення, яке знаходиться r8в наступний раз, коли його викликають.
  2. Розташування FIQ в кінці таблиці векторних винятків ( 0x1C) означає, що якщо код обробника FIQ розміщений безпосередньо в кінці векторної таблиці, гілка не потрібна - код може виконуватися безпосередньо з0x1C . Це економить кілька циклів при вступі до ISR.
  3. FIQ має вищий пріоритет, ніж IRQ. Це означає, що коли ядро ​​приймає виняток FIQ, воно автоматично маскує IRQ. IRQ не може перервати обробник FIQ. Навпаки, це неправда - IRQ не маскує FIQ, і тому обробник FIQ (якщо використовується) може перервати IRQ. Крім того, якщо запити IRQ та FIQ відбуваються одночасно, ядро ​​буде мати справу з FIQ першим.

То чому в багатьох системах не використовується FIQ?

  1. Код обробника FIQ, як правило, не може бути написаний мовою C - його потрібно писати безпосередньо мовою асемблера. Якщо ви в достатній мірі піклуєтеся про продуктивність ISR, щоб хотіти використовувати FIQ, ви, мабуть, не хочете залишати кілька циклів у таблиці, кодуючи C, у кожному разі, але, що важливіше, компілятор C не видасть код, який відповідає обмеженню на використовуючи лише регістри r8-r13. Код, створений компілятором C, що відповідає ATPCSстандарту виклику процедур ARM, замість цього використовуватиме регістри r0-r3для значень подряпин і не буде видавати правильний cpsrкод відновлення повернення в кінці функції.
  2. Все апаратне забезпечення контролера переривань, як правило, знаходиться на штифті IRQ. Використання FIQ має сенс лише у тому випадку, якщо у вас є одне джерело переривань з найвищим пріоритетом, підключене до входу nFIQ, і багато систем не мають жодного постійно найвищого пріоритету. Немає значення підключати кілька джерел до FIQ, а потім надавати пріоритети між ними, оскільки це усуває майже всі переваги, які має FIQ перед IRQ.

3
FIQ використовується для Secure Worlds в реалізаціях ARM TrustZone, щоб відрізнити переривання від "безпечних" джерел переривань. Точне визначення того, що може бути безпечним джерелом переривань і як із цим слід поводитися інакше, ніж звичайне переривання, залежить від моделей загрози та реалізації.
divegeek

1
GCC і LLVM не мають оптимізацій, необхідних для коду FIQ. Вони й надалі використовуватимуть регістри r0 - r7 замість r8 і вище. І ось згенерований код виштовхує / виводить їх на / зі стеку. Крім того, під час виклику функції компілятори продовжуватимуть використовувати стандартний ABI (функція може змінити r0 на r3). Досить швидко згенерована збірка стає стандартною та неефективною.
Свен

73

FIQ або швидке переривання часто згадується як Soft DMA в деяких посиланнях на ARM.
Особливостями FIQ є,

  1. Окремий режим з банківським регістром, включаючи стек, регістр посилань та R8-R12.
  2. Окремий біт увімкнення / вимкнення FIQ.
  3. Хвіст векторної таблиці (який завжди знаходиться в кеш-пам'яті та відображається MMU).

Остання особливість також дає невелику перевагу над IRQ, який повинен розгалужуватися.

Демонстрація швидкості на "С"

Деякі цитують труднощі кодування в асемблері для обробки FIQ. gccмає анотації для кодування обробника FIQ . Ось приклад,

void  __attribute__ ((interrupt ("FIQ"))) fiq_handler(void)
{
    /* registers set previously by FIQ setup. */
    register volatile char *src asm ("r8");  /* A source buffer to transfer. */
    register char *uart asm ("r9");          /* pointer to uart tx register. */
    register int size asm ("r10");           /* Size of buffer remaining. */
    if(size--) {
        *uart = *src++;
    }
}

Це означає наступний майже хороший асемблер,

00000000 <fiq_handler>:
   0:   e35a0000        cmp     sl, #0
   4:   e52d3004        push    {r3}            ; use r11, r12, etc as scratch.
   8:   15d83000        ldrbne  r3, [r8]
   c:   15c93000        strbne  r3, [r9]
  10:   e49d3004        pop     {r3}            ; same thing.
  14:   e25ef004        subs    pc, lr, #4

Підпрограма асемблера 0x1cможе виглядати так:

   tst     r10, #0    ; counter zero?
   ldrbne  r11, [r8]  ; get character.
   subne   r10, #1    ; decrement count
   strbne  r11, [r9]  ; write to uart
   subs    pc, lr, #4 ; return from FIQ.

Справжній UART, ймовірно, має готовий біт, але код для створення високошвидкісного м'якого DMA з FIQ буде складати лише 10-20 інструкцій. Основний код повинен опитати FIQ, r10щоб визначити, коли буфер закінчений. Основний (код без переривань) може передавати та налаштовувати зареєстровані реєстри FIQ , використовуючи msrінструкцію для переходу на FIQ режим та передавати небанківські R0-R7 до банківських регістрів R8-R13.

Зазвичай затримка переривання RTOS становить 500-1000 інструкцій. Для Linux це може бути 2000-10000 інструкцій. Справжній DMA завжди кращий, однак для простих частотних переривань (наприклад, передача буфера) FIQ може надати рішення.

Оскільки FIQ стосується швидкості, ви не повинні це враховувати, якщо ви не впевнені в кодуванні в асемблері (або хочете присвятити час). Асемблер, написаний нескінченно запущеним програмістом, буде швидшим за компілятор. Надання допомоги GCC може допомогти новачку.

Латентність

Оскільки FIQ має окремий біт маски, він майже повсюдно включений. На попередніх процесорах ARM (таких як ARM926EJ) деякі атомні операції повинні були бути реалізовані шляхом маскування переривань. Однак навіть з найдосконалішими процесорами Cortex існують випадки, коли ОС замаскує переривання. Часто час обслуговування не є критичним для переривання, а час між сигналізацією та обслуговуванням. Тут FIQ також має перевагу.

Слабкість

FIQ не є масштабованим. Для того, щоб використовувати кілька FIQджерел, банківські регістри повинні бути спільними між процедурами переривання. Крім того, необхідно додати код, щоб визначити, що спричинило переривання / FIQ. FIQ , як правило, один трюк поні .

Якщо ваше переривання є дуже складним (мережевий драйвер, USB тощо), то FIQ, мабуть, мало сенсу. В основному це те саме твердження, що і мультиплексування переривань. У накрененних регістри дають 6 вільних змінних у використанні , які ніколи не завантажується з пам'яті . Реєстрація швидша, ніж пам’ять. Регістри швидші, ніж L2-кеш. Регістри швидші за L1-кеш. Реєстри швидкі. Якщо ви не можете написати процедуру, яка працює з 6 змінними, тоді FIQ не підходить. Примітка: Якщо ви використовуєте 16-бітові значення, ви можете подвоїти деякий регістр із зрушеннями та обертаннями, які є безкоштовними на ARM.

Очевидно, що FIQ є більш складним. Розробники ОС хочуть підтримувати кілька джерел переривань. Вимоги замовника до FIQ будуть різними, і часто вони усвідомлюють, що їм слід просто дозволити клієнту прокручувати свої власні . Зазвичай підтримка FIQ обмежена, оскільки будь-яка підтримка, ймовірно, погіршить основну перевагу, SPEED .

Резюме

Не бийте мого друга FIQ . Це системний програміст, один фокус проти дурного обладнання. Це не для всіх, але воно має своє місце. Коли всі інші спроби зменшити затримку та збільшити частоту обслуговування ISR не вдалися, FIQ може бути вашим єдиним вибором (або кращою командою апаратного забезпечення).

Це також можна використовувати як переривання паніки в деяких важливих для безпеки програмах.


1
Додатком є те, що для безпечної світової ОС (ARM TrustZone) в основному обов’язково використовувати FIQ . Однак у цьому випадку він працює як звичайний обробник переривань, а не як традиційна роль SoftDMA . Нормальний світ використовує звичайний IRQ механізм і надійному ВИКОРИСТОВУЄ FIQ .
бездумний шум

Просто цікаво, чому ви не читаєте ACK і не відправляєте EOI у своєму обробнику
Чарвак,

@Charvak Це специфічно для контролера переривань; ви думаєте GIC . Деякі контролери переривань автоматично очищаються (тобто, uart ready стає не готовим, коли пишеться символ). Це гіпотетичний приклад (для загальної відповіді; ОП мав ARM926), а не фактичний робочий приклад. Помістіть базу GIC в реєстр FIQ і виконайте команду ACKі EOI, якщо це контролер, який у вас є.
бездумний шум

Змінні локального реєстру не роблять того, що, на вашу думку, робиться. Вони не резервують регістр для певної змінної. Насправді, gcc гарантуватиме лише те, що значення змінної знаходиться у зазначеному реєстрі, коли виконується вбудована збірка, яка має зазначену змінну вхідним або вихідним параметром. У будь-який інший час реєстр може використовуватися для інших даних. Зокрема, я вважаю, що gcc не розуміє, що при поверненні функції srcмає бути зареєстровано r8. Однак глобальні регістрові змінні тут здаються придатними, оскільки вони резервують регістри.
Свен

1
Відомо, що GCC, як правило, використовує регістри r0 до r7, хоча r8 і друзі можуть бути використані. Шкода, але GCC ще не є оптимальним для написання обробників FIQ, IMHO. Довідково: gcc.gnu.org/bugzilla/show_bug.cgi?id=48429
Свен

6

Хаос вже добре відповів, але додатковий момент, який досі не розглядався, полягає в тому, що FIQ знаходиться в кінці таблиці векторів, і тому загальноприйнятим / традиційним є просто розпочати процедуру прямо тут, тоді як вектор IRQ зазвичай є саме цим. (тобто стрибок кудись ще). Уникнення цієї зайвої гілки відразу після повного перемикання тайника та контексту - це невеликий приріст швидкості.


5

інша причина - у випадку FIQ, для перенесення стека потрібна менша кількість регістрів, режим FIQ має регістри від R8 до R14_fiq


3

FIQ є вищим пріоритетом і може бути введений під час обробки іншого IRQ. Найбільш критичними ресурсами займаються FIQ, решта - IRQ.



1

FIQ є вищим пріоритетом, без сумніву, решта пунктів я не впевнений ..... FIQ підтримуватимуть високошвидкісну передачу даних (або) обробку каналу, де потрібні високошвидкісні процеси передачі даних, ми використовуємо FIQ і, як правило, IRQ використовуються для нормальної обробки переривань .


0

Ніякої магії щодо FIQ. FIQ просто може перервати будь-який інший IRQ, який обслуговується, тому його називають "швидким". Система швидше реагує на ці переривання, але все те ж саме.


0

Це залежить від того, як ми розробляємо обробники переривань, оскільки FIQ нарешті йому не потрібна одна інструкція гілки, а також він має унікальний набір регістрів r8-r14, тому наступного разу, коли ми повернемося до переривання FIQ, нам не потрібно буде натискати / вискакувати стек. Звичайно, це економить деякі цикли, але знову ж таки нерозумно мати більше обробників, що обслуговують один FIQ, і так, FIQ має більший пріоритет, але немає жодної причини стверджувати, що він швидше обробляє переривання, обидва IRQ / FIQ працюють з однаковою частотою процесора, Тож вони повинні бігати з однаковою швидкістю.


-5

Це може бути неправильно. Мені відомо лише те, що FIQ означає «Запит на швидке переривання», а IRQ - «Запит на переривання». Судячи з цих назв, я здогадуюсь, що FIQ буде оброблятися (кидатися?) Швидше, ніж IRQ. Можливо, це має щось спільне з конструкцією процесора, де FIQ перериватиме процес швидше, ніж IRQ. Прошу вибачення, якщо помиляюся, але я зазвичай займаюся програмуванням вищого рівня, просто зараз здогадуюсь.

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