STM32中uCOS的任务切换讨论
时间:11-20
来源:互联网
点击:
在STM32平台下,移植了uCOS V291的核。然后在网上下载了一个移植文件:
- os_cpu_c.c
- os_cpu_asm.asm
本人并没有非常详细地去看任务切换过程的具体实现。只是大致有了一个了解。
当在后台程序中调用OSCtxSw()或OSIntCtxSw()进行任务切换时,其操作都是触发一个软中断PendSV_Handler(),让软中断来进行切换任务栈。如下:
- OSCtxSw
- LDRR0,=NVIC_INT_CTRL
- LDRR1,=NVIC_PENDSVSET
- STRR1,[R0]
- BXLR
- OSIntCtxSw
- LDRR0,=NVIC_INT_CTRL
- LDRR1,=NVIC_PENDSVSET
- STRR1,[R0]
- BXLR
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的中断优先级比较容易。
STM32uCOS任务切 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)