Igor_F 0 7 февраля, 2008 Опубликовано 7 февраля, 2008 · Жалоба Помогите, пожалуйста, разобраться. Работаем с процессором AT91SAM7X256, компилятор IAR. Есть два обработчика IRQ. Первый из них: ////////////////////////////////////////// IRQ_Handler_Entry: ;------------------------- ;- Manage Exception Entry ;------------------------- ;- Adjust and save LR_irq in IRQ stack sub lr, lr, #4 stmfd sp!, {lr} ;- Save r0 and SPSR (need to be saved for nested interrupt) mrs r14, SPSR stmfd sp!, {r0,r14} ;- Write in the IVR to support Protect Mode ;- No effect in Normal Mode ;- De-assert the NIRQ and clear the source in Protect Mode ldr r14, =AT91C_BASE_AIC ldr r0 , [r14, #AIC_IVR] str r14, [r14, #AIC_IVR] ;- Enable Interrupt and Switch in Supervisor Mode msr CPSR_c, #ARM_MODE_SVC ;- Save scratch/used registers and LR in User Stack stmfd sp!, { r1-r3, r12, r14} ;---------------------------------------------- ;- Branch to the routine pointed by the AIC_IVR ;---------------------------------------------- mov r14, pc bx r0 ;---------------------------------------------- ;- Manage Exception Exit ;---------------------------------------------- ;- Restore scratch/used registers and LR from User Stack ldmia sp!, { r1-r3, r12, r14} ;- Disable Interrupt and switch back in IRQ mode msr CPSR_c, #I_BIT | ARM_MODE_IRQ ;- Mark the End of Interrupt on the AIC ldr r14, =AT91C_BASE_AIC str r14, [r14, #AIC_EOICR] ;- Restore SPSR_irq and r0 from IRQ stack ldmia sp!, {r0,r14} msr SPSR_cxsf, r14 ;- Restore adjusted LR_irq from IRQ stack directly in the PC ldmia sp!, {pc}^ /////////////////////////////////////////// И второй, который вызывается по следующей команде: LDR PC, [PC, #-0xF20] ; Jump directly to the address given by the AIC Вот этот обработчик: vPortPreemptiveTick: portSAVE_CONTEXT ; Save the context of the current task. LDR R0, =vTaskIncrementTick ; Increment the tick count - this may wake a task. mov lr, pc BX R0 LDR R0, =vTaskSwitchContext ; Select the next task to execute. mov lr, pc BX R0 LDR R14, =AT91C_BASE_PITC ; Clear the PIT interrupt LDR R0, [R14, #PITC_PIVR ] LDR R14, =AT91C_BASE_AIC ; Mark the End of Interrupt on the AIC STR R14, [R14, #AIC_EOICR] portRESTORE_CONTEXT ; Restore the context of the selected task. При этом первый из них нормально обрабатывает прерывания USART-а, но при переключении между задачами программа вылетает в исключение Data Abort. При использовании второго обработчика переключение между задачами происходит корректно, но другие прерывания (USART, таймеры) не работают (тоже происходит исключение Data Abort). Подскажите, как можно объединить два эти обработчика. И, если не трудно, оставьте ссылку на data sheet с описанием ассемблера AT91SAM7X256. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xelax 0 11 февраля, 2008 Опубликовано 11 февраля, 2008 · Жалоба :( Во FreeRTOS сохранение контекста реализованно в самой оси. А по сему первый и второй обработчики неверены. Вот так обработчики прерывания стартуют. То есть видно, что адрес IRQ обработчика берётся напрямую из регистра AIC, без каких-либо самостоятельных сохранений контекста b _start /* reset - _start */ ldr pc, _undf /* undefined - _undf */ ldr pc, _swi /* SWI - _swi */ ldr pc, _pabt /* program abort - _pabt */ ldr pc, _dabt /* data abort - _dabt */ nop /* reserved */ ldr pc, [pc,#-0xF20] /* IRQ - read the AIC */ ldr pc, _fiq /* FIQ - _fiq */ А все твои обработчики, адреса которых ты записываешь в AIC должны иметь следующий вид. Вот пример прерывания от EMAC из примеров с сайта FreeRTOS void vEMACISR_Wrapper( void ) { /* Save the context of the interrupted task. */ portSAVE_CONTEXT(); /* Call the handler to do the work. This must be a separate function to ensure the stack frame is set up correctly. */ vEMACISR_Handler(); /* Restore the context of whichever task will execute next. */ portRESTORE_CONTEXT(); } То есть сначала сохраняется контекст, затем выполняется твой обработчик, затем контекст восстанавливается. Когда реализуешь всё таким образом, должно заработать. З.Ы. ВАЖНО!!! Все функции обработчика должны быть без пролога и эпилога. Т.е. объявлены следующим образом. /* The interrupt entry point is naked so we can control the context saving. */ void vEMACISR_Wrapper( void ) __attribute__((naked)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 11 февраля, 2008 Опубликовано 11 февраля, 2008 · Жалоба То есть сначала сохраняется контекст, затем выполняется твой обработчик, затем контекст восстанавливается. Если не вызывать переключение контекста непосредственно по выходу из обработчика прерывания, то и сохранять весь контекст "по-FreeRTOS-овски" совершенно никчему. Писать совершенно обычные обработчики прерываний можно. У меня, например, крайне редко обработчики прерывания имеют переключение контекста - устраивает вызов планировщика из прерывания и отложенное до окончания текущей задачи/системного тика преключение контекста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xelax 0 11 февраля, 2008 Опубликовано 11 февраля, 2008 · Жалоба Если не вызывать переключение контекста непосредственно по выходу из обработчика прерывания, то и сохранять весь контекст "по-FreeRTOS-овски" совершенно никчему. Писать совершенно обычные обработчики прерываний можно. У меня, например, крайне редко обработчики прерывания имеют переключение контекста - устраивает вызов планировщика из прерывания и отложенное до окончания текущей задачи/системного тика преключение контекста. Можно и своё, но это уже когда в родном FreeRTOS-овском разберёшься. :) А по началу лучше следовать советам(примерам) разработчика оси, хуже точно не будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Chudik 0 23 февраля, 2008 Опубликовано 23 февраля, 2008 · Жалоба А можно линк на страничку, где описывается работа с прерываниями? Чего-то при чтении сайта не нашёл. Или пример оформления обработчика прерывания... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xelax 0 26 февраля, 2008 Опубликовано 26 февраля, 2008 · Жалоба А можно линк на страничку, где описывается работа с прерываниями? Чего-то при чтении сайта не нашёл. Или пример оформления обработчика прерывания... Я из примеров всё беру... Да и в FAQ аффтар на example ссылается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться