一步一步教你使用uCOS-II( 三 )


3:恢复延时的任务()
延时的任务可以不等待延时的期满,而是通过其他任务取消延时而使自己处于就绪态,可以通过该函数来实现,实际上,()也可以唤醒正在等待的事件 。
4:系统时间()和()
内存管理
在ANSI C中是使用和free两个函数来动态分配和释放内存 。例如在Linux系统中就是这样 。但在嵌入式实时系统中,多次这样的操作会导致内存碎片,因为嵌入式系统尤其是uCOS是实地址模式,这种模式在分配任务堆栈时需要整块连续的空间,否则任务无法正确运行 。且由于内存管理算法的原因,和free的执行时间也是不确定 。这点是实时内核最大的矛盾 。
基于以上的原因uC/OS-II中把连续的大块内存按分区管理 。每个分区中包含整数个大小相同的内存块,但不同分区之间的内存快大小可以不同 。用户需要动态分配内存时,系统选择一个适当的分区,按块来分配内存 。释放内存时将该块放回它以前所属的分区,这样能有效解决碎片问题,同时执行时间也是固定的 。
同时uCOS-II根据以上的处理封装了适合于自己的动态内存分配函数()和(),但是使用这两个函数动态分配内存前需要先创建内存空间,也就是第二段咱们介绍的内存分块 。呵呵,不罗嗦了,具体的关于内存管理的函数如下:
内存控制块的数据结构
{void *;指向内存分区起始地址的指针 。
Void *;指向下一个空余内存控制块或者下一个空余内存块的指针,
;内存分区中内存块的大小,是建立内存分区时定义的 。
;内存分区中总的内存块数量,也是建立该内存分区时定义的 。
;内存分区块中当前获得的空余块数量 。
};
1;建立一个内存分区,()
2:分配一个内存块,()
应用程序通过调用该函数,从已经建立的内存分区中申请一个内存块 。该函数唯一的参数是指向特定内存分区的指针 。
3:释放一个内存块,()
当应用程序不再使用一个内存块时,必须及时的把它释放,并放回到相应的内存分区中,这个操作就是通过调用该函数实现的 。
4:查询一个内存分区的状态,() 。
任务间通信与同步
对一个多任务的操作系统来说,任务间的通信和同步是必不可少的 。uC/OS-II中提供了4种同步对象,分别是信号量,邮箱,消息队列和事件 。所有这些同步对象都有创建,等待,发送,查询的接口用于实现进程间的通信和同步 。
对于这4种同步对象将在后面一一讨论 。
任务调度
uC/OS-II 采用的是可剥夺型实时多任务内核 。可剥夺型的实时内核在任何时候都运行就绪了的最高优先级的任务 。
uC/os-II的任务调度是完全基于任务优先级的抢占式调度,也就是最高优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源 。为了简化系统设计,uC/OS-II规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身 。
UCOS的任务调度在一下情况下发生:
1) 高优先级的任务因为需要某种临界资源,主动请求挂起,让出处理器,此时将调度就绪状态的低优先级任务获得执行,这种调度也称为任务级的上下文切换 。
2) 高优先级的任务因为时钟节拍到来,在时钟中断的处理程序中,内核发现高优先级任务获得了执行条件(如休眠的时钟到时),则在中断态直接切换到高优先级任务执行 。这种调度也称为中断级的上下文切换 。
这两种调度方式在uC/OS-II的执行过程中非常普遍,一般来说前者发生在系统服务中,后者发生在时钟中断的服务程序中 。