|
Вложенные прерывания, GCC и ARM7 |
|
|
|
Mar 1 2010, 05:08
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032

|
Доброго времени суток! Работаю с платой LPC2478, требуется реализовать вложенные (nested) прерывания. Нарыл несколько статей на эту тему, но пока ни один метод не запахал. Тестирую прерывания таким образом: Код void TestInterrupts::TestTimers() { myPrintf("\nSTART TestTimers()\n");
Timer0VICInit(Timer0ISR); Timer1VICInit(Timer1ISR); Timer1StartWithInt(1000);
myPrintf("\nEND TestTimers()\n"); }
void TestInterrupts::Timer0ISR() { T0IR = TIR_MR0_INT; // reset interrrupt flags myPrintf("\nTimer0ISR()\n"); // Dummy write to VIC to signal end of interrupt VICVectAddr = 0x00000000; }
void TestInterrupts::Timer1ISR() { IENABLE;
T1IR = TIR_MR0_INT; // reset interrrupt flags myPrintf("\nSTART Timer1ISR()\n"); Timer0StartWithInt(5000); volatile tU8 dummy = 0; while(1) { dummy = 0; } myPrintf("\nEND Timer1ISR()\n"); IDISABLE; // Dummy write to VIC to signal end of interrupt VICVectAddr = 0x00000000; } Где в качестве IENABLE пробовал разные последовательности ассемблерных команд, вычитанных с разных статей: Код // FROM Nesting of interrupts in the LPC2000 (AN10381) #define IENABLE /* Nested Interrupts Entry */ \ __asm__ ("MRS LR, SPSR"); /* Copy SPSR_irq to LR */ \ __asm__ ("STMFD SP!, {LR}"); /* Save SPSR_irq */ \ __asm__ ("MSR CPSR_c, #0x1F"); /* Enable IRQ (Sys Mode) */ \ __asm__ ("STMFD SP!, {LR}"); /* Save LR */ \ Код // FROM Real-time processing with the Philips LPC ARM microcontroller; using GCC and the MicroC/OS-II RTOS. #define IENABLE /* Nested Interrupts Entry */ \ __asm__ ("sub lr, lr, #4"); /* (1) Save IRQ context, including the APCS registers, and r4-6 */ \ __asm__ ("stmfd sp!, {r0-r6, ip, lr}"); \ __asm__ ("mrs r4, spsr"); /* (2) Save the SPSR_irq register */ \ __asm__ ("ldr r5, =0xFFFFFF00"); /* (3) Read the VICVectAddr */ \ __asm__ ("ldr r6, [r5]"); \ __asm__ ("msr cpsr_c, 0x1F"); /* (4) Change to SYS mode and enable IRQ */ \ __asm__ ("stmfd sp!, {lr}"); /* (5) Save the banked SYS mode link register */ \ То есть, на консоли должно появиться Цитата START TestTimers() END TestTimers() START Timer1ISR() START Timer0ISR() А на самом деле последняя строка не выводиться, что говорит о невхождении в обработчик вложенного прерывания Timer0. Так вот, первый мой вопрос, какая же все таки последовательной команд должна быть в прологе и эпилоге обработчика для LPC2478? И еще, во втором случае IENABLE полное описание вхождения и вывода их вложенных прерываний выглядит так: Цитата nested_irq_isr: /* (1) Save IRQ context, including the APCS registers, and r4-6 */ sub lr, lr, #4 stmfd sp!, {r0-r6, ip, lr} /* (2) Save the SPSR_irq register */ mrs r4, spsr /* (3) Read the VICVectAddr */ ldr r5, VICVECTADDR ldr r6, [r5] /* (4) Change to SYS mode and enable IRQ */ msr cpsr_c, #SYS_MODE /* (5) Save the banked SYS mode link register */ stmfd sp!, {lr} /* (6) Call the C-coded handler */ mov lr, pc ldr pc, r6 /* (7) Restore SYS mode link register */ ldmfd sp!, {lr} 36 AR1803 May 10, 2006 /* (8) Change to IRQ mode and disable IRQ */ msr cpsr_c, #IRQ_MODE|IRQ_DISABLE /* (9) Restore the SPSR */ msr spsr, r4 /* (10) Acknowledge the VIC */ mov r0, #0 str r0, [r5] /* (11) Restore IRQ context and return from interrupt */ ldmfd sp!, {r0-r6, ip, pc}^ И это описание натолкнуло меня на дополнительный вопрос, а можно ли в GCC переопределять последовательность операций для вызова функций, например путем создания собственных атрибутов для функций. И дальнейшим их использованием в примерно таком виде: Код static void Timer0ISR() __attribute__ ((my_nested_interrupt))
Сообщение отредактировал Novichok1 - Mar 1 2010, 05:14
|
|
|
|
|
 |
Ответов
|
Mar 1 2010, 09:12
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032

|
Может и правда, дело в стартапе, выложу его на всякий случай, может кто и увидит несостыковку. CODE # # *** Startup Code (executed after Reset) *** #
#include "config.h"
# Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
.equ Mode_USR, 0x10 .equ Mode_FIQ, 0x11 .equ Mode_IRQ, 0x12 .equ Mode_SVC, 0x13 .equ Mode_ABT, 0x17 .equ Mode_UND, 0x1B .equ Mode_SYS, 0x1F
.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */ .equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
.equ sram_bottom, SRAM_SADDR .equ sram_top, SRAM_TOP .equ stackTop, SRAM_TOP
#define VAL_PLLCFG_MSEL ((PLL_MUL - 1) << 0) #if (PLL_DIV == 1) #define PLL_DIV_VALUE 0x00 #elif (PLL_DIV == 2) #define PLL_DIV_VALUE 0x01 #elif (PLL_DIV == 4) #define PLL_DIV_VALUE 0x10 #elif (PLL_DIV == 8) #define PLL_DIV_VALUE 0x11 #endif #define VAL_PLLCFG_PSEL (PLL_DIV_VALUE << 5) #define VAL_PLLCFG (VAL_PLLCFG_MSEL | VAL_PLLCFG_PSEL)
# Phase Locked Loop (PLL) definitions .equ PLL_BASE, 0xE01FC080 /* PLL Base Address */ .equ PLLCON_OFS, 0x00 /* PLL Control Offset*/ .equ PLLCFG_OFS, 0x04 /* PLL Configuration Offset */ .equ PLLSTAT_OFS, 0x08 /* PLL Status Offset */ .equ PLLFEED_OFS, 0x0C /* PLL Feed Offset */ .equ PLLCON_PLLE, (1<<0) /* PLL Enable */ .equ PLLCON_PLLC, (1<<1) /* PLL Connect */ .equ PLLSTAT_PLOCK, (1<<10) /* PLL Lock Status */
#define HANDLER(HandlerLabel,HandleLabel) \ HandlerLabel: ;\ sub sp, sp, #4 ;\ stmfd sp!, {r0};\ ldr r0, =HandleLabel;\ ldr r0, [r0] ;\ str r0, [sp,#4] ;\ ldmfd sp!, {r0,pc}
# Starupt Code must be linked first at Address at which it expects to run.
.text .arm # ****************************************************************************** # Declare external function # ****************************************************************************** .extern lowLevelInit .extern exceptionHandlerInit
.global _startup .func _startup _startup:
# Exception Vectors # Mapped to Address 0.
Vectors: _vectors: # If vectors are in FLASH, starting at 0x00000000 #if (MAM_MAP == 1) B handleReset /* jump to reset code */ B HandlerUndef /* handlerUndef */ B HandlerSWI /* SWI interrupt handler */ B HandlerPabort /* handlerPAbort */ B HandlerDabort /* handlerDAbort */ NOP /* Reserved Vector */ #if (IRQ_HANDLER == 0) B HandlerIRQ /* handlerIRQ */ #else LDR PC,[PC,#-0x120] /* jump to address supplied by VIC */ #endif B HandlerFIQ /* handlerFIQ */
# Create handlers HANDLER(HandlerUndef, HandleUndef) HANDLER(HandlerSWI, HandleSWI) HANDLER(HandlerPabort, HandlePabort) HANDLER(HandlerDabort, HandleDabort) #if (IRQ_HANDLER == 0) HANDLER(HandlerIRQ, HandleIRQ) #endif HANDLER(HandlerFIQ, HandleFIQ)
# If vectors are in RAM, starting at 0x40000000 #else LDR PC,[PC,#resetHandlerAddress - . - 8] /* handle reset */ LDR PC,[PC,#undefHandlerAddress - . - 8] /* handlerUndef */ LDR PC,[PC,#swiHandlerAddress - . - 8] /* SWI interrupt handler */ LDR PC,[PC,#pabortHandlerAddress - . - 8] /* handlerPAbort */ LDR PC,[PC,#dabortHandlerAddress - . - 8] /* handlerDAbort */ NOP /* Reserved Vector */ #if (IRQ_HANDLER == 0) LDR PC,[PC,#irqHandlerAddress - . - 8] /* jump to common irq handler */ #else LDR PC,[PC,#-0x120] /* jump to address supplied from VIC */ #endif LDR PC,[PC,#fiqHandlerAddress - . - 8] /* handlerFIQ */
resetHandlerAddress: .word handleReset
undefHandlerAddress: .word 0
swiHandlerAddress: .word 0
pabortHandlerAddress: .word 0
dabortHandlerAddress: .word 0
irqHandlerAddress: .word 0
fiqHandlerAddress: .word 0
#endif
# Reset Handler handleReset:
# Call pll initialization # BL pllInit
# Setup Stack for each mode LDR R0, =stackTop
# Enter Undefined Instruction Mode and set its Stack Pointer MSR CPSR_c, #Mode_UND|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #stackSize_UND
# Enter Abort Mode and set its Stack Pointer MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #stackSize_ABT
# Enter FIQ Mode and set its Stack Pointer MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #stackSize_FIQ
# Enter IRQ Mode and set its Stack Pointer MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #stackSize_IRQ
# Enter Supervisor Mode and set its Stack Pointer MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #stackSize_SVC
# Enter System Mode and set its Stack Pointer MSR CPSR_c, #Mode_SYS|I_Bit|F_Bit MOV SP, R0
# Setup a default Stack Limit (when compiled with "-mapcs-stack-check") SUB SL, SP, #stackSize_SYS
#if (MAM_MAP == 2) # Copy exception vectors into SRAM MOV R8, #SRAM_SADDR LDR R9, =Vectors # Move exception vectors (7 vectors + 1 reserved) LDMIA R9!, {R0-R7} STMIA R8!, {R0-R7} # Move addresses belonging to exception vectors (7 addresses) LDMIA R9!, {R0-R6} STMIA R8!, {R0-R6} #endif
# Call low-level initialization # BL lowLevelInit
# Relocate .data section (Copy from ROM to RAM) LDR R1, =_etext LDR R2, =_data LDR R3, =_edata LoopRel: CMP R2, R3 LDRLO R0, [R1], #4 STRLO R0, [R2], #4 BLO LoopRel
# Clear .bss section (Zero init) MOV R0, #0 LDR R1, =__bss_start__ LDR R2, =__bss_end__ LoopZI: CMP R1, R2 STRLO R0, [R1], #4 BLO LoopZI
# Initialize exception vectors # BL exceptionHandlerInit
# Enter the C code Jump_To_Main: ADR LR, __Return_from_Main MOV R0, #0 MOV R1, #0 LDR R2, =main BX R2
__Return_from_Main: B __Return_from_Main
.size _startup, . - _startup .endfunc
# # Reserve memory for exception handlers # .struct SRAM_SADDR + 0x20 HandleReset:
.struct SRAM_SADDR + 0x24 HandleUndef:
.struct SRAM_SADDR + 0x28 HandleSWI:
.struct SRAM_SADDR + 0x2c HandlePabort:
.struct SRAM_SADDR + 0x30 HandleDabort:
.struct SRAM_SADDR + 0x34 HandleIRQ:
.struct SRAM_SADDR + 0x38 HandleFIQ:
# # Reserve memory for stack areas # .struct STK_SADDR UserStack: /* User stack not used (size = 0) */
.struct UserStack + stackSize_SYS SYSStack:
.struct SYSStack + stackSize_SVC SVCStack:
.struct SVCStack + stackSize_UND UndefStack:
.struct UndefStack + stackSize_ABT AbortStack:
.struct AbortStack + stackSize_IRQ IRQStack:
.struct IRQStack + stackSize_FIQ FIQStack: /* this position equals top of SRAM */
.end Кстати, если следовать советам "Real-time processing with the Philips LPC ARM microcontroller; using GCC and the MicroC/OS-II RTOS." то я подозреваю этот код загрузки обработчика Код nested_irq_isr: /* (1) Save IRQ context, including the APCS registers, and r4-6 */ sub lr, lr, #4 stmfd sp!, {r0-r6, ip, lr} /* (2) Save the SPSR_irq register */ mrs r4, spsr /* (3) Read the VICVectAddr */ ldr r5, VICVECTADDR ldr r6, [r5] /* (4) Change to SYS mode and enable IRQ */ msr cpsr_c, #SYS_MODE /* (5) Save the banked SYS mode link register */ stmfd sp!, {lr} /* (6) Call the C-coded handler */ mov lr, pc ldr pc, r6 /* (7) Restore SYS mode link register */ ldmfd sp!, {lr} /* (8) Change to IRQ mode and disable IRQ */ msr cpsr_c, #IRQ_MODE|IRQ_DISABLE /* (9) Restore the SPSR */ msr spsr, r4 /* (10) Acknowledge the VIC */ mov r0, #0 str r0, [r5] /* (11) Restore IRQ context and return from interrupt */ ldmfd sp!, {r0-r6, ip, pc}^ нужно поместить в макрос HANDLER(HandlerLabel,HandleLabel)? Но тогда возникает вопрос, что такое VICVECTADDR, просто адрес 0xFFFFFF00, или нечто иное?
Сообщение отредактировал rezident - Mar 4 2010, 13:33
Причина редактирования: Редактирование оформления цитаты исходника.
|
|
|
|
Сообщений в этой теме
Novichok1 Вложенные прерывания, GCC и ARM7 Mar 1 2010, 05:08 sergeeff Про прерывания а форуме для ARM столько уже понапи... Mar 1 2010, 06:57 Novichok1 Цитата1. Заставить VIC вызывать по прерыванию С++ ... Mar 1 2010, 08:07 Novichok1 Хорошо, частично разобрался, для вызовов всех прер... Mar 4 2010, 05:44 Novichok1 И благодаря такому подходу исчезли глюки, которые ... Mar 4 2010, 07:06 GetSmart театр одного актёра Mar 4 2010, 23:26 aaarrr Цитата(GetSmart @ Mar 5 2010, 02:26) теат... Mar 4 2010, 23:57 Novichok1 Цитата(aaarrr @ Mar 5 2010, 02:57) Перед ... Mar 5 2010, 04:59  aaarrr Цитата(Novichok1 @ Mar 5 2010, 07:59) Бол... Mar 5 2010, 10:04   GetSmart Цитата(aaarrr @ Mar 5 2010, 15:04) Вложен... Mar 5 2010, 12:14    Novichok1 Цитата(GetSmart @ Mar 5 2010, 15:14) Это ... Mar 5 2010, 12:43     GetSmart Цитата(Novichok1 @ Mar 5 2010, 17:43) То ... Mar 5 2010, 12:54      Novichok1 Цитата(GetSmart @ Mar 5 2010, 15:54) То б... Mar 5 2010, 13:12   Novichok1 Цитата(aaarrr @ Mar 5 2010, 13:04) Вложен... Mar 5 2010, 12:23 GetSmart Цитата(Novichok1)Вот и складывается впечатление, ч... Mar 5 2010, 06:44 Novichok1 Ну точнее, там используется два источника прерыван... Mar 5 2010, 07:22 GetSmart Если после команды ldmfd в эпилоге второго ничего ... Mar 5 2010, 07:43 Novichok1 Цитата(GetSmart @ Mar 5 2010, 10:43) Если... Mar 5 2010, 07:47 GetSmart ЦитатаВсе-таки кажется странным, что некорректный ... Mar 5 2010, 12:35 Novichok1 Цитата(GetSmart @ Mar 5 2010, 15:35) Со с... Mar 5 2010, 12:55 aaarrr Цитата(Novichok1 @ Mar 5 2010, 15:23) А н... Mar 5 2010, 12:41 GetSmart Это не свой атрибут, а стандартный. Используется т... Mar 5 2010, 13:03 GetSmart Цитата(Novichok1)Спасибо, а не в курсе,
Не, не в к... Mar 5 2010, 14:03 GetSmart Novichok1, хотел ещё спросить, зачем было делать о... Mar 11 2010, 12:21 Novichok1 А разве к статическим членам нет доступа? Ведь обр... Mar 11 2010, 15:07 GetSmart Я бы всё таки выделил прерывания из класса. ИМХО э... Mar 11 2010, 16:35 Novichok1 Цитата(GetSmart @ Mar 11 2010, 20:35) Зна... Mar 11 2010, 18:22 GetSmart Вообще, излишняя универсальность, которая не понад... Mar 11 2010, 19:02 Novichok1 Цитата(GetSmart @ Mar 11 2010, 22:02) А ч... Mar 12 2010, 04:49 GetSmart Цитата(Novichok1)Но в любом случае, мне не совсем ... Mar 12 2010, 05:50 Aurochs Цитата(GetSmart @ Mar 12 2010, 07:50) Так... Mar 13 2010, 18:30
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|