arm的FIQ中断裸机特别写法及与ucos管理中断或不管理中断情况下处理,及最近遇到问题的
本人用的是2440开发板,一直以来网上都没找到fiq中断的写法,最后自己写了个如下这样的:IRQ仍然为向量中断,(貌似44b0的时候数据手册还强调这个,2440都没提了)
1、裸机和ucos不管理中断
2440init.s中为
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,
str r8,
ldmfd sp!,{r8-r9,pc}
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there isn''t 'subs pc,lr,#4' at 0x18, 0x1c
str r1,
普通写法,中断处理程序都是带__irq关键字的。好了关键部分了,rINTMOD = 0x00002000;设置想使用FIQ模式的中断,如这里是Timer3
然后就这样 pISR_FIQ = (unsigned int)Timer3Int;这里直接将中断处理程序放在了 FIQ异常的地址处,这也导致缺点明显--只能有一个FIQ中断存在。其它普通中断还这样写pISR_TIMER0 = (unsigned int)OSTickISR;
1、ucos管理中断,中断处理程序都是不带__irq关键字的
;Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1, =OS_CPU_IRQ_ISR ;modify by txf, for ucos
str r1,
; Setup FIQ handler
ldr r0,=HandleFIQ ;This routine is needed
ldr r1, =OS_CPU_FIQ_ISR ;modify by txf, for ucos
str r1,
OS_CPU_IRQ_ISR就不说了,在OS_CPU_A.s中
OS_CPU_FIQ_ISR --------程序来源于uCos2-2.83-AN-1014这本书
STMFD SP!, {R1-R4} ; PUSH WORKING REGISTERS ONTO FIQ STACK
MOV R1, SP ; Save FIQ stack pointer
SUB R2, LR,#4 ; Adjust PC for return address to task
MRS R3, SPSR ; Copy SPSR (i.e. interrupted task''s CPSR)
MOV R4, R3
AND R4, R4, #0x1F ; Isolate Mode bits
CMP R4, #IRQMODE ; See if we interrupted an IRQ
BEQ OS_CPU_FIQ_ISR_2 ; Branch if yes.
; ===== FIQ interrupted Task =====
MSR CPSR_c, #(NOINT | SVCMODE) ; Change to SVC mode
; SAVE TASK'S CONTEXT ONTO TASK'S STACK
STMFD SP!, {R2} ; Push task''s Return PC
STMFD SP!, {LR} ; Push task''s LR
STMFD SP!, {R5-R12} ; Push task''s R12-R5
LDMFD R1!, {R5-R8} ; Move R1-R4 from FIQ to SVC stack
STMFD SP!, {R5-R8}
STMFD SP!, {R0} ; Push task's R0 onto task's stack
STMFD SP!, {R3} ; Push task's CPSR (i.e. FIQ's SPSR)
; HANDLE NESTING COUNTER
LDR R0, =OSIntNesting ; OSIntNesting++;
LDRB R1,
ADD R1, R1,#1
STRB R1,
CMP R1, #1 ; if (OSIntNesting == 1){
BNE OS_CPU_FIQ_ISR_1
LDR R4, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP
LDR R5,
STR SP, ; }
OS_CPU_FIQ_ISR_1
MSR CPSR_c, #(NOINT | FIQMODE) ; Change to FIQ mode
ADD SP, SP, #16 ; Adjust FIQ stack pointer
LDR R0, =Timer0Int ; OS_CPU_FIQ_ISR_Handler();
MOV LR, PC
BX R0
MSR CPSR_c, #(NOINT | SVCMODE) ; Change to SVC mode
LDR R0, =OSIntExit ; OSIntExit();
MOV LR, PC
BX R0
; RESTORE NEW TASK''S CONTEXT
LDMFD SP!, {R4} ; Pop new task''s CPSR
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12,LR,PC}^ ; Pop new task''s context
OS_CPU_FIQ_ISR_2
; SAVE IRQ'S CONTEXT ONTO FIQ'S STACK
STMFD SP!, {R0-R7,LR} ; Push shared registers
; HANDLE NESTING COUNTER
LDR R0, =OSIntNesting ; OSIntNesting++; (Notify uC/OS-II)
LDRB R1,
ADD R1, R1,#1
STRB R1,
LDR R0, =Timer0Int ; OS_CPU_FIQ_ISR_Handler();
MOV LR, PC
BX R0
; HANDLE NESTING COUNTER
LDR R0, =OSIntNesting ; OSIntNesting--;
LDRB R1, ; NO need to call OSIntExit() ret to IRQ
SUB R1, R1, #1
STRB R1,
LDMFD SP!, {R0-R7,LR} ; Pop IRQ''s context
LDMFD SP!, {R1-R4} ; PULL WORKING REGISTERS ONTO FIQ STACK
SUBS PC, LR, #4 ; Return to IRQ
以上均由本人测试通过,各位可放心使用,关于OSTickISR中断,一直以来都好使用没外接TOUT的Timer4,但最近碰到了死机问题,最后使用Timer0,
并通过rPRIORITY = 0x00080000;改变其在所有IRQ中断中的优先级就改善了这种死机情况,但中断过高后仍然会死机!而用裸机不加ucos系统就没问题。不知道原因,特别是用ucos管理中断时候更容易死机,详细情况见俺的另一个帖子。
最后最近在debug过程中遇到了这个问题
这样写
t = b + 0.5;
a = 100.0 / t;
和这样写
a = 100.0 /(b + 0.5);
一样吗??不一样 这里注意t 和 a 是 int 还是 float
最最后,国际惯例,转载请注明出处,用于商业用途请跟本人联系,欢迎坛友讨论! 楼主玩过ARM7吗?
请教:ARM7的FIQ怎么写啊?
页:
[1]