×
嵌入式 > 嵌入式开发 > 详情

STM32中uCOS的任务切换讨论

发布时间:2020-09-01 发布时间:
|
STM32平台下,移植了uCOS V291的核。然后在网上下载了一个移植文件:
  • os_cpu_c.c
  • os_cpu_asm.asm

本人并没有非常详细地去看任务切换过程的具体实现。只是大致有了一个了解。

当在后台程序中调用OSCtxSw()或OSIntCtxSw()进行任务切换时,其操作都是触发一个软中断PendSV_Handler(),让软中断来进行切换任务栈。如下:

  1. OSCtxSw
  2. LDRR0,=NVIC_INT_CTRL
  3. LDRR1,=NVIC_PENDSVSET
  4. STRR1,[R0]
  5. BXLR
  1. OSIntCtxSw
  2. LDRR0,=NVIC_INT_CTRL
  3. LDRR1,=NVIC_PENDSVSET
  4. STRR1,[R0]
  5. BXLR

PendSV_Handler()中断处理函数如下:

  1. PendSV_Handler
  2. CPSIDI
  3. MRSR0,PSP
  4. CBZR0,OS_CPU_PendSVHandler_nosave
  5. SUBSR0,R0,#0x20
  6. STMR0,{R4-R11}
  7. LDRR1,=OSTCBCur;OSTCBCur->OSTCBStkPtr=SP;
  8. LDRR1,[R1]
  9. STRR0,[R1];R0isSPofprocessbeingswitchedout
  10. OS_CPU_PendSVHandler_nosave
  11. PUSH{R14};SaveLRexc_returnvalue
  12. LDRR0,=OSTaskSwHook;OSTaskSwHook();
  13. BLXR0
  14. POP{R14}
  15. LDRR0,=OSPrioCur;OSPrioCur=OSPrioHighRdy;
  16. LDRR1,=OSPrioHighRdy
  17. LDRBR2,[R1]
  18. STRBR2,[R0]
  19. LDRR0,=OSTCBCur;OSTCBCur=OSTCBHighRdy;
  20. LDRR1,=OSTCBHighRdy
  21. LDRR2,[R1]
  22. STRR2,[R0]
  23. LDRR0,[R2]
  24. LDMR0,{R4-R11};Restorer4-11fromnewprocessstack
  25. ADDSR0,R0,#0x20
  26. MSRPSP,R0;LoadPSPwithnewprocessSP
  27. ORRLR,LR,#0x04
  28. CPSIEI
  29. BXLR
  30. END

问题:

对于一般的小程序这样的任务切换方法简单有效,但最后我在调试一个中断触发频率非常高的设备时,发现PenSV_Handler()没有及时触发,甚至没有触发。这导致任务切换失败。

但我在调试程序时,单步运行程序至OSCtxSw(),OSCtxSw()执行完成了,并没有直接进入PenSV_Handler()中断进行任务切换操作,而是处理外部触发的中断去了。而在外部触发的中断又要求切换任务。

总体上讲,外部中断抢占了大部分的执行资源,而PenSV_Handler()得不到执行。所以,任务切换失败。

解决方案:

  1. 摒弃软中断任务切换,改用函数任务切换方式。这样可以保证OSCtxSw()或OSIntCtxSw()执行完成了任务一定切换完成。
  2. 将软中断PendSV_Handler(),触发优先级提至最高。

相对而言,提升PendSV的中断优先级比较容易。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
RIOS实验室联手Imagination.共同助力RISC-V生态发展