📄 os_cpu_a.s
字号:
NoInt EQU 0x80
USR32Mode EQU 0x10
FIQ32Mode EQU 0x11
IRQ32Mode EQU 0x12
SVC32Mode EQU 0x13
SYS32Mode EQU 0x1F
;T_bit用于检测进入异常前cpu是否处于THUMB状态
T_bit EQU 0x20
CODE32
PRESERVE8
AREA |subr|, CODE, READONLY
IMPORT OSTCBCur ;指向当前任务TCB的指针
IMPORT OSTCBHighRdy ;指向将要运行的任务TCB的指针
IMPORT OSPrioCur ;当前任务的优先级
IMPORT OSPrioHighRdy ;将要运行的任务的优先级
IMPORT OSTaskSwHook ;任务切换的钩子函数
IMPORT OSRunning ;uC/OS-II运行标志
IMPORT OsEnterSum ;关中断计数器(关中断信号量
IMPORT OSTimeTick ;系统时钟任务
IMPORT OSIntNesting
IMPORT SWI_Exception
IMPORT SvcStackBase
EXPORT OSIntCtxSw ;中断退出时的入口,参见startup.s中的IRQ_Handler
EXPORT SoftwareInterrupt ;软中断入口
;*********************************************************************************************************
;** 函数名称: SoftwareInterrupt
;** 功能描述: 软件中断,用于提供一些系统服务,功能参考os_cpu_c.c文件
;** 输 入: 依功能而定
;** 输 出 : 依功能而定
;** 全局变量: 无
;** 调用模块: SWI_Exception
;软件中断
SoftwareInterrupt
LDR SP,=SvcStackBase
STMFD SP!,{R0-R3,R12,LR}
MOV R1,SP
MRS R3,SPSR
TST R3,#T_bit
LDRNEH R0,[LR,#-2]
BICNE R0,R0,#0xFF00
LDREQ R0,[LR,#-4]
BICEQ R0,R0,#0xFF000000
CMP R0,#1
LDRLO PC,=OSIntCtxSw
LDREQ PC,=__OSStartHighRdy
BL SWI_Exception
;do not step debug the instruction, or the 'I' bit will be set in CPSR
LDMFD SP!,{R0-R3,R12,PC}^
;*********************************************************************************************************
;** 函数名称: OSIntCtxSw
;** 功能描述: 中断退出时的入口
;** 输 入: R3 :当前任务的状态寄存器CPSR(即SPSR的值)
;** R4-R12:当前任务的R4-R11
;** 当前处理器模式的堆栈结构(出栈次序):R0-R3、R12、PC(当前任务的)
;** 输 出 : 无
;** 全局变量: OSPrioCur,OSPrioHighRdy,OSPrioCur,OSPrioHighRdy
;** 调用模块: 无
OSIntCtxSw
;下面为保存任务环境
LDR R2, [SP, #20] ;获取PC
LDR R12, [SP, #16] ;获取R12
MRS R0, CPSR
MSR CPSR_c, #(NoInt | SYS32Mode)
MOV R1, LR
STMFD SP!, {R1-R2} ;保存LR,PC
;IMPORTANT, R7 save into stack double time, so even number of register stored into stacks
STMFD SP!, {R7-R12} ;保存R4-R12
STMFD SP!, {R4-R7} ;保存R4-R12
MSR CPSR_c, R0
LDMFD SP!, {R4-R7} ;获取R0-R3
ADD SP, SP, #8 ;出栈R12,PC
MSR CPSR_c, #(NoInt | SYS32Mode)
STMFD SP!, {R4-R7} ;保存R0-R3
OSIntCtxSw_0
LDR R1, =OsEnterSum ;获取OsEnterSum
LDR R2, [R1]
STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum
;保存当前任务堆栈指针到当前任务的TCB
LDR R1, =OSTCBCur
LDR R1, [R1]
STR SP, [R1]
BL OSTaskSwHook ;调用钩子函数
;OSPrioCur <= OSPrioHighRdy
LDR R4, =OSPrioCur
LDR R5, =OSPrioHighRdy
LDRB R6, [R5]
STRB R6, [R4]
;OSTCBCur <= OSTCBHighRdy
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
LDR R4, =OSTCBCur
STR R6, [R4]
OSIntCtxSw_1
;获取新任务堆栈指针
LDR R4, [R6]
ADD SP, R4, #72 ;17寄存器OsEnterSum,CPSR,R0-R12,LR,PC
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!, {R4, R5} ;OsEnterSum,CPSR
LDR R3, =OsEnterSum ;恢复新任务的OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R7 }
LDMFD SP!, {R7-R12, LR, PC }^ ;运行新任务
;*********************************************************************************************************
;** 函数名称: __OSStartHighRdy
;** 功能描述: uC/OS-II启动时使用OSStartHighRdy运行第一个任务,
;** OSStartHighRdy会调用__OSStartHighRdy
;** 输 入: 无
;** 输 出 : 无
;** 全局变量: OSRunning,OSTCBCur,OSTCBHighRdy,OsEnterSum
;** 调用模块: OSTaskSwHook
__OSStartHighRdy
MSR CPSR_c, #(NoInt | SYS32Mode)
;告诉uC/OS-II自身已经运行
LDR R4, =OSRunning
MOV R5, #1
STRB R5, [R4]
BL OSTaskSwHook ;调用钩子函数
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
B OSIntCtxSw_1
; MACRO
;$IRQ_Label HANDLER $IRQ_Exception_Function
;
; EXPORT $IRQ_Label
; IMPORT $IRQ_Exception_Function
;
;$IRQ_Label
; SUB LR,LR,#4
; STMFD SP!,{R0-R3,R12,LR}
; MRS R3,SPSR
; STMFD SP,{R3,SP,LR}^
;
; LDR R2,=OSIntNesting
; LDRB R1,[R2]
; ADD R1,R1,#1
; STRB R1,[R2]
;
; SUB SP,SP,#4*3
;
; MSR CPSR_c,#(NoInt | SYS32Mode)
; CMP R1,#1
; LDREQ SP,=StackUsr
;
; BL $IRQ_Exception_Function
; MSR CPSR_c,#(NoInt | SYS32Mode)
; LDR R2,=OsEnterSum
; MOV R1,#1
; STR R1,[R2]
;
; BL OSIntExit
;
; LDR R2,=OsEnterSum
; MOV R1,#0
; STR R1,[R2]
;
; MSR CPSR_c,#(NoInt | IRQ32Mode)
; LDMFD SP,{R3,SP,LR}^
;
; LDR R0,=OSTCBHighRdy
; LDR R0,[R0]
; LDR R1,=OSTCBCur
; LDR R1,[R1]
; CMP R0,R1
;
; ADD SP,SP,#4*3
; MSR SPSR_cxsf,R3
; LDMEQFD SP!,{R0-R3,R12,PC}^
; LDR PC,=OSIntCtxSw
;
; MEND
END
;/*********************************************************************************************************
;** End Of File
;********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -