📄 handler.s
字号:
; ********************************************************************************
; *
; * ARM Strategic Support Group
; *
; ********************************************************************************
; ********************************************************************************
; *
; * Module : handler.s
; * Description :
; *
; * Provides an IRQ handler that both services the interrupt for
; * both the timer and button interrupt. For the timer interrupt
; * a context change occurs between two tasks A and B.
; *
; * Tool Chain : ARM Developer Suite v1.0
; * Platform : Evaluator7T
; * History :
; *
; * 970326 DBrooke
; * - created example code
; *
; * 980420 MEchavarria
; * - modified for Sharp 790A
; * - added timer counter interrupt handler
; *
; * 980429 ASloss
; * - added button interrupt handler
; *
; * 990930 ASloss
; * - added context switch
; *
; * 2000-04-2 Andrew N. Sloss
; * - ported to the Evaluator7T
; *
; * Notes :
; *
; * The AREA must have
; * - the attribute READONLY, otherwise the linker will not
; * place it in ROM.
; * - the attribute CODE, otherwise the assembler will not
; * let us put any code in this AREA
; *
; ********************************************************************************
; ********************************************************************************
; * IMPORT
; ********************************************************************************
IMPORT taskb_process
IMPORT timer_irq
IMPORT button_irq
; ********************************************************************************
; * EXPORT
; ********************************************************************************
EXPORT handler_irq
EXPORT Angel_IRQ_Address
EXPORT SetupSVC
EXPORT handler_taskbpcb_str
EXPORT handler_taskapcb_str
EXPORT handler_currenttaskid_str
; ********************************************************************************
; * MACROS
; ********************************************************************************
SVC32md EQU 0x13
USR32md EQU 0x10
; *********************************************************************************
; * ROUTINES
; *********************************************************************************
AREA irq, CODE, READONLY
; -- address of the IRQ controller for the Samsung KS32C50100.
INTPND DCD 0x03ff4004 ;IRQ controller
; -- handler_irq ------------------------------------------------------------------
;
; Description : handles the IRQ interrupt and determines the source and then
; vectors to the correct interrupt rountine.
;
handler_irq
; -- save current context for APCS ........................
STMFD sp!, {r0 - r3, LR}
; -- identify source of interrupt .........................
LDR r0, INTPND
LDR r0, [r0]
; -- check if source is a timer interrupt .................
TST r0, #0x0400
BNE handler_timer
; -- check if source is a button interrupt ................
TST r0, #0x0001
BNE handler_button
; -- check if source is an Angel interrupt ..................
LDMFD sp!, {r0 - r3, lr}
LDR pc, Angel_IRQ_Address
; -- handler_timer ---------------------------------------------------------------
;
; Description : services the timer interrupt and complete a context change.
;
handler_timer
; -- reset the timer ................................
STMFD sp!, {r4 - r12}
BL timer_irq
LDMFD sp!, {r4 - r12}
; -- identify current task ..........................
LDR r0, =handler_currenttaskid_str
LDR r1,[r0]
CMP r1,#0
BNE handler_swapBtoA
; ***************************************************
; Setup context switch from TASK A to TASK B
;
handler_swapAtoB
; -- set process ID to 1 (TASK B) ...................
MOV r1, #1
STR r1, [r0]
; -- set current_task_addr to TASK A ................
LDR r0, =handler_currenttaskaddr_str
LDR r1, =handler_taskapcb_str
STR r1, [r0]
; -- set next_task to point to TASK B ...............
LDR r0, =handler_taskbpcb_str
LDR r1, =handler_nexttask_str
STR r0, [r1]
B handler_contextswitch
; ***************************************************
; Setup context switch from TASK B to TASK A
;
handler_swapBtoA
; -- set process ID to 0 (TASK A) ....................
MOV r1, #0
STR r1, [r0]
; -- set current_task_addr to TASK B .................
LDR r0, =handler_currenttaskaddr_str
LDR r1, =handler_taskbpcb_str
STR r1, [r0]
; set next_task to point to TASK A ...................
LDR r0, =handler_taskapcb_str
LDR r1, =handler_nexttask_str
STR r0, [r1]
; ****************************************************
; Carry out context switch
;
handler_contextswitch
; -- reset and save IRQ stack ........................
LDR r0, =handler_irqstack_str
MOV r1, sp
ADD r1, r1, #5*4
STR r1, [r0]
; -- restore the remaining registers .................
LDMFD sp!,{r0-r3,lr}
; -- load and position r13 to point into current PCB .
LDR r13, =handler_currenttaskaddr_str
LDR r13, [r13]
SUB r13, r13,#60
; -- store the current user registers in current PCB .
STMIA r13, {r0-r14}^
MRS r0, SPSR
STMDB r13, {r0,r14}
; -- load and position r13 to point into next PCB ....
LDR r13, =handler_nexttask_str
LDR r13, [r13]
SUB r13, r13,#60
; -- load the next task and setup PSR ................
cmp r13, #0
LDMNEDB r13, {r0,r14}
MSRNE spsr_cxsf, r0
LDMNEIA r13, {r0-r14}^
AND r0,r0,r0 ; nop
; -- load the IRQ stack into r13_irq ..................
LDR r13, =handler_irqstack_str
LDR r13,[r13]
; -- return the next task .............................
SUBS pc, r14, #4
; -- handler_button ----------------------------------------------------------------
;
; Description : services the button interrupt.
;
handler_button
; -- call C service routine for button
BL button_irq
; -- return to the current task ........................
LDMFD sp!, {r0 - r3,lr}
SUBS pc, lr, #4
; -- SetupSVC -----------------------------------------------------------------------
;
; Description : Stub
;
SetupSVC
MOV pc, lr ; return
; ***********************************************************************************
; * DATA AREA
; ***********************************************************************************
AREA var, DATA, READWRITE
; -- Scratch location for Angel IRQ Handler address ....
Angel_IRQ_Address
DCD 0x00000000
; -- Context ID 1=TASK B 0=TASK A ........................
handler_currenttaskid_str
DCD 0x0
; -- Address of the PCB for the next Task ..............
handler_currenttaskaddr_str
DCD 0x0
; -- Address of the PCB for the next Task ..............
handler_nexttask_str
DCD 0x0
; -- Store a copy of the IRQ stack .....................
handler_irqstack_str
DCD 0x0
;
; +-----------------+
; | PCB Structure |
; +-----------------+
; | -4 | r14 |
; | -8 | r13 |
; | -12 | r12 |
; | -16 | r11 |
; | -20 | r10 |
; | -24 | r9 |
; | -28 | r8 |
; | -32 | r7 |
; | -36 | r6 |
; | -40 | r5 |
; | -44 | r4 |
; | -48 | r3 |
; | -52 | r2 |
; | -56 | r1 |
; | -60 | r0 |
; | -64 | LR |
; | -68 | SPSR |
; +-----------------+
;
; Note: the offsets are from handler_task?pcb_str
;
; -- Context PCB for TASK A ............................
handler_taskabottom
% 68
handler_taskapcb_str
; -- Context PCB for TASK B ............................
handler_taskbbottom
% 68
handler_taskbpcb_str
END
; ***********************************************************************************
; * End OF handler.s
; ***********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -