找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4114|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

UCOS移植代碼之LAMMY分析--OS_CPU_a.s

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:72519 發(fā)表于 2015-1-23 20:46 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
OS_CPU_a.s:
;定義系統(tǒng)模式堆棧的大小
SVC_STACK_LEGTH EQU 32

NoInt EQU 0x80

USR32Mode EQU 0x10
SVC32Mode EQU 0x13
SYS32Mode EQU 0x1f
IRQ32Mode EQU 0x12
FIQ32Mode EQU 0x11

;T_bit用于檢測(cè)進(jìn)入異常前cpu是否處于THUMB狀態(tài)
T_bit EQU 0x20

CODE32

AREA |subr|, CODE, READONLY

IMPORT OSTCBCur ;指向當(dāng)前任務(wù)TCB的指針
IMPORT OSTCBHighRdy ;指向?qū)⒁\(yùn)行的任務(wù)TCB的指針
IMPORT OSPrioCur ;當(dāng)前任務(wù)的優(yōu)先級(jí)
IMPORT OSPrioHighRdy ;將要運(yùn)行的任務(wù)的優(yōu)先級(jí)
IMPORT OSTaskSwHook ;任務(wù)切換的鉤子函數(shù)
IMPORT OSRunning ;uC/OS-II運(yùn)行標(biāo)志

IMPORT OsEnterSum ;關(guān)中斷計(jì)數(shù)器(關(guān)中斷信號(hào)量)
IMPORT SWI_Exception ;軟中斷異常處理程序

EXPORT __OSStartHighRdy
EXPORT OSIntCtxSw ;中斷退出時(shí)的入口,參見(jiàn)startup.s中的IRQ_Handler
EXPORT SoftwareInterrupt ;軟中斷入口

;軟件中斷
//當(dāng)CPU發(fā)現(xiàn)有軟中斷信號(hào)出現(xiàn)時(shí),CPU的PC馬上指到軟中斷服務(wù)地址處【見(jiàn)Startup.s】,然后通過(guò)跳轉(zhuǎn)到下面這段軟中斷處理程序,進(jìn)入后,首先要設(shè)置好管理模式下的堆棧,保存好用戶任務(wù)的幾個(gè)寄存器,其它寄存器系統(tǒng)會(huì)自動(dòng)保存,然后取出SWI號(hào)。
SoftwareInterrupt
LDR SP, StackSvc ; 重新設(shè)置堆棧指針
STMFD SP!, {R0-R3, R12, LR} //為什么只保存這幾個(gè)寄存器,見(jiàn)上面的解釋
MOV R1, SP ; R1指向參數(shù)存儲(chǔ)位置

MRS R3, SPSR //保存管理模式的狀態(tài)寄存器
TST R3, #T_bit ; 中斷前是否是Thumb狀態(tài)
LDRNEH R0, [LR,#-2] ; 是: 取得Thumb狀態(tài)SWI號(hào)
BICNE R0, R0, #0xff00
LDREQ R0, [LR,#-4] ; 否: 取得arm狀態(tài)SWI號(hào)
BICEQ R0, R0, #0xFF000000
; r0 = SWI號(hào),R1指向參數(shù)存儲(chǔ)位置
CMP R0, #1
LDRLO PC, =OSIntCtxSw
LDREQ PC, =__OSStartHighRdy ; SWI 0x01為第一次任務(wù)切換

BL SWI_Exception

LDMFD SP!, {R0-R3, R12, PC}^

StackSvc DCD (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

OSIntCtxSw
;下面為保存任務(wù)環(huán)境
LDR R2, [SP, #20] ;獲取PC//其實(shí)他就是管理模式下的LR寄存器的值,也就是用戶任務(wù)的PC值,為什么是SP+20,因?yàn)樵摋J菨M棧遞減,保存了R0-R3, R12, LR,所以LR的值為[SP+#20]。
LDR R12, [SP, #16] ;獲取R12
MRS R0, CPSR //用通用寄存器R0保存該管理模式下的CPSR

MSR CPSR_c, #(NoInt | SYS32Mode)//切換到系統(tǒng)模式
MOV R1, LR //把用戶的LR保存在通用寄存器R1中
STMFD SP!, {R1-R2} ;保存LR,PC//把系統(tǒng)模式的LR,PC壓入用戶任務(wù)的棧中
STMFD SP!, {R4-R12} ;保存R4-R12//把系統(tǒng)模式的R4-R12壓入用戶棧中

MSR CPSR_c, R0 //重新回到管理模式
LDMFD SP!, {R4-R7} ;獲取R0-R3//實(shí)際上把用戶的R0~R3放到管理模式下的R4-R7
ADD SP, SP, #8 ;出棧R12,PC//這兩個(gè)已經(jīng)保存了,所以SP要往上8個(gè)字節(jié)

MSR CPSR_c, #(NoInt | SYS32Mode//系統(tǒng)模式
STMFD SP!, {R4-R7} ;保存R0-R3//因?yàn)楣芾砟J降腞4-R11和系統(tǒng)模式的R4-R11是一樣的,保它保存在用戶任務(wù)的棧中
//接下來(lái)的我就不分析拉,因?yàn)槟闳绻凑瘴疑厦娴姆治,?yīng)該不成問(wèn)題的,如果還未明白,請(qǐng)多看幾遍,如果有問(wèn)題,請(qǐng)留言我們一起來(lái)探討,謝謝合作!上面的分析除了紅色部分是周立功公司的注釋外,其余都是我的理解,如果有錯(cuò)的,真心希望您能指出!謝謝!
LDR R1, =OsEnterSum ;獲取OsEnterSum
LDR R2, [R1]
STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum

;保存當(dāng)前任務(wù)堆棧指針到當(dāng)前任務(wù)的TCB
LDR R1, =OSTCBCur
LDR R1, [R1]
STR SP, [R1]

BL OSTaskSwHook ;調(diào)用鉤子函數(shù)
;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
;獲取新任務(wù)堆棧指針
LDR R4, [R6]
ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;進(jìn)入管理模式
MOV SP, R4 ;設(shè)置堆棧指針

LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum
;恢復(fù)新任務(wù)的OsEnterSum
LDR R3, =OsEnterSum
STR R4, [R3]

MSR SPSR_cxsf, R5 ;恢復(fù)CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;運(yùn)行新任務(wù)


__OSStartHighRdy
MSR CPSR_c, #(NoInt | SYS32Mode)
;告訴uC/OS-II自身已經(jīng)運(yùn)行
LDR R4, =OSRunning
MOV R5, #1
STRB R5, [R4]

BL OSTaskSwHook ;調(diào)用鉤子函數(shù)

LDR R6, =OSTCBHighRdy
LDR R6, [R6]
B OSIntCtxSw_1

AREA SWIStacks, DATA, NOINIT,ALIGN=2
SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;管理模式堆棧空間

END


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:68804 發(fā)表于 2015-2-9 15:05 | 只看該作者
學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表