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高的任务运行完了后,再开?没道理啊
希望大家指点下 比如,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任务就运行了。 建议楼主反复看看书,理解下任务,调度,切换,中断,入栈,出栈,时基,慢慢就明白为什么要有OSIntExit,为什么会OS_ENTER_CRITICAL。。。。。。。。。。。。。 楼主还是不太明白系统的任务切换原理,你说的那种情况,没有发生中断嵌套的情况。贴个书本上的图给你看看!
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_691390ZE33Z7.jpg
(原文件名:未命名.jpg) 回复【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任务的信息填到栈里面吗? A任务在执行,这时中断来了。如果中断把B任务就绪,B任务优先级大于A任务。这时是不是要切换到B任务去运行?那中断服务程序还没有退出,
要是B任务运行的时候,又做了切换,C任务就绪,C任务又是最高优先级,那不是又要C运行了,那中断函数不是没有运行完,释放掉吗?
-----------------------------------------------------------------------------------------------------------
可剥夺型的最高优先级的任务一旦就绪,总能得到CPU的控制权。 回复【2楼】yinqiu009
-----------------------------------------------------------------------
回复【2楼】yinqiu009
建议楼主反复看看书,理解下任务,调度,切换,中断,入栈,出栈,时基,慢慢就明白为什么要有osintexit,为什么会os_enter_critical。。。。。。。。。。。。。
-----------------------------------------------------------------------
多谢指导!我会再好好看书! mark! 楼主这个程序是有毛病的,应该把
OSTCBHighRdy= OSTCBPrioTbl;
这句提到这句之前:
if(OSPrioHighRdy!=OSPrioCur)/* No Ctx Sw if current task is highest rdy */
在2.88以及以后版本的ReleaseNotes里面都有提到过,涉及OSIntExit()和OS_Sched()两个函数。 UCOS的任务切换,实际上也是个中断吧。
OS_ENTER_CRITICAL();这句关了中断,任务不是应该没法立即切换的么...
OS_EXIT_CRITICAL();之后才可以进行切换啦 深奥啊!! 弄了一天,原来是这样啊,{:victory:} i55x 发表于 2011-11-5 16:36
楼主这个程序是有毛病的,应该把
OSTCBHighRdy= OSTCBPrioTbl;
这句提到这句之前:
很好的提示啊,在旧的版本上始终找不到问题,郁闷了整整一天,谢谢了.
页:
[1]