ucosii
1、任务调度
1.调度
uCOS-II的任务由任务控制块管理,在任务每个循环的末尾通过调用OSTimeDly()或者OSTimeDlyHMSM()来将当前任务从任务就绪表移除,并将该任务控制块内OSTCBDly赋予新值,然后进行一次任务调度让出cpu控制权。
uCOS-II含有时钟节拍,时钟节拍在开中断的情况下定时触发时钟节拍中断,时钟节拍中断遍历任务控制块链表并将每个任务控制块内的OSTCBDly减1,若任务的OSTCBDly减1后为0则将该任务加入任务就绪表。在中断结束前,时钟节拍中断调用OSIntExit()函数,OSInitExit()找出当前任务就绪表内优先级最高的任务控制块,然后调用OSCtxSW()进行一次任务切换。
当任务内OSTimeDly指定延时时间到,也就是其对应任务控制块的OSTCBDly减为0,则该任务重新进入就绪状态,若此时其优先级最高,那么它获得CPU的控制权,重新运行。
2.挂起和恢复
任务的挂起就是将该任务从任务就绪表移除并将该任务的任务控制块状态位置为挂起状态。节拍中断不处理挂起状态的任务,其OSTCBDly不减1。只有得到恢复的挂起任务任务控制块内的OSTCBDly才能被节拍时钟正常处理。
任务的恢复就是将该任务的任务控制块挂起状态清除,若此时任务刚好就绪,则进行一次调度。
3.调度上锁和调度解锁
调度上锁就是将OSLockNesting自增1,调度的解锁是将OSLockNesting自减1,OSLockNesting表示任务上锁的次数,调度函数OSSched()只有在调度未上锁并且调用者非中断的情况下才进行任务调度。OSSched()不能在中断中调用。
2、中断
uCOS-II通过OSIntNesting表示中断的次数,进入中断时要通过调用OSintenter()来使OSIntNesting自增1,OSIntExit()来使OSIntNesting自减1。当OSIntNesting为0,也就是所有中断结束的末尾,OSIntExit()会获取任务就绪表内优先级最高的任务并通过OSIntCtxSw()进行一次任务调度(uCOS-II为可剥夺型内核,中断结束后进入任务就绪表内优先级最高的任务,不一定会返回原任务)。
3、任务间的通信与同步
1、信号量
消息的发送是将信号量的数目加1,将该任务从事件等待表移除并将该任务加入任务就绪表,并将任务控制块的OSTCBDly清零,然后进行一次任务调度。
消息的等待是当信号量数目大于0时,将信号量数目减1;若信号量等于0,则将该任务从任务就绪表中移除并添加到事件等待表内,然后将等待超时值赋给该任务控制块的OSTCBDly,然后进行一次任务调度让出CPU的控制权。该任务再次获得CPU控制权条件有以下两个,满足任意一个即可:
- 有其他任务发送消息,将信号量置为非零并将该任务状态标准清零,而且该任务为任务就绪表内优先级最高的任务;或者
- 任务等待超时,并且该任务为任务就绪表内优先级最高的任务。
若为条件1,则消息等待函数返回无错误,若为条件2,则消息等待函数返回等待超时错误。在等待时间内,若没有其他任务发送消息,则该任务一直处于等待状态,无法获取CPU的控制权。
2、消息邮箱
消息邮箱与信号量类似,只是消息邮箱检查的不是信号量的数目,而是消息是否为空。
3、消息队列
消息队列与消息邮箱类似,只是消息队列检测的不是单一消息是否为空,而是整个消息队列是否为空。
4、信号量集
信号量集的发送和等待不再是单一一个信号的有效,而是所有指定信号均为有效才将任务加入任务就绪表。
4、动态内存管理
uCOS-II的内存管理是一是为了减少内存碎片,二是为了使内存分配占用的时间是确定的。思想即为建立拥有不同内存块大小的内存分区。当程序运行时,需要多大的内存就从含有对应内存大小的内存分区获取所需的内存块。内存的分配和释放需要成对进行。
相关阅读
文章目录任务就绪表及任务调度任务的就绪表结构对任务就绪表的操作登记注销最高优先级就绪任务的查找任务的调度任务的创建OSTask
第一篇 UCOS介绍 第一篇 UCOS介绍这个大家都知道。呵呵。考虑到咱们学习的完整性还是在这里唠叨一下。让大家再熟悉一下。高手们