📄 irqswitch.s.old
字号:
; irqswitch.s - determine whether an IRQ is for the application or RM.
; Copyright (C) 2000 ARM Limited.
; All rights reserved.
; RCS $Revision: 1.1.2.3 $
; Checkin $Date: 2000/11/01 19:30:19 $
; Revising $Author: sellis $
; This code demonstrates how an application's interrupt handler can
; co-operate with RM's interrupt handler.
;
; The structure is as follows:
; Stack some registers.
; Check for any application-specific interrupt sources.
; If these have been triggered, call the relevant handler.
; Otherwise, it must be a RealMonitor interrupt:
; Restore the stack to the state expected by RM_IRQHandler2
; Call RM_IRQHandler2
;
; The application-specific handling in this case just uses uHAL's
; interrupt detection and handling code: the READ_INT macro determines
; which interrupts sources are active, and uHALir_DispatchIRQ
; passes control to the relevant handler.
;
; This code is for demonstration purposes only: it is not intended
; to replace the code in uHAL's irqtrap.s for general purpose uHAL
; applications.
; ------------------------------------------------------------------
; READ_INT
; --------
; uHAL macro to read which interrupt(s) is active (result in $w1)
; Get interrupt controller definitions from uHAL.
INCLUDE rm_options.s
INCLUDE rm_comms.s
INCLUDE aic.inc
INCLUDE usart2.inc
INCLUDE irq.mac
COMMTX_MASK EQU 0x40000000
COMMRX_MASK EQU 0x80000000
DBGU_BASE EQU 0xFFFFF200
IF RM_OPT_USE_INTERRUPTS
IMPORT RM_IRQHandler2
IMPORT irq1_c_handler
ENDIF
AREA demo_trap, CODE, READONLY
EXPORT App_IRQDispatch
MACRO
$label READ_INT $w1, $w2, $w3
LDR $w2, =AIC_BASE
LDR $w1,[$w2, #AIC_IVR] ; Dummy read of vector to enter int hdlr.
LDR $w1,[$w2, #AIC_ISR]
LDR $w2, =DBGU_BASE
LDR $w1,[$w2, #US_CSR]
MEND
MACRO
$label IRQ_EXIT $w1
LDR $w1, =AIC_BASE
STR $w1,[$w1, #AIC_EOICR] ; Dummy write end of interrupt hndlr.
MEND
ROUT
App_IRQDispatch
; Point the lr back to the instruction which was interrupted.
SUB lr, lr, #4
; Save enough registers to call APCS-compliant C functions.
STMFD sp!, {r0-r3, ip, lr}
; READ_INT returns a bit-mask containing a '1' for each active interrupt source.
READ_INT r0, r1, r2
IF RM_OPT_USE_INTERRUPTS
; Check whether anything other than a RealMonitor IRQ occurred:
; this gives priority to app interrupts over DCC interrupts.
ANDS r0, r0, #COMMRX_MASK :OR: COMMTX_MASK
BNE no_app_irqs
ENDIF
app_IRQHandler
; An application-specific interrupt has occurred: pass control
; to application code.
BL irq1_c_handler
IRQ_EXIT r0
; Return to the foreground application.
LDMFD sp!, {r0-r3, ip, pc}^
IF RM_OPT_USE_INTERRUPTS
; No app irqs occurred, so process RealMonitor traffic.
no_app_irqs
; Remove r0-r3 from the stack, leaving 'ip' and the adjusted
; 'lr', then call RM's interrupt handler.
IRQ_EXIT r0
LDMFD sp!, {r0-r3}
LDR ip, =RM_IRQ_BASE
B RM_IRQHandler2
ENDIF
END
; end of file irqswitch.s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -