Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1190136
  • 博文数量: 221
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2139
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(221)

文章存档

2024年(6)

2023年(8)

2022年(2)

2021年(2)

2020年(29)

2019年(11)

2018年(23)

2017年(41)

2016年(76)

2015年(23)

我的朋友
最近访客

分类: 嵌入式

2015-07-21 22:04:16

原文地址:http://blog.csdn.net/hevake_lcj/article/details/6637185
在STM32平台下,移植了uCOS V291的核。然后在网上下载了一个移植文件:
  • os_cpu_c.c
  • os_cpu_asm.asm

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

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

  1. OSCtxSw  
  2.     LDR     R0, =NVIC_INT_CTRL        
  3.     LDR     R1, =NVIC_PENDSVSET  
  4.     STR     R1, [R0]  
  5.     BX      LR  
OSCtxSw LDR R0, =NVIC_INT_CTRL LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR
  1. OSIntCtxSw  
  2.     LDR     R0, =NVIC_INT_CTRL            
  3.     LDR     R1, =NVIC_PENDSVSET  
  4.     STR     R1, [R0]  
  5.     BX      LR  
OSIntCtxSw LDR R0, =NVIC_INT_CTRL LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR

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

  1. PendSV_Handler  
  2.     CPSID   I                                
  3.     MRS     R0, PSP                          
  4.     CBZ     R0, OS_CPU_PendSVHandler_nosave   
  5.     SUBS    R0, R0, #0x20                      
  6.     STM     R0, {R4-R11}  
  7.   
  8.     LDR     R1, =OSTCBCur                    ; OSTCBCur->OSTCBStkPtr = SP;  
  9.     LDR     R1, [R1]  
  10.     STR     R0, [R1]                         ; R0 is SP of process being switched out  
  11.   
  12.                                                
  13. OS_CPU_PendSVHandler_nosave  
  14.     PUSH    {R14}                            ; Save LR exc_return value  
  15.     LDR     R0, =OSTaskSwHook                ; OSTaskSwHook();  
  16.     BLX     R0  
  17.     POP     {R14}  
  18.   
  19.     LDR     R0, =OSPrioCur                   ; OSPrioCur = OSPrioHighRdy;  
  20.     LDR     R1, =OSPrioHighRdy  
  21.     LDRB    R2, [R1]  
  22.     STRB    R2, [R0]  
  23.   
  24.     LDR     R0, =OSTCBCur                    ; OSTCBCur  = OSTCBHighRdy;  
  25.     LDR     R1, =OSTCBHighRdy  
  26.     LDR     R2, [R1]  
  27.     STR     R2, [R0]  
  28.   
  29.     LDR     R0, [R2]       
  30.     LDM     R0, {R4-R11}                     ; Restore r4-11 from new process stack  
  31.     ADDS    R0, R0, #0x20  
  32.     MSR     PSP, R0                          ; Load PSP with new process SP  
  33.     ORR     LR, LR, #0x04                      
  34.     CPSIE   I  
  35.     BX      LR                     
  36.     END  

问题:

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

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

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

 

解决方案:

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。 

阅读(3531) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~