搜索
bottom↓
回复: 12

ucos中断调度,一直困惑着我,忍不住要问问大侠们了

[复制链接]

出0入0汤圆

发表于 2011-11-3 15:17:24 | 显示全部楼层 |阅读模式
在UCOS中,中断处理时,退出中断都要调用一下OSIntExit();
void  OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr = 0;
#endif

   if(OSRunning==OS_TRUE)
   {
        OS_ENTER_CRITICAL();  //保存全局中断标志,关中断

        if(OSIntNesting>0)          /* Prevent OSIntNesting from wrapping       */
         {                           
            OSIntNesting--;
         }

        if(OSIntNesting==0)   /* Reschedule only if all ISRs complete ... */
        {                          
            if(OSLockNesting==0)           /* ... and not locked.                      */
         {                     
                 OS_SchedNew();

                 if(OSPrioHighRdy!=OSPrioCur)  /* No Ctx Sw if current task is highest rdy */
              {         
                      OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
                      #if OS_TASK_PROFILE_EN > 0
                        OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task  */
                      #endif
                      OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */
                      OSIntCtxSw();                          /* Perform interrupt level ctx switch       */
                 }
            }
        }

        OS_EXIT_CRITICAL();         //恢复之前的中断标志
   }
}
如果当前优先级是最高优先级,那任务就不做切换。如果当前任务不是最高优先级,那任务要做一次切换是吧.
我不明白的是,
比如,A任务在执行,这时中断来了。如果中断把B任务就绪,B任务优先级大于A任务。这时是不是要切换到B任务去运行?那中断服务程序还没有退出,
要是B任务运行的时候,又做了切换,C任务就绪,C任务又是最高优先级,那不是又要C运行了,那中断函数不是没有运行完,释放掉吗?
还有一点这个进入时关了中断 OS_ENTER_CRITICAL();  //保存全局中断标志,关中断
OS_EXIT_CRITICAL();         //恢复之前的中断标志
这个开中断的函数,到底什么时候才运行?中断不是一直关着了?是等所有比A高的任务运行完了后,再开?没道理啊
希望大家指点下

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-11-3 16:05:49 | 显示全部楼层
比如,A任务在执行,这时中断来了。如果中断把B任务就绪,B任务优先级大于A任务。这时是不是要切换到B任务去运行?那中断服务程序还没有退出,
要是B任务运行的时候,又做了切换,C任务就绪,C任务又是最高优先级,那不是又要C运行了,那中断函数不是没有运行完,释放掉吗?
-------------------------------------------------------------------------------------------------------------------------
“如果中断把B任务就绪”这个不对,任务就绪是在OSIntExit里面实现的,用户中断处理函数里只是申请要执行B任务。
“这时是不是要切换到B任务去运行。。。。。。”,这后面都不对了。是OSIntExit.OSIntCtxSw执行了之后,把中断入栈保存的A任务的信息另存一份备份,把B任务的信息填到栈里面,然后一退出中断时候,会出栈恢复中断前的现场,这个时候才是运行了B任务。
----------------------------------------------------------------------------------------------------------------
B-》C任务同理,如果最后C任务也执行完了,最坏的情况是A一直等到系统的定时器中断发生了,在定时器中断退出的时候,还会调用OSIntExit这个函数,然后发现还备份了个倒霉的A任务,这时候假设没有高于A优先级的任务存在,就把A给就绪了,然OSIntExit.OSIntCtxSw切换,然后退出中断,然后出栈A的信息,然后A任务就运行了。

出0入0汤圆

发表于 2011-11-3 16:08:02 | 显示全部楼层
建议楼主反复看看书,理解下任务,调度,切换,中断,入栈,出栈,时基,慢慢就明白为什么要有OSIntExit,为什么会OS_ENTER_CRITICAL。。。。。。。。。。。。。

出0入0汤圆

发表于 2011-11-3 17:11:08 | 显示全部楼层
楼主还是不太明白系统的任务切换原理,你说的那种情况,没有发生中断嵌套的情况。贴个书本上的图给你看看!


(原文件名:未命名.jpg)

出0入0汤圆

 楼主| 发表于 2011-11-3 19:00:44 | 显示全部楼层
回复【2楼】yinqiu009
建议楼主反复看看书,理解下任务,调度,切换,中断,入栈,出栈,时基,慢慢就明白为什么要有osintexit,为什么会os_enter_critical。。。。。。。。。。。。。
-----------------------------------------------------------------------

多谢大侠指导!!!

“如果中断把B任务就绪”这个不对,任务就绪是在OSIntExit里面实现的,用户中断处理函数里只是申请要执行B任务。
-----------------------------------------------------------------------------------------------------------
中断函数的OSIntExit是使就绪任务转变为运行态任务。(这过程是叫申请要执行B任务?)只要一退出中断就运行B任务了。


“这时是不是要切换到B任务去运行。。。。。。”,这后面都不对了。是OSIntExit.OSIntCtxSw执行了之后,把中断入栈保存的A任务的信息另存一份备份,把B任务的信息填到栈里面,然后一退出中断时候,会出栈恢复中断前的现场,这个时候才是运行了B任务。
-----------------------------------------------------------------------------------------------------------
A任务的信息另存一份?是保存在哪呢?是存到A的任务控制块吗?
OSIntCtxSw
LDR     R0, =NVIC_INT_CTRL                              
LDR     R1, =NVIC_PENDSVSET
STR     R1, [R0]
BX      LR
这个函数是保存A任务的信息,然后把B任务的信息填到栈里面吗?

出0入0汤圆

发表于 2011-11-3 23:35:50 | 显示全部楼层
A任务在执行,这时中断来了。如果中断把B任务就绪,B任务优先级大于A任务。这时是不是要切换到B任务去运行?那中断服务程序还没有退出,
要是B任务运行的时候,又做了切换,C任务就绪,C任务又是最高优先级,那不是又要C运行了,那中断函数不是没有运行完,释放掉吗?
-----------------------------------------------------------------------------------------------------------
可剥夺型的最高优先级的任务一旦就绪,总能得到CPU的控制权。

出0入0汤圆

 楼主| 发表于 2011-11-4 09:27:40 | 显示全部楼层
回复【2楼】yinqiu009
-----------------------------------------------------------------------

回复【2楼】yinqiu009
建议楼主反复看看书,理解下任务,调度,切换,中断,入栈,出栈,时基,慢慢就明白为什么要有osintexit,为什么会os_enter_critical。。。。。。。。。。。。。
-----------------------------------------------------------------------

多谢指导!我会再好好看书!

出0入0汤圆

发表于 2011-11-5 16:30:25 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-11-5 16:36:51 | 显示全部楼层
楼主这个程序是有毛病的,应该把
OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
这句提到这句之前:
if(OSPrioHighRdy!=OSPrioCur)  /* No Ctx Sw if current task is highest rdy */

在2.88以及以后版本的ReleaseNotes里面都有提到过,涉及OSIntExit()和OS_Sched()两个函数。

出0入0汤圆

发表于 2011-11-15 11:00:36 | 显示全部楼层
UCOS的任务切换,实际上也是个中断吧。
OS_ENTER_CRITICAL();这句关了中断,任务不是应该没法立即切换的么...
OS_EXIT_CRITICAL();之后才可以进行切换啦

出0入0汤圆

发表于 2011-11-25 22:00:37 | 显示全部楼层
深奥啊!!

出0入0汤圆

发表于 2015-6-29 19:25:39 | 显示全部楼层
弄了一天,原来是这样啊,

出0入0汤圆

发表于 2015-6-29 19:28:26 | 显示全部楼层
i55x 发表于 2011-11-5 16:36
楼主这个程序是有毛病的,应该把
OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
这句提到这句之前:

很好的提示啊,在旧的版本上始终找不到问题,郁闷了整整一天,谢谢了.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 14:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表