uC/OS-II的OS_TaskIdle()怎么引起调度?
uC/OS-II(Version 2.86) 中空闲任务(OS_TaskIdle())的代码如下voidOS_TaskIdle (void *p_arg){
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SRcpu_sr = 0;
#endif
(void)p_arg; /* Prevent compiler warning for not using 'p_arg' */
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtr++;
OS_EXIT_CRITICAL();
OSTaskIdleHook(); /* Call user definable HOOK */
}
}在某一时刻该任务获得CPU使用权之后,在该任务中也没有调用调度器,那么当别的高优先级任务就绪时,如何实现调度呢? 定时中断里面OSTimeTick()对所有TCB中非零OSTimedly减一,减后为零,则使该TCB对应的任务就绪(就续表相应位置1)。在OSIntExit()中查找最高优先级,调度。 高优先级的任务释放CPU运行权利,低优先级的任务可以得到执行。
低优先级任务运行的过程中,高优先级的任务是通过抢占获得CPU的运行权利。举个例子
比如一个高优先级任务是通过延迟函数挂起的,那么会在这里让高优先级的任务重新加入到就绪列表
voidOSTimeTick (void)
{
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {/* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No,Make ready */
OSRdyTbl |= ptcb->OSTCBBitX;
}
退出的时候再让高优先级的任务得到执行,如果这个任务是当前需要执行的最高优先级的任务的话。
OSIntExit();
} Eric_Xue 发表于 2013-9-13 08:46 static/image/common/back.gif
定时中断里面OSTimeTick()对所有TCB中非零OSTimedly减一,减后为零,则使该TCB对应的任务就绪(就续表相 ...
你看我这样理解行不行:uC/OS任务调度有两种途径:一、在任务中,当任务的某个行为(例如释放互斥信号)会导致ReadyList发生改变时,在该任务中启动调度器,去判断释放需要进行任务切换(通过与当前任务的优先级的大小关系判断);二、在滴答中断中,该ISR完成的功能为:每次中断发生,都会去对每个TCB中的TimeDly域进行减一,并且判断是否为0。如果为0,则改变ReadyList进而启动任务调度,最终完成任务切换的工作。
而我的问题的答案正是第二种。
理解出错之处,敬请指教! Eric2013 发表于 2013-9-13 09:00 static/image/common/back.gif
高优先级的任务释放CPU运行权利,低优先级的任务可以得到执行。
低优先级任务运行的过程中,高优先级的任务 ...
呵呵谢谢,看了兄台跟一楼的回答。貌似有点懂了,就是不知理解对不对。还烦请移步4楼,看下我的理解是否正确。出错之处、敬请指教! knight_lxf 发表于 2013-9-13 21:21 static/image/common/back.gif
你看我这样理解行不行:uC/OS任务调度有两种途径:一、在任务中,当任务的某个行为(例如释放互斥信号) ...
对的,前一种任务自身调用系统函数,执行任务级调度,
后一种是在中断中事件有效或延迟完成,进行中断级任务调度。
空闲程序不能调用系统函数,只能被中断打断执行其他就绪任务。 knight_lxf 发表于 2013-9-13 21:21 static/image/common/back.gif
你看我这样理解行不行:uC/OS任务调度有两种途径:一、在任务中,当任务的某个行为(例如释放互斥信号) ...
有一个前提你没有注意到,一个任务的死循环里面必须有ostimedly和/或pend函数释放对处理器的控制权,否则优先级比这个任务低的任务永远无法执行。
在这个条件下,ucosii任务调度有两个途径,第一就是在systick中断处理函数里面要对ostimedly一系的挂起任务进行就绪检查,一旦发现有任务就绪就按照优先级高低进行执行。第二个就是中断处理函数里面post消息,在OSIntExit函数里面进行任务调度,发现pend在这个消息的任务,就会执行这个任务。
你说的途径一的错误在于,释放互斥信号如果是ostimedly时间到,那么本质上属于我说的途径一,如果释放互斥信号是来源于中断事件,那么就是我说的途径二。没有第三种途径来源。 Eric_Xue 发表于 2013-9-13 22:03 static/image/common/back.gif
对的,前一种任务自身调用系统函数,执行任务级调度,
后一种是在中断中事件有效或延迟完成,进行中断级 ...
嗯 谢谢 看过你的回复 有RTFS一遍 明白了 呵呵。谢谢! 楼主你学的不慢啊,论坛的i55x前辈都给你回复了。{:lol:} Eric2013 发表于 2013-9-14 00:04 static/image/common/back.gif
楼主你学的不慢啊,论坛的i55x前辈都给你回复了。
呵呵谢谢! 也就是瞎看呗! 之前是跳过任务管理看事件管理对里面的全局变量像OSTCBCur、OSTCBPrioHighRdy等等虽然从字面大概知道什么意思但不是彻底清除。 又反过来看任务管理呵呵 走弯路咯!!! knight_lxf 发表于 2013-9-14 00:11 static/image/common/back.gif
呵呵谢谢! 也就是瞎看呗! 之前是跳过任务管理看事件管理对里面的全局变量像OSTCBCur、OSTCBPrioHig ...
你已经学的非常快了,比我学习那会强很多了。我那时候简直就是蜗牛爬。 i55x 发表于 2013-9-13 22:53 static/image/common/back.gif
有一个前提你没有注意到,一个任务的死循环里面必须有ostimedly和/或pend函数释放对处理器的控制权,否则 ...
前辈好!
小弟不才,对回复中“释放互斥信号如果是ostimedly时间到”这句话实在不解。举例如下:void TaskA(void *pdata)//prio = 4
{
INT8U err;
.
.
OSMutexPend(DispMutex,0,&err);
.
.
}
void TaskB(void *pdata) //prio = 5
{
INT8U err;
.
.
err = OSMutexPost(DispMutex)
.
.
}释放互斥信号跟OSTimeDly有什么关系呢?
还烦请前辈不要嫌弃这问题低端,谢谢! Eric2013 发表于 2013-9-14 00:13 static/image/common/back.gif
你已经学的非常快了,比我学习那会强很多了。我那时候简直就是蜗牛爬。 ...
哎,提起来都是泪啊!毕业两年有余才开始看嵌入式操作系统!实在惭愧! knight_lxf 发表于 2013-9-14 00:20 static/image/common/back.gif
前辈好!
小弟不才,对回复中“释放互斥信号如果是ostimedly时间到”这句话实在不解。举例如下:释 ...
你taskb里面没有ostimedly的话比他优先级低的任务永远无法执行 i55x 发表于 2013-9-14 00:25 static/image/common/back.gif
你taskb里面没有ostimedly的话比他优先级低的任务永远无法执行
刚试了试确实是死在一个任务中 没办法调度。那是因为互斥的PIP设置为3 比那两个都高。目前对我来说互斥的水还太深。换个。换成Sem,初值为0。基本相同的代码同样没有OSTimeDly这时候任务都能正常运行static void Task1(void *pdata) //prio = 4
{
INT8U err;
pdata = pdata;
while(1)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
//OSMutexPend(DispMutex,0,&err);
OSSemPend(DispMutex,0,&err);
if(err==OS_NO_ERR)
{
OS_ENTER_CRITICAL();
UsartPrintf("任务2已经发生,任务1已经同步\n");
OS_EXIT_CRITICAL();
}
}
}
static void Task2(void *pdata) //prio = 5
{
INT8U err;
pdata = pdata;
while(1)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
//err = OSMutexPost(DispMutex);
err = OSSemPost(DispMutex);
if(OS_NO_ERR==err)
{
OS_ENTER_CRITICAL();
UsartPrintf("任务2正在发生\n");
OS_EXIT_CRITICAL()
}
}
}这时候也没有TimeDly 任务却能交替执行 knight_lxf 发表于 2013-9-14 00:57 static/image/common/back.gif
刚试了试确实是死在一个任务中 没办法调度。那是因为互斥的PIP设置为3 比那两个都高。目前对我来说互斥 ...
你的代码能正确执行不等于你的代码有现实意义。task2优先级最低,task1当然能执行。但是你的代码里面task2耗尽了所有的cpu执行时间的宝贵资源,idle任务永远无法执行,cpu负载率100%,在一个真实可用的系统里面你的代码是严重错误的。
页:
[1]