本文章介紹在stm32上也就是cortex m3核的基礎(chǔ)上ucosii是如何運(yùn)行起來(lái)的。 打卡啟動(dòng)代碼 xx_cl.s 首先stm32起來(lái)后首先進(jìn)入啟動(dòng)代碼, ; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP 啟動(dòng)代碼中,系統(tǒng)初始化完成,然后在 dummy exception中喚醒一些中斷,其中ucosii用到的系統(tǒng)滴答中斷和cpu任務(wù)掛起切換的中斷。按著箭頭往下走。 DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
OS_CPU_PendSVHandler\
PROC
EXPORT OS_CPU_PendSVHandler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
關(guān)于這兩個(gè)函數(shù)的位置,OS_CPU_PendSVHandler這個(gè)在os_cpu_a.asm里邊有實(shí)體定義
OS_CPU_PendSVHandler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] ; R0 is SP of process being switched out
; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
這個(gè)就是關(guān)中斷,壓入堆棧切換任務(wù),OSTCBCur就是當(dāng)前要切換任務(wù)的指針。 Sysytickhandler右鍵單擊即可進(jìn)入他的實(shí)體定義,我們定義在it.c里邊,當(dāng)然也有其他版本不在it.c里邊的。 void SysTick_Handler(void) { OSIntEnter(); OSTimeTick(); OSIntExit(); } 這個(gè)函數(shù)就是一個(gè)1s延時(shí)中斷,為ucosii提供時(shí)鐘心臟。 接下來(lái)看main函數(shù) int main(void) { INT8U ret = 0; BspInit(); OSInit(); //uCOS-II ret = OSTaskCreate( Start_Task, (void*)0, &Start_TaskStk[PRIO_START_TASK_STK_SIZE-1], PRIO_START_TASK); / if(ret != OS_ERR_NONE) { OSStart(); } Main里邊就一個(gè)外設(shè)初始化和ucosii初始化,OSStart(); 是正式開(kāi)始進(jìn)入任務(wù)調(diào)度了, void OSStart (void) { if (OSRunning == OS_FALSE) { OS_SchedNew(); /* Find highestpriority's task priority number */ OSPrioCur = OSPrioHighRdy; OSTCBHighRdy =OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready torun */ OSTCBCur = OSTCBHighRdy; OSStartHighRdy(); /* Execute targetspecific code to start task */ } } 開(kāi)始時(shí)是吧優(yōu)先級(jí)最高的賦給當(dāng)前的任務(wù)指針OSTCBCur ,然后進(jìn)入OSStartHighRdy();這個(gè)函數(shù),這個(gè)函數(shù)又在cpu_.a.asm里邊預(yù)定義。
OSStartHighRdy
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call
MSR PSP, R0
LDR R0, =OSRunning ; OSRunning = TRUE
MOVS R1, #1
STRB R1, [R0]
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
CPSIE I ; Enable interrupts at processor level
OSStartHang
B OSStartHang
程序能順利的跑到這里基本就ok了。
|