lskybs 发表于 2014-7-28 23:31:09

uC/OS-ii中OSTimeDly的问题

   在做uC/OS-ii移植的时候碰到一些问题:系统中开了3个任务,分别为A、B、C,优先级顺序为A > B > C,其中任务A为系统的启动任务,在任务A中建立任务B和任务C,然后将A休眠处理,问题如下:
(1)在任务B中使用OSTimeDly(1000)这样延时,Systick设置的为1ms进入Interrupt,在任务C中使用OSTimeDly(100)这样延时,请问任务B和任务C是如何处理延时任务的?我的猜想是任务C执行10次后执行1次任务B,不知道是不是这样的情况,假如我的猜想是正确的,那为什么会这样执行?
(2)在任务执行函数OSTimeDly的时候是不是会进行一次任务调度?同时进入到systick的ISR中执行OSIntExit()这个函数的时候是不是又会执行一次任务调度?
(3)B和C是否有同时为suspend的状态?假如有,那么执行OSTimeTick()中ptcb = ptcb->OSTCBNext;的时候是不是ptcb应该为空?因为没有任务处于就绪状态。
    不知道我的假设和猜想是否正确,请分析,谢谢!

kazenoai 发表于 2014-7-29 08:01:40

(1)在任务B中使用OSTimeDly(1000)这样延时,Systick设置的为1ms进入Interrupt,在任务C中使用OSTimeDly(100)这样延时,请问任务B和任务C是如何处理延时任务的?我的猜想是任务C执行10次后执行1次任务B,不知道是不是这样的情况,假如我的猜想是正确的,那为什么会这样执行?
       延时不是由任务去实现的,延时是由操作系统实现的,调用OSTimeDly这个函数只是告诉操作系统,我这个任务要停止运行多长时间,在系统的延时的链表中注册了一个时间,系统每隔1ms会去查询并且将计数减一,直到延时完成之后,再把任务放回就绪状态。
(2)在任务执行函数OSTimeDly的时候是不是会进行一次任务调度?同时进入到systick的ISR中执行OSIntExit()这个函数的时候是不是又会执行一次任务调度?
       会执行一次任务的调度,由于当前任务执行的OSTimeDly,所以需要去判断是否有优先级低于当前运行的任务正处于就绪状态,所以会执行一次调度,去执行处于就绪状态并且优先级最高的任务。OSIntExit这个一个退出中断的函数,并没有调度功能,起始在调用OSIntExit这个函数之前已经将堆栈进行了重新的处理,如果有任务优先级最高,并且处于就绪状态,那么调用OSIntExit之后会将相应任务的堆栈push出来,因此退出中断之后就会去执行相应的任务。
(3)B和C是否有同时为suspend的状态?假如有,那么执行OSTimeTick()中ptcb = ptcb->OSTCBNext;的时候是不是ptcb应该为空?因为没有任务处于就绪状态。
       如果C的任务执行的时间少于100ms的话,就会有同时挂起,如果C任务执行的时间真的大于100ms,或者大于1ms,那么这样的任务安排也是有问题的,一个任务的执行时间最好是小于系统的最小滴答时间。如果没有用户任务处于就绪状态的话,系统会去执行一个idle任务,这个是系统本身的任务,这个任务的优先级是最低的。

lskybs 发表于 2014-7-29 12:59:38

kazenoai 发表于 2014-7-29 08:01
(1)在任务B中使用OSTimeDly(1000)这样延时,Systick设置的为1ms进入Interrupt,在任务C中使用OSTimeDly(100 ...

学习了,非常感谢!

tigerman520 发表于 2014-8-1 10:38:48

本帖最后由 tigerman520 于 2014-8-1 10:43 编辑

OSIntExit() 有任务调度的功能呀。调度由于中断唤醒了的任务。这里就是调度由于OSTimeDly()延时到了的任务。

tigerman520 发表于 2014-8-1 10:41:12

建议楼主还是买本uc/osII的书看看吧。

lskybs 发表于 2014-8-1 13:11:28

tigerman520 发表于 2014-8-1 10:38
OSIntExit() 有任务调度的功能呀。调度由于中断唤醒了的任务。这里就是调度由于OSTimeDly()延时到了的任务 ...

    嗯,是的,OSIntExit()函数中执行任务切换是有前提的,并不是说调度由于中断唤醒了的任务,在调用OSIntExit()这个函数之前会执行OSTimeTick()函数,它将被systick中断了的任务push到就绪状态,然后在OSIntExit()中判断处于就绪状态任务的优先级,谁的最高就会执行中断级的任务切换,使其切换到运行状态。在OSTimeDly()函数中会挂起当前任务,做一次任务级的切换。我是这样理解的,从Debug来看也是这样执行的!所以并不是调度由于OSTimeDly()延时到了的任务,前提是延时到了,还要有高优先级才会跑到running state,如果只有2个任务那就不一样了。

tigerman520 发表于 2014-8-1 13:35:34

OSIntExit()并不是只在SYSTICK中断中调用,在用户中断中也要调用的(比如串口中断函数中),如果串口中断产生一个消息,唤醒(使一个任务达到就绪态)一个任务,那么调用OSIntExit(),就有可能切换任务的。
页: [1]
查看完整版本: uC/OS-ii中OSTimeDly的问题