qzx276514343 发表于 2011-11-3 15:17:24

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

在UCOS中,中断处理时,退出中断都要调用一下OSIntExit();
voidOSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3                              /* Allocate storage for CPU status register */
    OS_CPU_SRcpu_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;
                      #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高的任务运行完了后,再开?没道理啊
希望大家指点下

yinqiu009 发表于 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任务就运行了。

yinqiu009 发表于 2011-11-3 16:08:02

建议楼主反复看看书,理解下任务,调度,切换,中断,入栈,出栈,时基,慢慢就明白为什么要有OSIntExit,为什么会OS_ENTER_CRITICAL。。。。。。。。。。。。。

wuha 发表于 2011-11-3 17:11:08

楼主还是不太明白系统的任务切换原理,你说的那种情况,没有发生中断嵌套的情况。贴个书本上的图给你看看!

http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_691390ZE33Z7.jpg
(原文件名:未命名.jpg)

qzx276514343 发表于 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,
BX      LR
这个函数是保存A任务的信息,然后把B任务的信息填到栈里面吗?

youkou2012 发表于 2011-11-3 23:35:50

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

qzx276514343 发表于 2011-11-4 09:27:40

回复【2楼】yinqiu009
-----------------------------------------------------------------------

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

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

ailibuli 发表于 2011-11-5 16:30:25

mark!

i55x 发表于 2011-11-5 16:36:51

楼主这个程序是有毛病的,应该把
OSTCBHighRdy= OSTCBPrioTbl;
这句提到这句之前:
if(OSPrioHighRdy!=OSPrioCur)/* No Ctx Sw if current task is highest rdy */

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

javine 发表于 2011-11-15 11:00:36

UCOS的任务切换,实际上也是个中断吧。
OS_ENTER_CRITICAL();这句关了中断,任务不是应该没法立即切换的么...
OS_EXIT_CRITICAL();之后才可以进行切换啦

zgkfw520 发表于 2011-11-25 22:00:37

深奥啊!!

cos 发表于 2015-6-29 19:25:39

弄了一天,原来是这样啊,{:victory:}

cos 发表于 2015-6-29 19:28:26

i55x 发表于 2011-11-5 16:36
楼主这个程序是有毛病的,应该把
OSTCBHighRdy= OSTCBPrioTbl;
这句提到这句之前:


很好的提示啊,在旧的版本上始终找不到问题,郁闷了整整一天,谢谢了.
页: [1]
查看完整版本: ucos中断调度,一直困惑着我,忍不住要问问大侠们了