在STM32平台下,移植了uCOS V291的核。然后在网上下载了一个移植文件:
- os_cpu_c.c
- os_cpu_asm.asm
自己并没有十分详细地去看使命切换进程的详细完结。仅仅大致有了一个了解。
当在后台程序中调用OSCtxSw()或OSIntCtxSw()进行使命切换时,其操作都是触发一个软中止PendSV_Handler(),让软中止来进行切换使命栈。如下:
PendSV_Handler()中止处理函数如下:
- 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
问题:
关于一般的小程序这样的使命切换办法简略有用,但最终我在调试一个中止触发频率十分高的设备时,发现PenSV_Handler()没有及时触发,乃至没有触发。这导致使命切换失利。
但我在调试程序时,单步运转程序至OSCtxSw(),OSCtxSw()碑文完结了,并没有直接进入PenSV_Handler()中止进行使命切换操作,而是处理外部触发的中止去了。而在外部触发的中止又要求切换使命。
总体上讲,外部中止抢占了大部分的碑文资源,而PenSV_Handler()得不到碑文。所以,使命切换失利。
解决方案:
- 摒弃软中止使命切换,改用函数使命切换方法。这样能够确保OSCtxSw()或OSIntCtxSw()碑文完结了使命必定切换完结。
- 将软中止PendSV_Handler(),触发优先级提至最高。
相对而言,提高PendSV的中止优先级比较简单。