|
AT91SAM9G45, IRQ и FIQ |
|
|
|
May 2 2013, 09:11
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596

|
Цитата(jcxz @ May 2 2013, 12:59)  Вы-то как это поняли? Методом тыка? Не поверите, но изучал ассемблер ARM7/9 я как раз без JTAG ещё. А вот без понимания ассемблера дальше приложений пользовательского уровня соваться не стоит. Не надо делать: впустую переключать контекст, использовать AIC если у вас одно прерывание (да и больше - не всегда он нужен), даже половину регистров в FIQ в ARM7/9-ядрах можно не сохранять, а использовать для static переменных... Всего этого вы не узнаете пока не прочитаете доку на ядро. Код в первую очередь отлаживается головой. Практически методом тыка. В первую очередь головой но на вашем же примере видно что с помощью головы не всегда все становится ясно рабочий ли код или нет Это при том что вы знаете и ассемблер и ядро Подскажите идиоту в какую доку смотреть чтобы включать фик без использования AIC и чтобы еще при этом IRQ через AIC работали? И еще вопрос если я не делаю переключения контекста смогу ли я менять глобальные переменные находящиеся в другом контексте?
Сообщение отредактировал Sergey1212 - May 2 2013, 09:18
|
|
|
|
|
May 2 2013, 09:45
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Sergey1212 @ May 2 2013, 13:02)  стало при появлении уровня срабатывать и при исчезновении еще раз Оно именно так и работает - по изменению уровня, т.е. по обоим фронтам. Так устроена железка, настроить нельзя. Можно только проверять реальный уровень линии внутри прерывания. Цитата(Sergey1212 @ May 2 2013, 13:11)  Подскажите идиоту в какую доку смотреть чтобы включать фик без использования AIC и чтобы еще при этом IRQ через AIC работали? Что значит "без использования AIC"? Цитата(Sergey1212 @ May 2 2013, 13:11)  И еще вопрос если я не делаю переключения контекста смогу ли я менять глобальные переменные находящиеся в другом контексте? Да, это просто переключение банка регистров. На работе с расположенными в памяти глобальными переменными никак не отразится.
|
|
|
|
|
May 2 2013, 09:54
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Sergey1212 @ May 2 2013, 15:11)  В первую очередь головой но на вашем же примере видно что с помощью головы не всегда все становится ясно рабочий ли код или нет Я же не отлаживаю ваше ПО, а просто мельком просмотрел. Цитата(Sergey1212 @ May 2 2013, 15:11)  Подскажите идиоту в какую доку смотреть чтобы включать фик без использования AIC и чтобы еще при этом IRQ через AIC работали? Контроллер прерывания не входит в состав ядра. Здесь надо вам читать доку на ваш процессор, а не ядро. Я вашего процессора не знаю. В том ARM9, с которым я имел дело, в его AIC было 32 канала прерываний. Младшие 2 из которых всегда шли на FIQ-вход ядра, остальные - на IRQ-вход. Соответственно при инициализации прерывания, надо соответствующий event отнести к одной из групп. Если у вас в группе FIQ будет только один event, то работа с AIC в ISR может ограничиться только квитированием прерывания AIC-у (если это вообще нужно вашему AIC). В ARM7-ядрах NXP выбор типа FIQ/IRQ выполняется в регистре VICIntSelect, который работает как битовая карта. В вашем CPU может быть свой метод. Далее - читаете описание периферии, которая генерит int-event-ы и смотрите как её надо инитить и как ей квитировать прерывания для этой периферии (если надо). Цитата(Sergey1212 @ May 2 2013, 15:11)  И еще вопрос если я не делаю переключения контекста смогу ли я менять глобальные переменные находящиеся в другом контексте? Переменные не относятся к контексту CPU. Они находятся в ОЗУ. А контекст - этот состояние ядра с соответствующим ему набором регистров. Вот получить доступ к регистрам другого контекста вы не сможете. Надо переключать контекст чтобы получить к ним доступ.
|
|
|
|
|
May 2 2013, 11:12
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596

|
Цитата Не надо делать: впустую переключать контекст, использовать AIC если у вас одно прерывание (да и больше - не всегда он нужен) Я так и не понял, всетаки без AIC не обойтись? Или его ненадо использовать? Цитата Подумайте, нужны ли вам вообще прерывания по фронту - для внутренних источников (к которым относится и GPIO), в 99.9% случаев смысла работать по фронту нет. Цитата Оно именно так и работает - по изменению уровня, т.е. по обоим фронтам. Так устроена железка, настроить нельзя. А для чего тогда настройки по фронтам? Их всетаки можно использовать для GPIO? Если можно то как я понимаю будет только один раз вызываться прерывание
|
|
|
|
|
May 2 2013, 11:50
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596

|
Всем спасибо, хоть что-то разъяснилось) Код сократился до такого варианта: Код stmfd sp!, {r0, lr} ldr lr, =AT91C_BASE_AIC ldr r0, [lr, #AIC_FVR] mov lr, pc bx r0 ldmia sp!, {r0, lr} subs pc,lr,#4 Чего тут еще не нужно делать? вот r0 нужно сохранять-возвращать? может и вместо bx что-то посоветуете чтобы lr не приходилось менять перед bx чтобы и его не сохранять? а может чего-то нехватает?
Сообщение отредактировал Sergey1212 - May 2 2013, 13:39
|
|
|
|
|
May 2 2013, 16:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Я же уже писал... В моём ARM9-ядре (ARM926EJ-S из состава OMAP-L137) достаточно в контроллере прерываний посадить только одно прерывание на линию FIQ (остальные - на IRQ). Тогда достаточно будет оставить: Код SUB LR, LR, #4 STMFD SP!, {..., LR} ... LDMFD SP!, {..., PC}^ Вместо многоточия можно писать свой код, учитывая, что регистры R8-R12 можно не сохранять. Вместо многоточия можно также поставить вызов си-функции. Тогда в команды STMFD/LDMFD нужно добавить все регистры из диапазона R0-R7, которые нужно сохранять (список таких регистров ищется в разделе "Calling Conventions" на ваш компилятор). Для CodeComposer (и ARM926EJ-S из состава OMAP-L137) это будет: Код FIQ_handler: SUBS LR, LR, #4 STMFD SP!, {R0-R3, R12, LR} ;Store registers on FIQ stack BL c_func ;Go to ISR (still in FIQ mode), will return to following line LDMFD SP!, {R0-R3, R12, PC}^ ;Restore registers from FIQ stack. Return to program current status Так что выгоднее FIQ-обработчик писать на асм - если уложитесь в регистры R8-R12 то вообще ничего на стек сохранять не нужно и можно избавиться от STMFD/LDMFD, и может даже от команд загрузки рабочих регистров статическими переменными и константами. Я так на ARM7 с частотой 72МГц получал частоты прерываний порядка нескольких мегагерц при 50% загрузке CPU. И даже без JTAG...
|
|
|
|
|
May 2 2013, 18:02
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Sergey1212 @ May 2 2013, 15:50)  Чего тут еще не нужно делать? вот r0 нужно сохранять-возвращать? может и вместо bx что-то посоветуете чтобы lr не приходилось менять перед bx чтобы и его не сохранять? а может чего-то нехватает? Начнем с того, что нужно сделать, но не сделано: следует сохранить регистры r0-r3 и r12. См. пример FIQ_Handler из сообщения jcxz. Весь приведенный фрагмент кода можно благополучно заменить одной командой ldr pc, [pc, #-0xf20], расположенной по адресу вектора FIQ (0x1c). Только C-обработчик нужно будет снабдить модификатором, который укажет компилятору на то, что это обработчик FIQ-прерывания (__fiq, __attribute__ ((interrupt( fiq ))) и т.п., в зависимости от используемого компилятора). Результат будет тот же, зато в стек не будет записано лишнего.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|