色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          uCOS-II的移植步驟

          作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏

          (二)函數(shù) void OSStartHighRdy(void)

          OSStartHighRdy()由OSStart()調(diào)用,用來啟動(dòng)最高優(yōu)先級任務(wù),當(dāng)然任務(wù)必須在OSStart()前已被創(chuàng)建

          • PendSV中斷的優(yōu)先級應(yīng)該為最低優(yōu)先級,原因在<>的7.6節(jié)已有說明
          • .PSP設(shè)置為0,是告訴具體的任務(wù)切換程序(OS_CPU_PendSVHandler()),這是第一次任務(wù)切換。做過切換后PSP就不會(huì)為0了,后面會(huì)看到。
          • 往中斷控制及狀態(tài)寄存器ICSR(0xE000ED04)第28位寫1即可產(chǎn)生PendSV中斷。這個(gè)<>8.4.5 其它異常的配置寄存器有說明

          OSStartHighRdy ;設(shè)置PendSV中斷的優(yōu)先級
          LDR R0, =NVIC_SYSPRI14 ;Set the PendSV exception priority
          LDR R1, =NVIC_PENDSV_PRI
          STRB R1, [R0] ;*(uint8_t *)NVIC_SYSPRI14 = NVIC_PENDSV_PRI

          MOVS R0, #0 ;初始化進(jìn)程堆棧指針 Set the PSP to 0 for initial context switch call
          MSR PSP, R0 ;初始化PSP為0 初始化上下文切換調(diào)用

          LDR R0, =OSRunning ; OSRunning = TRUE
          MOVS R1, #1 ;設(shè)置OSRunning = TRUE
          STRB R1, [R0]

          LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
          LDR R1, =NVIC_PENDSVSET ;觸發(fā)PendSV中斷
          STR R1, [R0] ;*(uint32_t *)NVIC_INT_CTRL = NVIC_PENDSVSET

          CPSIE I ; Enable interrupts at processor level開啟中斷

          OSStartHang
          B OSStartHang ; Should never get here 死循環(huán) which(1);

          (三)用戶任務(wù)切換函數(shù)和中斷任務(wù)的切換函數(shù)。

          官方的移植代碼里面,這兩個(gè)函數(shù)的處理函數(shù)是一樣的,而關(guān)于這個(gè)問題的討論,網(wǎng)上也有很多,我查了下官方關(guān)于在Cortex-M3各個(gè)廠家處理器上的移植,都是一樣的,就連現(xiàn)在最新推出的M4系列(飛思卡爾 K60),他們也是這么做,所以我決定也這么干吧。

          這兩個(gè)函數(shù)就做了一件事,就是觸發(fā)PendSV中斷。如果沒有比PendSV優(yōu)先級高的中斷觸發(fā),那么用戶的切換任務(wù)和中斷的切換任務(wù)就會(huì)得到及時(shí)的執(zhí)行。

          OSIntCtxSw
          LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
          LDR R1, =NVIC_PENDSVSET
          STR R1, [R0]
          BX LR

          OSCtxSw
          LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
          LDR R1, =NVIC_PENDSVSET
          STR R1, [R0] ;*(uint32_t *)NVIC_INT_CTRL = NVIC_PENDSVSET
          BX LR

          (四)這個(gè)函數(shù)是真正實(shí)現(xiàn)任務(wù)切換的函數(shù),理解這個(gè)函數(shù)很重要。

          首先我們要明白一點(diǎn),那就是這個(gè)函數(shù)說白了就是一個(gè)中斷函數(shù),而它不同于一般的中斷函數(shù),在KEIL里面我們寫好C的程序之后,已經(jīng)將中斷的入棧和出棧的工作做好了,在這里我們要自己寫入棧和出棧的匯編指令,而且這里的關(guān)鍵就在,中斷函數(shù)出棧的時(shí)候恢復(fù)的堆棧指針是指向別的任務(wù)的,理解了這個(gè),下面的函數(shù)就很好的理解了。

          附上一幅任務(wù)出棧和入棧的圖

          // | .... |
          ;// |-----------------|
          ;// | .... |
          ;// |-----------------|
          ;// | .... |
          ;// |-----------------| |---- 任務(wù)切換時(shí)PSP
          ;// Low Memory | .... | |
          ;// |-----------------| | |---------------| |----------------|
          ;// ^ | R4 | <----|----|--OSTCBStkPtr |<-----| (OS_TCB *) |
          ;// ^ |-----------------| |---------------| |----------------|
          ;// ^ | R5 | | | OSTCBHighRdy
          ;// | |-----------------| |---------------|
          ;// | | R6 | | |
          ;// | |-----------------| |---------------|
          ;// | | R7 | | |
          ;// | |-----------------| |---------------|
          ;// | | R8 | Tasks
          ;// | |-----------------| OS_TCB
          ;// | | R9 |
          ;// | |-----------------|
          ;// | | R10 |
          ;// Stack |-----------------|
          ;// Growth | R11 |
          ;// = 1 |-----------------|
          ;// | | R0 = p_arg | <-------- 異常時(shí)的PSP (向上生長的滿棧)
          ;// | |-----------------|
          ;// | | R1 |
          ;// | |-----------------|
          ;// | | R2 |
          ;// | |-----------------|
          ;// | | R3 |
          ;// | |-----------------|
          ;// | | R12 |
          ;// | |-----------------|
          ;// | | LR |
          ;// | |-----------------|
          ;// | | PC = task |
          ;// | |-----------------|
          ;// | | xPSR |
          ;// High Memory |-----------------|

          這個(gè)里面有個(gè)PSP進(jìn)程堆棧指針,關(guān)于這個(gè)指針和主堆棧指針的區(qū)別需要好好的看看權(quán)威指南

          OS_CPU_PendSVHandler ;xPSR, PC, LR, R12, R0-R3已自動(dòng)保存
          CPSID I ;任務(wù)切換期間需要關(guān)中斷 Prevent interruption during context switch
          MRS R0, PSP ;R0 = PSP PSP is process stack pointer 線程堆棧指針
          CBZ R0, OS_CPU_PendSVHandler_nosave ;如果PSP==0跳轉(zhuǎn)到OS_CPU_PendSVHandler_nosave去執(zhí)行 在多任務(wù)的初始化時(shí)PSP被初始化為0 Skip register save the first time
          ;若果PSP如果是0,標(biāo)示任務(wù)沒有運(yùn)行過,那么不需要壓棧

          SUBS R0, R0, #0x20 ;R0 -= 0x20 保存R4-R11到任務(wù)堆棧 共32個(gè)字節(jié)

          STM R0, {R4-R11} ;壓棧R4-R11, 其他8個(gè)寄存器是在異常時(shí)自動(dòng)壓棧的
          LDR R1, =OSTCBCur ;獲取OSTCBCur->OSTCBStkPtr

          LDR R1, [R1] ;R1 = *R1 (R1 = OSTCBCur)
          STR R0, [R1] ;*R1 = R0 (*OSTCBCur = SP) R0 is SP of process being switched out
          ;將當(dāng)前任務(wù)的堆棧保存到自己的任務(wù)控制塊
          ;OSTCBCur->OSTCBStkPtr = PSP
          ;程序運(yùn)行此位置,已經(jīng)保存了當(dāng)前任務(wù)的context了

          ; At this point, entire context of process has been saved
          OS_CPU_PendSVHandler_nosave
          PUSH {R14} ; Save LR exc_return value 保存R14,因?yàn)楹竺嬉{(diào)用函數(shù)
          LDR R0, =OSTaskSwHook ; OSTaskSwHook(); R0 = &OSTaskSwHook
          BLX R0 ; 調(diào)用OSTaskSwHook()
          POP {R14} ; 恢復(fù)R14

          LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; R0 = &OSPrioCur
          LDR R1, =OSPrioHighRdy ; R1 = &OSPrioHighRdy
          LDRB R2, [R1] ; R2 = *R1 (R2 = OSPrioHighRdy)
          STRB R2, [R0] ; *R0 = R2 (OSPrioCur = OSPrioHighRdy)

          LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;;R0 = &OSTCBCur
          LDR R1, =OSTCBHighRdy ; R1 = &OSTCBHighRdy
          LDR R2, [R1] ; R2 = *R1 (R2 = OSTCBHighRdy)
          STR R2, [R0] ; *R0 = R2 (OSTCBCur = OSTCBHighRdy) 此時(shí) [R2] = 新任務(wù)的PSP

          LDR R0, [R2] ;R0 = *R2 (R0 = OSTCBHighRdy), 此時(shí)R0是新任務(wù)的SP R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
          LDM R0, {R4-R11} ; 從任務(wù)堆棧SP恢復(fù)R4-R11 Restore r4-11 from new process stack
          ADDS R0, R0, #0x20 ; 調(diào)整PSP R0 += 0x20
          MSR PSP, R0 ; Load PSP with new process SP PSP = R0, 用新任務(wù)的SP加載PSP
          ORR LR, LR, #0x04 ; Ensure exception return uses process stack 確保LR位2為1,返回后使用進(jìn)程堆棧PSP
          CPSIE I ;開中斷
          BX LR ; Exception return will restore remaining context 中斷返回

          END

          由于是第一次的學(xué)習(xí)關(guān)于操作系統(tǒng)的知識(shí),里面的理解估計(jì)有很多不對的地方。隨著自己的理解就會(huì)有所修正。


          上一頁 1 2 下一頁

          關(guān)鍵詞: uCOS-II移植步

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉