|
AT91SAM9G45, IRQ и FIQ |
|
|
|
Apr 26 2013, 07:54
|
Участник

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

|
Вобщем задача такая хочу реализовать параллельную шину данных и 8 ног внешнего прерывания по которым будет опрашиваться шина. данные с шины должны опрашиваться как можно быстрее т.е. прерываться выполнения IRQ и не допускать вложенности. Для этих целей хочу использовать FIQ. Использовать EBI для общения как с статической памятью не получится, буду использовать ногодрыг, да и устройство на другой стороне имеет относительно низкую скорость шины. IRQ будут висеть на таймерах и т.д. а FIQ на физических пинах.
Отсюда вопросы насколько хорошо выполненна реализация IRQ в стандартных примерах атмеля? из архив at91sam9m10-ekes-softpack-1.9.zip Если там все по кривому, было бы не плохо увидеть ссылку на правильный код. Получится ли вообще повесить на 8 ног FIQ прерывания? Не владею асемблером, где можно посмотреть пример кода с FIQ на этот проц? сохранение стека, возврат и т.д. И еще стоит ли вообще использовать FIQ или достаточно использовать на эти 8 ног IRQ с одинаковым самым высоким приоритетом? будут ли выполняющиеся в этот момент IRQ с более низким приоритетом прерываться для выполнения IRQ с более высоким приоритером? и как я понимаю вложенности тоже не будет т.к. IRQ будут с одинаковым высоким приоритетом?
Сообщение отредактировал Sergey1212 - Apr 26 2013, 08:08
|
|
|
|
|
Apr 26 2013, 08:13
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Sergey1212 @ Apr 26 2013, 11:54)  Отсюда вопросы насколько хорошо выполненна реализация IRQ в стандартных примерах атмеля? Не знаю, как сейчас, но раньше было криво - дурацкий код для обеспечения вложенности прерываний с убитой векторизацией и дичайшим оверхедом для прерывания с высшим приоритетом. Цитата(Sergey1212 @ Apr 26 2013, 11:54)  Получится ли повесить на 8 ног FIQ прерывания? FIQ прерывание одно. Поэтому получится, но только если все ноги находятся в пределах одного порта. Цитата(Sergey1212 @ Apr 26 2013, 11:54)  И еще стоит ли вообще использовать FIQ или достаточно использовать на эти 8 ног IRQ с одинаковым самым высоким приоритетом? Лучше FIQ, чем вложенные прерывания.
|
|
|
|
|
Apr 26 2013, 08:30
|
Участник

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

|
Не подскажите пример хорошей реализации IRQ и FIQ?
|
|
|
|
|
Apr 26 2013, 08:41
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Sergey1212 @ Apr 26 2013, 13:54)  Получится ли вообще повесить на 8 ног FIQ прерывания? Получится. По ИЛИ. Цитата(Sergey1212 @ Apr 26 2013, 13:54)  Не владею асемблером, где можно посмотреть пример кода с FIQ на этот проц? сохранение стека, возврат и т.д. Вы сначала не ассемблер, а описание на ядро ARM7/9 почитайте. Нет там никакого сохранения стека. По соотв. прерыванию (IRQ или FIQ) переключается контекст CPU. Цитата(Sergey1212 @ Apr 26 2013, 13:54)  будут ли выполняющиеся в этот момент IRQ с более низким приоритетом прерываться для выполнения IRQ с более высоким приоритером? и как я понимаю вложенности тоже не будет т.к. IRQ будут с одинаковым высоким приоритетом? Не будут, но по-другой причине. В ядре нет никаких приоритетов. Если произошло IRQ, то CPU переключается в контекст IRQ и автоматом запрещает IRQ. То же для FIQ (но запрещаются и IRQ и FIQ). Приоритеты есть только в контроллере прерываний, который можно использовать, а можно - нет. Поэтому для одного высокочастотного прерывания ядро ARM7/9 удобнее кортексов: если FIQ происходит, то вход в контекст FIQ очень быстрый и нет необходимости ничего сохранять и восстанавливать. А вообще для быстрой работы с GPIO лучше использовать DMA (если есть возможность в вашем процессоре). А дёргание в прерывании и программный ногодрыг - это пустая трата тактов процессора. А ещё лучше - используйте канал SPI. Мегагерц на 60 думаю сможете его завести. И дорог на плате меньше.
|
|
|
|
|
Apr 26 2013, 11:01
|
Участник

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

|
а всетаки пример может кто скинет? с вложенными IRQ, использованием AIC и FIQ
Сообщение отредактировал Sergey1212 - Apr 26 2013, 11:04
|
|
|
|
|
May 2 2013, 05:44
|
Участник

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

|
Есть вот такой код фика CODE FIQ_Handler_Entry:
stmfd sp!, {r0, lr} ldr lr, =AT91C_BASE_AIC ldr r0, [lr, #AIC_FVR] str lr, [lr, #AIC_FVR] msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC //;- Save scratch/used registers and LR in User Stack stmfd sp!, {r1-r3, r4, r12, lr} //;- Branch to the routine pointed by the AIC_FVR
ldr r0, =fiq mov r14, pc bx r0 //;- Restore scratch/used registers and LR from User Stack ldmia sp!, {r1-r3, r4, r12, lr} //;- Leave Interrupts disabled and switch back in FIQ mode msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ mov r0, #0xFFFFFF ldr r8, =AT91C_BASE_AIC str r0, [r8, #AIC_EOICR]
//;- Restore the R0 ARM_MODE_SVC register ldmia sp!, {r0, lr} //;- Restore the Program Counter using the LR_fiq directly in the PC subs pc,lr,#4
но работает он только если я в AIC_SMR[source] = AT91C_AIC_PRIOR_HIGHEST | 0; а если использую другие варианты (0x2 << 5) или (0x1 << 5) или (0x3 << 5) то прерывание остается активным т.к. все время заходит в процедуру fiq и там прочитанный статус равен 0 если тот же обраотчик вешаю на IRQ то все работает отлично прерывания сбрасываются как положено т.е. дело не в обработчике вот код fiq Код void fiq(void) { volatile unsigned int dummy, reg; unsigned int status; status = AT91C_BASE_PIOA->PIO_ISR; status &= AT91C_BASE_PIOA->PIO_IMR;
printf("HI %d \r\n", status);
if(status!=0) { dummy = AT91C_BASE_PIOA->PIO_ISR; printf("HI fiq \r\n"); } } Подскажите в чем проблема? И как сделать чтобы переходил по вектору на процедуру сохраненную через AIC комментирую строку ldr r0, =fiq в фик не попадаю жытага нет поэтому в слепую очень уж непросто разбираться и учиться подскажите пожалуйста
Сообщение отредактировал Sergey1212 - May 2 2013, 05:48
|
|
|
|
|
May 2 2013, 07:52
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Sergey1212 @ May 2 2013, 11:44)  Есть вот такой код фика ... //;- Restore the R0 ARM_MODE_SVC register ldmia sp!, {r0, lr} //;- Restore the Program Counter using the LR_fiq directly in the PC subs pc,lr,#4 И где же восстановление прерванного режима CPU??? У вас после такого возврата, CPU останется в режиме FIQ, стек разрушится, не говоря уже о том что прерывания останутся запрещёнными. Цитата(Sergey1212 @ May 2 2013, 11:44)  если тот же обраотчик вешаю на IRQ то все работает отлично прерывания сбрасываются как положено По-моему - Вы обманываете. Такой код работать не будет. И это кроме того, что таким Вы убиваете весь смысл FIQ как быстрого прерывания. Зачем он Вам тогда нужен? Пользуйтесь IRQ. Такими манипуляциями Вы низводите плюсы FIQ (скорость входа/выхода) до обычной скорости IRQ с внешним AIC-контроллером, т.е. - самой тормозной. Цитата(aaarrr @ May 2 2013, 12:41)  Подумайте, нужны ли вам вообще прерывания по фронту - для внутренних источников (к которым относится и GPIO), в 99.9% случаев смысла работать по фронту нет. Проблема автора в том, что он не хочет ничего читать из документации на CPU, а хочет надёргать каких-то левых чужих кусков не разбираясь как они работают, и чтобы это всё заработало, да ещё и быстро... Цитата(Sergey1212 @ May 2 2013, 11:44)  ... printf("HI %d \r\n", status); ... Запускать такие тяжёлые функции из ISR, к тому же ещё на стеке SVC (printf до фига ест стека) неизвестно какого размера (скорей всего - небольшого)??? Ну-ну, успехов!
|
|
|
|
|
May 2 2013, 08:00
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(jcxz @ May 2 2013, 11:52)  По-моему - Вы обманываете. Такой код работать не будет. Нет, тут все правильно: sub s pc, lr, #4 восстановит режим. Цитата(jcxz @ May 2 2013, 11:52)  Запускать такие тяжёлые функции из ISR, к тому же ещё на стеке SVC (printf до фига ест стека) неизвестно какого размера (скорей всего - небольшого)??? Ну-ну, успехов!  Если это из атмеловских примеров, то у них как раз все наоборот - стек IRQ/FIQ имеет минимальный размер, а SVC/USR достаточно приличные. Но правильно, конечно, будет убрать это дурацкое переключение и расширить при необходимости стек FIQ.
|
|
|
|
|
May 2 2013, 08:32
|
Участник

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

|
Цитата По-моему - Вы обманываете. Такой код работать не будет. И это кроме того, что таким Вы убиваете весь смысл FIQ как быстрого прерывания. Зачем он Вам тогда нужен? Пользуйтесь IRQ. Такими манипуляциями Вы низводите плюсы FIQ (скорость входа/выхода) до обычной скорости IRQ с внешним AIC-контроллером, т.е. - самой тормозной. Проблема автора в том, что он не хочет ничего читать из документации на CPU, а хочет надёргать каких-то левых чужих кусков не разбираясь как они работают, и чтобы это всё заработало, да ещё и быстро... Запускать такие тяжёлые функции из ISR, к тому же ещё на стеке SVC (printf до фига ест стека) неизвестно какого размера (скорей всего - небольшого)??? Ну-ну, успехов!  Я конечно понимаю что вы очень умный и начитанный документаций до того что даже не можете понять что код рабочий. Посмотрел бы я на вас без жытаги, без понимания в асемблере и с такой богатой документацие где ведь все по полочкам разложено, в том числе и команды асма, какие регистры надо сохранять или не надо и что вообще надо делать при входе в прерывание на этом асемблере и т.д. А писать код на асме без отладки думаю не простое дело даже для знающих ассемблер и изучивших проц. По поводу принтф, как по вашему я должен отлаживать код? То что смысл весь фика убиваю так это да, но я непонимаю и незнаю как сделать чтобы было правильно. Если бы все знал и понимал думаю тут бы не оказался. Цитата(aaarrr @ May 2 2013, 10:41)  Прочитайте внимательно раздел "27.8.4.5 Fast Forcing": 1. Прерывания по фронту в этом режиме автоматически не сбрасываются, поэтому и зависает 2. AIC_FVR всегда возвращает значение из AIC_SVR0
Подумайте, нужны ли вам вообще прерывания по фронту - для внутренних источников (к которым относится и GPIO), в 99.9% случаев смысла работать по фронту нет. Дело в том что если я не по фронту делаю то при подаче на ногу сигнала вызов прерывания повторяется пока этот сигнал не будет снят. для сброса я так понимаю нужно AIC_ICCR использовать?
|
|
|
|
|
May 2 2013, 08:59
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Sergey1212 @ May 2 2013, 14:32)  Я конечно понимаю что вы очень умный и начитанный документаций до того что даже не можете понять что код рабочий. Вы-то как это поняли? Методом тыка? Цитата(Sergey1212 @ May 2 2013, 14:32)  Посмотрел бы я на вас без жытаги, без понимания в асемблере и с такой богатой документацие где ведь все по полочкам разложено, в том числе и команды асма, какие регистры надо сохранять или не надо и что вообще надо делать при входе в прерывание на этом асемблере и т.д. Не поверите, но изучал ассемблер ARM7/9 я как раз без JTAG ещё. А вот без понимания ассемблера дальше приложений пользовательского уровня соваться не стоит. Не надо делать: впустую переключать контекст, использовать AIC если у вас одно прерывание (да и больше - не всегда он нужен), даже половину регистров в FIQ в ARM7/9-ядрах можно не сохранять, а использовать для static переменных... Всего этого вы не узнаете пока не прочитаете доку на ядро. Цитата(Sergey1212 @ May 2 2013, 14:32)  По поводу принтф, как по вашему я должен отлаживать код? Код в первую очередь отлаживается головой.
|
|
|
|
|
May 2 2013, 09:02
|
Участник

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

|
Да спасибо, это видимо потому что прерывание не сбрасывал, вот только как то странно получалось как только уровень снимал оно сбрасывалось щас добавил в обработчик AT91C_BASE_AIC->AIC_ICCR = status; стало при появлении уровня срабатывать и при исчезновении еще раз а при настройке по фронту все равно не сбрасывается а если вы говорите что оно еще до AIC где-то настроено это где тогда? хотелось бы всетаки по фронту сделать чтобы появился уровень затем снялся и только тогда прерывание появилось
|
|
|
|
|
May 2 2013, 09:09
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(aaarrr @ May 2 2013, 14:00)  Нет, тут все правильно: subs pc, lr, #4 восстановит режим. Да, давненько не писал для ARM7/9. На cortex-ах отвык уже... Не заметил этого модификатора, ведь при применении к PC у него особый смысл  Я всегда делал по-другому: Код SUB LR, LR, #4 STMFD SP!, {..., LR} ... LDMFD SP!, {..., PC}^
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|