📄 os_cpu_a.s
字号:
;****************************************************************************
; Name : OS_CPU_A.S *
; Modified : xuwei 2007-09-07 *
; Description: 用汇编语言编写与处理器相关的函数,至少包括以下四个函数: *
; OSStartHighRdy(); *
; OSCtxSw(): *
; OSIntCtxSw(); *
; OSTickISR(); *
;****************************************************************************
BIT_TIMER5 EQU (0x1<<8)
I_ISPC EQU 0x1e00024
INTMSK EQU 0x1e0000c
AREA |subr|, CODE, READONLY
IMPORT OSTCBCur
addr_OSTCBCur DCD OSTCBCur
IMPORT OSTCBHighRdy
addr_OSTCBHighRdy DCD OSTCBHighRdy
IMPORT OSPrioCur
addr_OSPrioCur DCD OSPrioCur
IMPORT OSPrioHighRdy
addr_OSPrioHighRdy DCD OSPrioHighRdy
IMPORT OSRunning
IMPORT OSIntEnter
IMPORT OSIntExit
IMPORT OSTimeTick
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: OSStartHighRdy ;
; Purpose: 该函数由OSStart()函数调用,功能是让进入就绪态的优先级最高的任务运行 ;
; Processing: See uC/OS-II Task Level Context Switch flow chart ;
; Parameters: void ;
; Outputs: None ;
; Returns: void ;
; Notes: 在调用OSStart()之前,必须先调用OSInit()函数,且已经建立了至少一个任务 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXPORT OSStartHighRdy
OSStartHighRdy
LDR r0, =OSRunning ; OSRunning = 1
MOV r1, #1
STRB r1, [r0]
LDR r5, addr_OSTCBHighRdy ; Get highest priority task TCB address
LDR r5, [r5] ; get stack pointer
LDR sp, [r5] ; switch to the new stack
LDMFD sp!, {r4} ; get new state from top of the stack
MSR CPSR_cxsf, r4 ; CPSR should be SVC32Mode
LDMFD sp!, {r0-r12, lr, pc } ; start the new task
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: OS_TASK_SW ;
; Purpose: 实现任务上下文切换 ;
; Processing: See uC/OS-II Task Level Context Switch flow chart ;
; Parameters: void ;
; Outputs: None ;
; Returns: void ;
; Notes: The whole function is executed in CRITICAL state. See OSSched(). ;
; ;
; On entry, OSTCBCur and OSPrioCur hold the current TCB and priority ;
; and OSTCBHighRdy and OSPrioHighRdy contain the same for the task ;
; to be switched to. ;
; The following code assumes that the virtual memory is directly ;
; mapped into physical memory. If this is not true, the cache must ;
; be flushed at context switch to avoid address aliasing. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXPORT OSCtxSw
OSCtxSw
STMFD sp!, {lr} ; save pc
STMFD sp!, {lr} ; save lr
STMFD sp!, {r0-r12} ; save register file and ret address
MRS r4, CPSR
STMFD sp!, {r4} ; save CPSR
LDR r4, addr_OSTCBCur ; 在当前任务的任务控制块中保存当前任务的堆栈指针
LDR r5, [r4]
STR sp, [r5] ;
LDR r4, addr_OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR r5, addr_OSPrioHighRdy
LDRB r6, [r5]
STRB r6, [r4]
LDR r4, addr_OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
LDR r5, addr_OSTCBCur
LDR r4, [r4]
STR r4, [r5]
LDR sp, [r4] ; 从新任务的任务控制块中弹出堆栈指针
LDMFD sp!, {r4} ;
MSR CPSR_cxsf, r4 ;
LDMFD sp!, {r0-r12, lr, pc} ; 弹出处理器所有寄存器值
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: OSIntCtxSW ;
; Purpose: 在ISR中实现任务切换功能,假定所有处理器寄存器都已被正确地保存到了被中断任务的堆栈中 ;
; Processing: See uC/OS-II Interrupt Level Context Switch flow chart ;
; Parameters: void ;
; Outputs: None ;
; Returns: void ;
; Notes: The whole function is executed in CRITICAL state. See OSIntExit(). ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXPORT OSIntCtxSw
OSIntCtxSw
LDR r6, addr_OSPrioHighRdy ;OSPrioCur = OSPrioHighRdy
LDR r5, addr_OSPrioCur
LDRB r6, [r6]
STRB r6, [r5]
LDR r4, addr_OSTCBHighRdy ;OSTCBCur = OSTCBHighRdy
LDR r5, addr_OSTCBCur
LDR r4, [r4]
STR r4, [r5]
LDR sp, [r4]
LDMFD sp!, {r4} ; pop new task cpsr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task r0-r12,lr & pc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: OSTickISR ;
; Purpose: Timer0 Interrupt Sever ;
; Processing: Call OSTimeTick ;
; Parameters: void ;
; Outputs: None ;
; Returns: void ;
; Notes: ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LINK_SAVE DCD 0
PSR_SAVE DCD 0
EXPORT OSTickISR
OSTickISR
STMFD sp!, {r4} ; 先保存寄存器r4
LDR r4, =LINK_SAVE
STR lr, [r4] ; 将lr保存在LINK_SAVE中
MRS lr, spsr ; lr = spsr
STR lr, [r4, #4] ; 将spsr_irq保存在PSR_SAVE中
LDMFD sp!, {r4} ; 寄存器r4出栈
ORR lr, lr, #0x80 ; 将spsr_irq中IRQ位禁止
MSR cpsr_cxsf, lr ; 将当前程序状态寄存器CPSR中IRQ位禁止
SUB sp, sp, #4 ; Space for PC寄存器
STMFD sp!, {r0-r12, lr} ; 将除PC外的所有处理器寄存器入栈
LDR r4, =LINK_SAVE
LDR lr, [r4, #0]
SUB lr, lr, #4 ; lr中保存的值为PC+4
STR lr, [sp, #(14*4)] ; PC寄存器入栈
LDR r4, [r4, #4] ; r4 = PSR_SAVE,
STMFD sp!, {r4} ; spsr_irq最后入栈
LDR r4, addr_OSTCBCur ; 将保存好的堆栈指针保存到被中断任务的任务块中
LDR r4, [r4]
STR sp, [r4]
LDR r0, =I_ISPC ; 必须手动清除中断pending位
LDR r1, =BIT_TIMER5
STR r1, [r0]
BL OSIntEnter
BL OSTimeTick
BL OSIntExit
LDMFD sp!, {r4} ; pop new task cpsr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task r0-r12,lr & pc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Functions: ARMDisableInt ARMEnableInt ;
; Purpose: Disable and enable IRQ and FIQ preserving current CPU mode. ;
; Processing: Push the cpsr onto the stack, Disable IRQ and FIQ interrupts, Return ;
; Parameters: void ;
; Outputs: None ;
; Returns: void ;
; Notes: ;
; (1) Can be called from SVC mode to protect Critical Sections. ;
; (2) Do not use these calls at interrupt level. ;
; (3) Used in pairs within the same function level; ;
; (4) Will restore interrupt state when called; i.e., if interrupts ;
; are disabled when DisableInt is called, interrupts will still ;
; still be disabled when the matching EnableInt is called. ;
; (5) Uses the method described by Labrosse as "Method 2". ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXPORT ARMDisableInt
ARMDisableInt
MRS r0, cpsr
STMFD sp!, {r0} ; push current PSR
ORR r0, r0, #0xC0
MSR cpsr_c, r0 ; disable IRQ and FIQ
MOV pc, lr
EXPORT ARMEnableInt
ARMEnableInt
LDMFD sp!, {r0} ; pop current PSR
MSR cpsr_c, r0 ; restore original cpsr
MOV pc, lr
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -