?? 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 + -