STM32中uCOS的任務(wù)切換討論
- os_cpu_c.c
- os_cpu_asm.asm
本人并沒有非常詳細(xì)地去看任務(wù)切換過程的具體實(shí)現(xiàn)。只是大致有了一個(gè)了解。
本文引用地址:http://www.ex-cimer.com/article/201611/318809.htm當(dāng)在后臺(tái)程序中調(diào)用OSCtxSw()或OSIntCtxSw()進(jìn)行任務(wù)切換時(shí),其操作都是觸發(fā)一個(gè)軟中斷PendSV_Handler(),讓軟中斷來進(jìn)行切換任務(wù)棧。如下:
- OSCtxSw
- LDRR0,=NVIC_INT_CTRL
- LDRR1,=NVIC_PENDSVSET
- STRR1,[R0]
- BXLR
- OSIntCtxSw
- LDRR0,=NVIC_INT_CTRL
- LDRR1,=NVIC_PENDSVSET
- STRR1,[R0]
- BXLR
PendSV_Handler()中斷處理函數(shù)如下:
- PendSV_Handler
- CPSIDI
- MRSR0,PSP
- CBZR0,OS_CPU_PendSVHandler_nosave
- SUBSR0,R0,#0x20
- STMR0,{R4-R11}
- LDRR1,=OSTCBCur;OSTCBCur->OSTCBStkPtr=SP;
- LDRR1,[R1]
- STRR0,[R1];R0isSPofprocessbeingswitchedout
- OS_CPU_PendSVHandler_nosave
- PUSH{R14};SaveLRexc_returnvalue
- LDRR0,=OSTaskSwHook;OSTaskSwHook();
- BLXR0
- POP{R14}
- LDRR0,=OSPrioCur;OSPrioCur=OSPrioHighRdy;
- LDRR1,=OSPrioHighRdy
- LDRBR2,[R1]
- STRBR2,[R0]
- LDRR0,=OSTCBCur;OSTCBCur=OSTCBHighRdy;
- LDRR1,=OSTCBHighRdy
- LDRR2,[R1]
- STRR2,[R0]
- LDRR0,[R2]
- LDMR0,{R4-R11};Restorer4-11fromnewprocessstack
- ADDSR0,R0,#0x20
- MSRPSP,R0;LoadPSPwithnewprocessSP
- ORRLR,LR,#0x04
- CPSIEI
- BXLR
- END
問題:
對(duì)于一般的小程序這樣的任務(wù)切換方法簡單有效,但最后我在調(diào)試一個(gè)中斷觸發(fā)頻率非常高的設(shè)備時(shí),發(fā)現(xiàn)PenSV_Handler()沒有及時(shí)觸發(fā),甚至沒有觸發(fā)。這導(dǎo)致任務(wù)切換失敗。
但我在調(diào)試程序時(shí),單步運(yùn)行程序至OSCtxSw(),OSCtxSw()執(zhí)行完成了,并沒有直接進(jìn)入PenSV_Handler()中斷進(jìn)行任務(wù)切換操作,而是處理外部觸發(fā)的中斷去了。而在外部觸發(fā)的中斷又要求切換任務(wù)。
總體上講,外部中斷搶占了大部分的執(zhí)行資源,而PenSV_Handler()得不到執(zhí)行。所以,任務(wù)切換失敗。
解決方案:
- 摒棄軟中斷任務(wù)切換,改用函數(shù)任務(wù)切換方式。這樣可以保證OSCtxSw()或OSIntCtxSw()執(zhí)行完成了任務(wù)一定切換完成。
- 將軟中斷PendSV_Handler(),觸發(fā)優(yōu)先級(jí)提至最高。
相對(duì)而言,提升PendSV的中斷優(yōu)先級(jí)比較容易。
評(píng)論