UCOS-II的前身是UCOS,1992年由Jean J. Labrosse发表,1998年UCOS升级为UCOS-II,2009年更新为UCOS-III。本文论及的版本为UCOS-II 2.5.1,发表于2001年。UCOS、UCOS-II、UCOS-III开源但不免费,需要购买许可证才能用于商业目的。
在UCOS-II里,每一个任务(task)都有自己独有的优先权和独有的一个TCB结构。结构里面包含优先权(OSTCBPrio)、堆栈指针(OSTCBStkPtr)、事件指针(OSTCBEventPtr)等等信息。系统里所有的任务连成一个双向链。UCOS-II里最基本的任务间通讯机制是事件(event),其他的通讯机制,如信号(semaphore)、互斥(mutex)、旗标(flag)、信箱(mailbox)、队列(queue),都是基于事件而实现的。每一个事件都有自己的OS_Event结构,里面有事件种类(OSEventType)、等待事件的任务(OSEventTbl)等等信息。USCOS-II里用来进入和退出关键区域(critical section)的函数是OSEnterCritical和OSExitCritical。 在freeRTOS里每一个任务也有自己的tskTCB结构,里面包含优先权(uxPriority)、堆栈指针(pxTopOfStack)等。同一个优先权上可以有多个任务。任务被放置在pxReadyTasksLists、xDelayedTaskList或xPendingReadyList任务链里。系统里最基本的通讯机制是队列(queue),其他的如信号(semaphore)、互斥(mutex)都是基于队列而实现的。每一个队列有自己的xQUEUE结构,里面有读写指针(pcWriteTo、pcReadFrom)以及等待读写的任务(xTasksWaitingToSend、xTasksWaitingToReceive)等信息。freeRTOS用来进入和退出关键区域的函数是portENTER_CRITICAL和portExit_CRITICAL。 对于关键区域,UCOS-II提供了一个局域(local)变量OS_CPU_SR用来保存和恢复某些处理器状态(cpu status),如中断屏蔽设置等;freeRTOS没有提供类似的机制,而是通过ulCriticalNesting变量来决定是否屏蔽中断。
freeRTOS把任务分成4种状态:就绪(ready)、执行(running)、挂起(suspended)、阻塞(blocked)。任务在某个时刻只会处在某一个任务链中。系统根据任务链的内容进行协调式(cooperative)或者抢占加轮流(preemptive + round robin)式调度。 在两个系统里,抢占式调度都是通过时钟节拍中断(time tick interrupt)来实现的。任务的主动切换也可以通过触发软件中断来实现,但不是非得如此才行,各个移植(porting)可以有自己的选择。
freeRTOS里最常用到的内存管理方式是:不固定内存块的大小;选择满足要求的最小空闲内存块使用,并将多余的部分划分出去形成一个新的内存块。这种管理方式有可能产生碎片,不过使用起来要方便一些。
适当的剪裁可以减小系统并提高系统的速度。但是对于大多数的项目来说,处理器的大部分时间应当不是花在操作系统上(如果不是这样的话,是不是应该使用操作系统就成了一个需要考虑的问题了),所以对操作系统的剪裁不必追求尽善尽美。出于同样的原因,一定要说某个操作系统比另一个小,或者比另一个快,都没有太大的实际意义。
据本文作者的经验,如果系统不稳定,问题基本不会出在操作系统本身,而是很可能在于操作系统的移植有漏洞,或者中断的处理不成功。移植和中断的查错都很不容易,需要有很好的耐心和经验。
freeRTOS的移植通常需要修改3个文件:
UCOS-II的移植也是需要修改3个文件:
很明显,两个系统的移植工作量大致相等。
|
|