📄 os_cpu_a.s
字号:
;/****************************************Copyright (c)**************************************************
;** 中南民族大学
;** 电子信息工程学院
;** 2005级电子信息工程
;** yangbin6b210@yahoo.com.cn
;**
;**
;**----------------------------------------文件信息------------------------------------------------------
;**文 件 名: os_cpu_s.s
;**创 建 人: 杨斌
;**最后修改日期: 2007年12月12日
;**描 述: μCOS-II在S3C44B0X上的移植代码汇编代码部分,用ADS1.2编译
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
NoInt EQU 0x80
SVC32Mode EQU 0x13
IRQ32Mode EQU 0x12
FIQ32Mode EQU 0x11
SYS32Mode EQU 0X1F
CODE32
AREA |subr|, CODE, READONLY
IMPORT OSIntNesting
IMPORT OSTCBCur
IMPORT IsrIRQ
IMPORT OSIntExit
IMPORT OSTaskSwHook
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT IRQStack
IMPORT OSRunning
EXPORT OSIRQISR
EXPORT OSIntCtxSw
EXPORT OS_TASK_SW
EXPORT OSStartHighRdy
EXPORT OS_ENTER_CRITICAL
EXPORT OS_EXIT_CRITICAL
;/*********************************************************************************************************
;** 函数名称: OSIRQISR
;** 功能描述: 中断进入和退出时的接口
;** 输 入: 无
;**
;**
;** 输 出 : 无
;** 全局变量: OSIntNesting、OSTCBCur、IRQStack
;** 调用模块: 无
;**
;** 作 者: 杨斌
;** 日 期: 2007年12月12日
;**-------------------------------------------------------------------------------------------------------
; 系统模式堆栈 IRQ模式堆栈
; |PC | |LR |=断点处的将要执行的PC值
; |LR | |R3 |
; |R12 | |R2 |
; |R11 | |R1 |
; |R10 | |R0 |
; |R9 | |LR |=系统模式的LR
; |R8 | |SP |=系统模式的SP
; |R7 | SP→|SPSR|=断点处的CPSR
; |R6 |
; |R5 |
; |R4 |
; |R3 |
; |R2 |
; |R1 |
; |R0 |
; |CPSR|←SP
;/********************************************************************************************************/
OSIRQISR
SUB LR,LR,#4 ;调整返回地址
STMFD SP!,{R0-R3,LR}
MRS R3,SPSR
STMFD SP,{R3,SP,LR}^ ; 系统模式SP→|R0 |
SUB SP,SP,#4*3 ; 系统模式SP→|SPSR|
LDR R0,=OSIntNesting
LDRB R1,[R0]
ADD R1,R1,#1
STRB R1,[R0] ;OSIntNesting加1
MOV R2,LR
MSR CPSR_c, #(NoInt | SYS32Mode)
CMP R1,#1
BNE OSIRQ_NEXT ;若OSIntNesting为1,则保存当前任务的寄存器到当前任务的堆栈中
STMFD SP!,{R2} ;保存当前任务的PC, 系统模式SP→|PC |
STMFD SP!,{LR} ;保存当前任务的LR, 系统模式SP→|LR |
STMFD SP!,{R4-R12} ;保存当前任务的R4-R12, 系统模式SP→|R4 |
STR R3,[SP,#-5*4] ;保存当前任务的CPSR
MSR CPSR_c, #(NoInt | IRQ32Mode) ;进入IRQ模式
ADD SP,SP,#4*3 ; IRQ模式SP→ |R0 |
LDMFD SP,{R0-R3} ;取出R0-R3
SUB SP,SP,#4*3 ; IRQ模式SP→ |SPSR|
MSR CPSR_c, #(NoInt | SYS32Mode) ;进入系统模式
STMFD SP!,{R0-R3} ;保存R0-R3, 系统模式SP→|R0 |
SUB SP,SP,#4 ;调整SP, 系统模式SP→|CPSR|
LDR R0,=OSTCBCur
LDR R0,[R0]
STR SP,[R0] ;OSTCBCur->OSTCBStkPtr=SP
OSIRQ_NEXT
BL IsrIRQ ;调用IRQ中断服务函数,在此中断服务函数中必须清除中断挂起位
BL OSIntExit ;调用推出系统中断函数,在此函数中OSIntNesting减1,也有可能会切换到其他任务中
MSR CPSR_c, #(NoInt | IRQ32Mode) ;进入IRQ模式。
LDR R0,=OSIntNesting
LDRB R0,[R0]
CMP R0,#0 ;若OSIntNesting=0则表明这是第一层中断
BEQ OSIRQ_LEAVE
LDMFD SP,{R0,SP,LR}^ ;程序运行到此处,此时处在嵌套中断中
MSR SPSR_cxsf,R0 ;恢复系统模式的SP,LR,IRQ模式SPSR
ADD SP,SP,#4*3 ;调整IRQ模式SP, IRQ模式SP→ |R0 |
LDMFD SP!,{R0-R3,PC}^ ;恢复R0-R3,PC,CPSR, IRQ模式SP→ |X |←上一层中断的堆栈顶部
OSIRQ_LEAVE
LDR R0,=IRQStack ;程序运行到此处,表明这是第一层中断且不需要切换任务
LDR R0,[R0]
MOV SP,R0 ; IRQ模式SP→ |X |←中断模式堆栈栈底
SUB SP,SP,#8*4 ; IRQ模式SP→ |SPSR|
LDMFD SP,{R0,SP,LR}^ ;恢复系统模式的SP,LR, 系统模式SP→|X |←当前任务中断时的SP
MSR SPSR_cxsf,R0 ;恢复IRQ模式SPSR
ADD SP,SP,#4*3 ;调整IRQ模式SP, IRQ模式SP→ |R0 |
MSR CPSR_c, #(NoInt | SYS32Mode) ;切换到系统模式,
SUB SP,SP,#11*4 ;调整系统模式SP, 系统模式SP→|R4 |
LDMFD SP,{R4-R12} ;恢复R4-R12
ADD SP,SP,#11*4 ;调整系统模式SP, 系统模式SP→|X |←当前任务中断时的SP
MSR CPSR_c, #(NoInt | IRQ32Mode) ;切换到IRQ模式
LDMFD SP!,{R0-R3,PC}^ ;恢复R0-R3、CPSR并从中断返回到当前任务断点处
;/*********************************************************************************************************
;** 函数名称: OSIntCtxSw
;** 功能描述: 中断级任务切换
;** 输 入: IRQ模式堆栈结构(出栈次序):SPSR、SP(系统模式)、LR(系统模式)、R0-R3、LR
;** 当前任务(系统模式)堆栈结构:CPSR、R0-R12、LR、PC
;**
;** 输 出 : 无
;** 全局变量: OSTCBHighRdy、OSTCBCur、OSPrioCur、OSPrioHighRdy、IRQStack
;** 调用模块: OSTaskSwHook
;**
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OSIntCtxSw
BL OSTaskSwHook ;调用钩子函数OSTaskSwHook()
MSR CPSR_c, #(NoInt | IRQ32Mode)
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR R1, =OSTCBCur
STR R0, [R1] ;OSTCBCur=OSTCBHighRdy
LDR R0,=OSPrioCur
LDR R1,=OSPrioHighRdy
LDRB R1,[R1]
STRB R1,[R0] ;OSPrioCur=OSPrioHighRdy
LDR R0,=IRQStack
LDR R0,[R0]
SUB R0,R0,#4 ;
MOV SP,R0 ;IRQ模式堆栈保留一个字
MSR CPSR_c, #(NoInt | SYS32Mode) ;进入系统模式
LDR R2, =OSTCBHighRdy
LDR R2, [R2]
LDR R2, [R2] ;取得新任务堆栈指针OSTCBHighRdy->OSTCBStkPtr并存入R2中
LDR R1,[R2] ;取得新任务的CPSR存入R1中
LDR R3,[R2,#15*4] ;取得新任务的PC存入R3中
STR R3,[R0] ;把新任务的PC存入IRQ模式的堆栈中
MSR CPSR_c, #(NoInt | IRQ32Mode) ;进入IRQ模式
MSR SPSR_cxsf,R1 ;把新任务的CPSR保存到IRQ模式的SPSR中
MSR CPSR_c, #(NoInt | SYS32Mode) ;进入系统模式
ADD R2,R2,#4 ;调整新任务堆栈指针
MOV SP,R2 ; 系统模式SP→|R0 |
LDMFD SP!,{R0-R12,LR} ;恢复新任务的R0-R12,LR, 系统模式SP→|PC |
ADD SP,SP,#4 ;调整系统模式堆栈指针
MSR CPSR_c, #(NoInt | IRQ32Mode) ;进入IRQ模式
LDMFD SP!,{PC}^ ;恢复新任务的CPSR、PC和IRQ模式SP
;/*********************************************************************************************************
;** 函数名称: OS_TASK_SW
;** 功能描述: 在任务调度中切换任务
;** 输 入: 无
;**
;**
;** 输 出 : 无
;** 全局变量: OSTCBCur、OSTCBHighRdy、OSPrioCur、OSPrioHighRdy
;** 调用模块: OSTaskSwHook
;**
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OS_TASK_SW
STMFD SP!,{LR} ;保存当前任务的PC
STMFD SP!,{R0-R12,LR} ;依次保存R0-R12、LR
MRS R0,CPSR
STMFD SP!,{R0} ;保存CPSR
LDR R1,=OSTCBCur
LDR R1,[R1]
STR SP,[R1] ;OSTCBCur->OSTCBStkPtr = SP(在当前任务控制块中保存当前任务的堆栈指针)
BL OSTaskSwHook ;调用OSTaskSwHook()
LDR R3,=OSPrioCur
LDR R4,=OSPrioHighRdy
LDRB R4,[R4]
STRB R4,[R3] ;OSPrioCur=OSPrioHighRdy
__OSStartHighRdy
LDR R1,=OSTCBCur
LDR R2,=OSTCBHighRdy
LDR R2,[R2]
STR R2,[R1] ;OSTCBCur=OSTCBHighRdy
LDR SP,[R2] ;得到将要重新运行的任务的堆栈指针SP=OSTCBHighRdy->OSTCBStkPtr
LDMFD SP!,{R0} ;取出将要运行任务的CPSR存入R0中
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MSR SPSR_cxsf,R0 ;管理模式SPSR=将要运行任务的CPSR
LDR SP,[R2] ;管理模式SP=将要重新运行的任务的堆栈指针
ADD SP,SP,#15*4 ;调整SP
MSR CPSR_c, #(NoInt | SYS32Mode) ;进入系统模式
LDMFD SP!,{R0-R12,LR} ;恢复R0-R12、LR
ADD SP,SP,#4 ;恢复要重新运行的任务的堆栈指针SP
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
LDMFD SP,{PC}^ ;恢复任务的CPSR并开始运行任务
;/*********************************************************************************************************
;** 函数名称: OSStartHighRdy
;** 功能描述: uC/OS-II启动时调用此程序运行第一个任务
;** 输 入: 无
;**
;**
;** 输 出 : 无
;** 全局变量: OSRunning
;** 调用模块: OSTaskSwHook
;**
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OSStartHighRdy
MSR CPSR_c,#(NoInt | SYS32Mode )
LDR R1,=OSRunning
MOV R2,#1
STRB R2,[R1] ;OSRunning=1
BL OSTaskSwHook ;调用OSTaskSwHook()
B __OSStartHighRdy ;运行最高优先级任务
;/*********************************************************************************************************
;** 函数名称: OS_ENTER_CRITICAL
;** 功能描述: 关闭中断
;** 输 入: 无
;**
;**
;** 输 出 : 无
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OS_ENTER_CRITICAL
STMFD SP!,{R0}
MRS R0,CPSR
ORR R0,R0,#NoInt
MSR CPSR_cxsf,R0
LDMFD SP!,{R0}
MOV PC,LR
;/*********************************************************************************************************
;** 函数名称: OS_EXIT_CRITICAL
;** 功能描述: 打开中断
;** 输 入: 无
;**
;**
;** 输 出 : 无
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OS_EXIT_CRITICAL
STMFD SP!,{R0}
MRS R0,CPSR
BIC R0,R0,#NoInt
MSR CPSR_cxsf,R0
LDMFD SP!,{R0}
MOV PC,LR
END
;/*********************************************************************************************************
;** End Of File
;*********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -