|
|
  |
Cortex-A9 вложенные прерыания, Стандартный GIC, как приготовить |
|
|
|
Mar 6 2016, 20:05
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Появился вопрос в процессе одевания на голое железо обычной системы с super loop. Железо - Renesas RZ/A1L. Что есть: Вот такой код обработчика в ассемблере: Код IRQHandler:
/* Save interrupt context on the stack to allow nesting */ sub lr, lr, #4 stmfd sp!, {lr} mrs lr, SPSR stmfd sp!, {r0, lr}
// save VFP/Neon data registers VPUSH {d0-d15} // same as s0-s31 // save VFP/Neon FPSCR register FMRX r0, fpscr stmfd sp!, {r0-r3, r4, r12, lr}
ldr r2, =IRQHandlerSafe mov lr, pc bx r2 /* And jump... */
ldmia sp!, {r0-r3, r4, r12, lr} // restore VFP/Neon FPSCR register FMXR fpscr, r0 // restore VFP/Neon data registers VPOP {d0-d15} // same as s0-s31
ldmia sp!, {r0, lr} msr SPSR_cxsf, lr ldmia sp!, {pc}^ И его продолжение в C: Код void IRQHandlerSafe(void) { /* const uint32_t icchpir = */ (void) INTC.ICCHPIR; const uint32_t icciar = INTC.ICCIAR; (* intc_func_table [icciar & 0x03FF]) (); /* Call interrupt handler */ INTC.ICCEOIR = icciar & 0x1FFF; } Сейчас всё работает в случае, если среди прерываний нет разделения на группы с меньшим и большим приоритетами. Стоит добавить, получается "каша" - похоже, что выполнение более приоритетного прерывания не рапрещает выполнение менее приоритетного. Установка при инициализации процессора значения в регистре priority mask на менее приоритетное прерывание - оно естественно запрещается... Вопрос - как это должно тут выглядеть? (на STM32 с архитектурой Cortex-M4 и Cortex-M7 это всё работает, с использованием тамошних механизмов BASEPRI и остального). зы: картинки просто как иллюстрация.
Сообщение отредактировал Genadi Zawidowski - Mar 6 2016, 21:25
Эскизы прикрепленных изображений
|
|
|
|
|
Mar 7 2016, 07:53
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 20-11-13
Пользователь №: 79 278

|
загляните в примеры для freertos , там есть для cortex-a9 реализация FreeRTOS_IRQ_Handler в файле portASM.s . стартуете в supervisor , в обработчике снова в него переключаетесь FreeRTOS_IRQ_Handler
; Return to the interrupted instruction. SUB lr, lr, #4
; Push the return address and SPSR PUSH {lr} MRS lr, SPSR PUSH {lr}
; Change to supervisor mode to allow reentry. CPS #SVC_MODE
; Push used registers. PUSH {r0-r4, r12} ............................
|
|
|
|
|
Mar 7 2016, 16:58
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Genadi Zawidowski @ Mar 7 2016, 01:32)  Почитал... понял что тут (в armv7-a) всё совсем не так просто... Наоборот - все просто, если о том, что в ядре - есть два прерывания IRQ и FIQ. FIQ, естественно, прерывает IRQ. То есть такого типа вложенность есть. Любые другие форусы с вложеностью - ручками. Собственно контролеры прерываний это не как у мелких кортексов - не пренадлежность ядра и могут быть разнообразными в зависимости от производителя. Что прикручивает STM не смотрел. QUOTE А если я запущу в IRQ mode? при входе в прерывание не будет происходить перезагрузка SP и прерывания будут вложенными? ВСЕГДА устанавливаться начало собственного стека и соответственно никакой автоматической вложенности не может быть в принципе.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 8 2016, 00:24
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Разобрался... Самое необычное, что в старом проекте для AT91SAM7S64 было именно так сделано... Разобрался снова в коде более чем пять лет назад писанном... Я не мог догадаться, что в результате начинает использоваться два стека. А я всё искал способ "выгрести" всё из стека IRQ и перенести в главный (SVC). Обработчик теперь выглядит так: Код IRQHandler:
/* Save interrupt context on the stack to allow nesting */ sub lr, lr, #4 stmfd sp!, {lr} mrs lr, SPSR stmfd sp!, {r0, lr}
msr CPSR_c, #ARM_MODE_SVC | I_BIT // added ***** stmfd sp!, {r1-r3, r4, r12, lr}
// save VFP/Neon data registers VPUSH {d0-d15} // same as s0-s31 // save VFP/Neon FPSCR register FMRX r2, fpscr PUSH {r2}
ldr r2, =IRQHandlerSafe mov lr, pc bx r2 /* And jump... */
// restore VFP/Neon FPSCR register POP {r2} FMXR fpscr, r2 // restore VFP/Neon data registers VPOP {d0-d15} // same as s0-s31
ldmia sp!, {r1-r3, r4, r12, lr} msr CPSR_c, #ARM_MODE_IRQ | I_BIT // added *****
ldmia sp!, {r0, lr} msr SPSR_cxsf, lr Остались ещё проблемы с маской приоритетов, но это уже не страшно...
Сообщение отредактировал Genadi Zawidowski - Mar 8 2016, 00:26
|
|
|
|
|
Mar 9 2016, 13:31
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Как выяснилось при тестировании на минимальной программе: прерывания действительно "вложенны", обрабатываются так как надо (в нужном порядке соответственно назначенным приоритетам). Но! После возникновения первого же прерывания основная программа перестает выполняться. Вот RPR (running priority) и CPSR в разных точках: Основная программа до возникновения первого из прерываний FF 800001d3 Прерывание с меньшим приоритетом 10 60000193 Прерывание с большим приоритетом 08 80000193 Состояние RPR=FF больше не появляется ни разу. UPD:Код После возникновения первого же прерывания основная программа перестает выполняться Всё нормально, просто тест был написан таким образом, что аппаратные прерывания возникали так часто (и с такими задержками внутри обработчиков), что в основной цикл никогда не возвращались...
Сообщение отредактировал Genadi Zawidowski - Mar 9 2016, 13:32
|
|
|
|
|
Mar 10 2016, 04:51
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(zltigo @ Mar 7 2016, 22:58)  Наоборот - все просто, если о том, что в ядре - есть два прерывания IRQ и FIQ. FIQ, естественно, прерывает IRQ. Не естестественно  Насколько я помню ARM7: при входе в режим IRQ, процессор автоматически устанавливает запрет прерываний IRQ; при входе в режим FIQ автоматически устанавливает запрет FIQ & IRQ. Но ничто не запрещает программисту хоть в начале ISR любой из этих запретов снять или установить дополнительно и тогда и IRQ сможет прервать FIQ-обработчик если очень хочется. Как впрочем и вложенное прерывание (IRQ в IRQ или FIQ в FIQ) может возбудиться, но только надо быть аккуратным тут, так как будут перезаписаны теневые регистры регистрового файла для данного режима (SP, LR, SPSR для IRQ-режима и ещё больше регистров для FIQ-режима).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|