В чем разница между FIQ и системой прерываний IRQ?
Я хочу знать разницу между FIQ и системой прерываний IRQ в любом микропроцессоре, например: ARM926EJ.
12 ответов
Особенность современных процессоров ARM (и некоторых других).
Из патента:
Предложен способ выполнения быстрого прерывания в процессоре цифровых данных, имеющем возможность обработки более одного прерывания. При получении запроса на быстрое прерывание устанавливается флаг, а регистр счетчика программы и код состояния сохраняются в стеке. В конце процедуры обработки прерывания возврат из команд прерывания извлекает регистр кода состояния, который содержит состояние процессора цифровых данных, и проверяет, был ли установлен флаг или нет. Если флаг установлен, это указывает на то, что быстрое прерывание было обработано и, следовательно, только программный счетчик не установлен в стек.
Другими словами, FIQ - это просто запрос прерывания с более высоким приоритетом, приоритет которого отделяется отключением IRQ и других обработчиков FIQ во время обслуживания запроса. Следовательно, никакие другие прерывания не могут возникать во время обработки активного прерывания FIQ.
ARM звонки FIQ
быстрое прерывание, подразумевающее, что IRQ
это нормальный приоритет. В любой реальной системе будет гораздо больше источников прерываний, чем просто два устройства, и поэтому будет некоторый внешний аппаратный контроллер прерываний, который позволяет маскировать, расставлять приоритеты и т. Д. Этих нескольких источников и который направляет строки запроса прерываний в процессор.
В некоторой степени это делает различие между двумя режимами прерывания избыточным, и многие системы не используют nFIQ
или использовать его способом, аналогичным немаскируемому (NMI
) прерывание найдено на других процессорах (хотя FIQ
программно маскируется на большинстве процессоров ARM).
Так почему же ARM называет FIQ "быстрым"?
- Режим FIQ имеет свои собственные банковские регистры,
r8-r14
, R14 - это регистр связи, который содержит адрес возврата (+4) из FIQ. Но если ваш обработчик FIQ может быть написан так, что он использует толькоr8-r13
Эти банковские регистры могут воспользоваться двумя способами:- Один из них заключается в том, что он не влечет за собой затраты на передачу и выталкивание любых регистров, которые используются подпрограммой обработки прерываний (ISR). Это может сэкономить значительное количество циклов как при входе, так и при выходе из ISR.
- Кроме того, обработчик может полагаться на значения, сохраняющиеся в регистрах от одного вызова к другому, так что, например,
r8
может использоваться как указатель на аппаратное устройство, и обработчик может полагаться на то же значение, находящееся вr8
в следующий раз это называется.
- Расположение FIQ в конце таблицы векторов исключений (
0x1C
) означает, что если код обработчика FIQ размещен непосредственно в конце таблицы векторов, ветвление не требуется - код может выполняться непосредственно из0x1C
, Это экономит несколько циклов при входе в ISR. - FIQ имеет более высокий приоритет, чем IRQ. Это означает, что когда ядро принимает исключение FIQ, оно автоматически маскирует IRQ. IRQ не может прерывать обработчик FIQ. Обратное неверно - IRQ не маскирует FIQ, и поэтому обработчик FIQ (если используется) может прерывать IRQ. Кроме того, если и запросы IRQ, и запросы FIQ происходят одновременно, ядро сначала будет работать с FIQ.
Так почему же многие системы не используют FIQ?
- Код обработчика FIQ обычно не может быть написан на C - он должен быть написан непосредственно на языке ассемблера. Если вы достаточно заботитесь о производительности ISR, чтобы захотеть использовать FIQ, вы, вероятно, не захотите оставлять несколько циклов в таблице, кодируя в C в любом случае, но, что более важно, компилятор C не будет генерировать код, который следует ограничениям на используя только регистры
r8-r13
, Код, созданный компилятором C, совместимым с ARMATPCS
стандарт вызова процедуры вместо этого будет использовать регистрыr0-r3
для значений нуля и не будет давать правильныеcpsr
восстановление кода возврата в конце функции. - Все оборудование контроллера прерываний обычно находится на выводе IRQ. Использование FIQ имеет смысл только в том случае, если к входу n FIQ подключен один источник прерываний с наивысшим приоритетом, а во многих системах нет одного источника с наивысшим приоритетом. Нет смысла подключать несколько источников к FIQ, а затем устанавливать приоритеты программного обеспечения между ними, поскольку это устраняет почти все преимущества, которые FIQ имеет по сравнению с IRQ.
FIQ или быстрое прерывание часто упоминается как Soft DMA в некоторых ссылках ARM.
Особенности FIQ:
- Отдельный режим с банковским регистром, включая стек, регистр связи и R8-R12.
- Отдельный бит включения / выключения FIQ.
- Хвост таблицы векторов (которая всегда находится в кеше и отображается в MMU).
Последняя функция также дает небольшое преимущество перед IRQ, который должен ответвляться.
Демонстрация скорости в 'C'
Некоторые цитируют сложность кодирования на ассемблере для обработки 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, вероятно, имеет готовый бит, но код для создания высокоскоростного мягкого прямого доступа к памяти с 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 не подходит. Примечание: Вы можете удвоить некоторые регистры со сдвигами и поворотами, которые свободны на ARM, если вы используете 16-битные значения.
Очевидно, что FIQ более сложный. Разработчики ОС хотят поддерживать несколько источников прерываний. Требования клиентов к FIQ могут отличаться, и часто они понимают, что должны просто позволить клиенту делать свои собственные. Обычно поддержка для FIQ ограничена, так как любая поддержка может отвлекать от основной выгоды, SPEED.
Резюме
Не бей моего друга в FIQ. Это системный программист, одна хитрость против тупого оборудования. Это не для всех, но у него есть свое место. Когда все другие попытки уменьшить задержку и увеличить частоту обслуживания ISR потерпели неудачу, FIQ может быть вашим единственным выбором (или лучшей командой аппаратного обеспечения).
Также возможно использование в качестве панического прерывания в некоторых критических для безопасности приложениях.
Хаос уже хорошо ответил, но еще один момент, который еще не был рассмотрен, заключается в том, что FIQ находится в конце таблицы векторов, и поэтому обычно / традиционно просто запустить процедуру прямо здесь, тогда как вектор IRQ обычно является именно этим. (то есть прыжок куда-то еще). Избегание этой дополнительной ветки сразу после полного тайника и переключения контекста - это небольшое увеличение скорости.
Другая причина в случае FIQ, меньшее количество регистров необходимо для вставки в стек, режим FIQ имеет регистры от R8 до R14_fiq
FIQ имеет более высокий приоритет и может быть введен во время обработки другого IRQ. Наиболее важные ресурсы обрабатываются FIQ, остальные - IRQ.
FIQ имеют более высокий приоритет, без сомнения, остающиеся точки, я не уверен..... FIQ будут поддерживать высокоскоростную обработку каналов передачи (или) каналов, где требуется высокоскоростная обработка данных, мы используем FIQ, и обычно IRQ используют обычную обработку прерываний,
Я считаю, что это то, что вы ищете:
http://newsgroups.derkeiler.com/Archive/Comp/comp.sys.arm/2005-09/msg00084.html
По сути, FIQ будет иметь самый высокий приоритет с несколькими источниками IRQ с более низким приоритетом.
Никакого волшебства насчет FIQ. FIQ просто может прервать любой другой IRQ, который обслуживается, поэтому он называется "быстрым". Система реагирует быстрее на эти прерывания, но в остальном то же самое.
Он зависит от того, как мы проектируем обработчики прерываний, поскольку FIQ, наконец, может не нуждаться в одной инструкции ветвления, а также имеет уникальный набор регистров r8-r14, поэтому в следующий раз, когда мы вернемся к прерыванию FIQ, нам не нужно выдвигать / выдвигать стек. Конечно, это экономит некоторые циклы, но опять же не имеет смысла иметь больше обработчиков, обслуживающих один FIQ, и да, FIQ имеет больший приоритет, но нет никаких оснований утверждать, что он обрабатывает прерывание быстрее, оба IRQ/FIQ работают на той же частоте ЦП, Поэтому они должны работать с одинаковой скоростью.
Если ваш вариант использования касается не скорости выполнения, а задержки, использование FIQ с подпрограммой обслуживания (ISR), написанной на C* вместо ассемблера, может привести к получению более компактного кода, чем при стандартном подходе. Подумайте об одной задаче, которую необходимо выполнить с меньшей задержкой, чем время выполнения каждой из нескольких других, редких задач.
Стандартный подход: IRQ для нечастых задач будут устанавливать только флаги уведомлений и возвращать результат, так что ISR частых задач может обслуживаться с низкой задержкой. Вне любого ISR работа редких задач выполняется всякий раз, когда установлен соответствующий флаг.
Используя FIQ, вам не потребуются уведомления, но каждая задача будет полностью выполняться как ISR.
*) Учитывая, что ваш компилятор C знает, как реализовать FIQ ISR. Ссылаясь, например, на Руководство пользователя ARM Optimizing C/C++ Compiler v18.1.0.LTS (Rev. R):
5.10.15 Прагма INTERRUPT позволяет обрабатывать прерывания напрямую с помощью кода C. [...] Сохраняемые регистры и последовательность возврата зависят от типа прерывания.
Это может быть неправильно. Все, что я знаю, это то, что FIQ обозначает запрос быстрого прерывания, а IRQ - запрос прерывания. Судя по этим именам, я предполагаю, что FIQ будет обрабатываться (генерироваться?) Быстрее, чем IRQ. Вероятно, это связано с дизайном процессора, в котором FIQ будет прерывать процесс быстрее, чем IRQ. Я прошу прощения, если я ошибаюсь, но я обычно занимаюсь программированием более высокого уровня, я просто догадываюсь прямо сейчас.