*********************************************************** ***************************; productors.s; *************** *********************************************************** ************; define the size of the stack, according to changing needs FIQ_STACK_LENGTH EQU 0IRQ_STACK_LENGTH EQU 64ABT_STACK_LENGTH EQU 0UND_STACK_LENGTH EQU 0; VICVectAddr register address VICVectAddr EQU 0xFFFFF030; for I bit in the program status register (IRQ Interrupt mask bit) Noint EQU 0x80
The introduced external label is in this statement import fiq_exception; fast disrupting exception handler IMPORT SoftwareInterrupt; Reset vector entry import osintxsw; interrupt task switch function import Osintexit; interrupt exit function import Ostcbcur; point to current task TCB Pointer import ostcbhighrdy; pointing to the Task TCB to be run (highest priority task) Import OsintNesting; interrupt nested counter
; Giving the outside the label in this statement, initstack is the necessary Export Initack Export Vectors
Code32
Area Startup, Code, Readonly
ENTRY; interrupt vector table Vectors LDR PC, ResetAddr LDR PC, UndefinedAddr LDR PC, SWI_Addr LDR PC, PrefetchAddr LDR PC, DataAbortAddr DCD 0xb9205f80 LDR PC, [PC, # -0xff0]; 0xFFFFF030 VICVectAddr address register LDR PC, FIQ_Addr
ResetAddr DCD ResetUndefinedAddr DCD UndefinedSWI_Addr DCD SoftwareInterruptPrefetchAddr DCD PrefetchAbortDataAbortAddr DCD DataAbortnouse DCD 0IRQ_Addr DCD IRQ_HandlerFIQ_Addr DCD FIQ_Handler
The interrupt service program with the macro of the interface interface Macro $ IRQ_LABEL HANDAL $ IRQ_EXCEPTIONEXPORT $ IRQ_LABEL; the output marker import $ Irq_Exception; referenced external label
$ IRQ_LABEL SUB LR, LR, # 4; Calculate Return Address STMFD SP !, {R0-R3, R12, LR}; Save Task Environment MRS R3, SPSR; Save Status STMFD SP !, {R3}
LDR R2, = OsintNesting; OsintNesting LDRB R1, [R2] Add R1, R1, # 1 STRB R1, [R2] BL $ IRQ_EXCEPTION; invoke C language interrupt handler; MSR write status register command makes CPSR [7: 0] = 0B10010010; Role is the IRQ interrupt MSR CPSR_C, # 0x92 BL OSINTEXIT; call Osintexit; Compare ostcbhighrdy and ostcbcur; function to determine if task switching LDR R0 after exiting interrupt processing, = ostcbhighrdy LDR R0, [R0] LDR R1, = OSTCBCUR LDR R1, [R1] CMP R0, R1 LDMFD SP !, {R3} MSR SPSR_CXSF, R3; SPSR [31: 0] = R3
LDMEQFD SP !, {R0-R3, R12, PC} ^; does not perform task to switch, restore task environments LDR PC, = OSINTCTXSW; Task Switch to call OsintctXsw Mend
Undefined instructions undefined b undefined
Take instructions to stop prefetchabort b prefetchabort
Take data stop Dataabort B Dataabort
; Interrupt (Handler Macro) IRQ_Handler Handler IRQ_EXCEPTION
Quick interrupt FIQ_HANDLER STMFD SP !, {R0-R3, LR} BL FIQ_EXCEPTION LDMFD SP !, {R0-R3, LR} SUBS PC, LR, # 4
; Timer 0 Interrupt (Handler Macro) Timer0_Handler Handler Timer0
; / ********************************************************* **************************; ** Function Name: INITSTACK; ** Function Description: Initialization Stack ; ** input: None; ** Output: None; ** Global variable: None; ** Call Module: None; *********************** *********************************************************** ********** InitStack MOV R0, LR; use R0 to save the return address; set the interrupt mode stack MSR CPSR_C, # 0xd2 LDR SP, Stackirq; Set the fast interrupt mode stack MSR CPSR_C, # 0xd1 LDR SP, Stackfiq; Setting the Stop Mode Stack MSR CPSR_C, # 0xD7 LDR SP, StackAbt; Set Undefined Mode Stack MSR CPSR_C, # 0xDB LDR SP, STACKUND; Set System Mode Stack MSR CPSR_C, # 0xDF LDR SP, Stackirq MOV PC, R0; Use R0 to return StackIrq DCD (IrqStackSpace IRQ_STACK_LENGTH * 4 - 4) StackFiq DCD (FiqStackSpace FIQ_STACK_LENGTH * 4 - 4) StackAbt DCD (AbtStackSpace ABT_STACK_LENGTH * 4 - 4) StackUnd DCD (UndtStackSpace UND_STACK_LENGTH * 4 - 4)
; / * Allocate stack space * / AREA MyStacks, DATA, NOINITIrqStackSpace SPACE IRQ_STACK_LENGTH * 4; interrupt mode stack space FiqStackSpace SPACE FIQ_STACK_LENGTH * 4; fast interrupt mode stack space AbtStackSpace SPACE ABT_STACK_LENGTH * 4; suspend righteous mode stack space UndtStackSpace SPACE UND_STACK_LENGTH * 4 ; Undefined mode stack end