微型抢占式多任务实时内核设计
if( (os_flag&0x01) && (!(--s_nLayers ) ) ) {--os_Schedule( ); }
5.2 内核同步对象
如果要保护执行时间较长的代码,就要使用内核同步对象来同步。常用的内核同步对象有事件(event)、信标(semaphore,亦称信号量)和互斥量(mutex)。 事件对象用来通知事件或者操作已经完成,它用一个布尔值来表示该事件处于通知还是未通知状态。信标对象用于对资源进行计数。它记录了当前可用的资源数目。当用1来初始化信标对象的可用资源数目时,信标对象实际上成为了互斥对象。MicroStar提供事件和信标两种同步对象,支持查询、限时等待或无限时等待操作。内核同步对象的结构如下:
typedef struct{
uint_16 waiter; /*等待列表*/
uchar num; /*可用资源数目或者事件状态*/
uchar type; /*同步对象类型*/
}OBJECT,*POBJECT,*HOBJECT,*HEVENT,*HSEMAPHORE;
当一个任务因等待同步对象而进入休眠态时,它的静态优先级按位存放在waiter域中。如果静态优先级为N的任务在等待某个同步对象,则waiter二进制数中第N位置1,以示等待。当type为EVENT_OBJECT时,表示事件对象,此时num为事件状态,1表示通知态,0表示未通知态;为SEMAPHORE_OBJECT时,表示信标对象,对应的num为可用资源数。
内核同步对象不是嵌入式多任务系统特有的,通用的多任务操作系统如Windows都提供齐全的同步函数,在此不作介绍。
6 运用和使用示例
在MicroStar中,各个功能模块是分开的,因而可裁减度高。移植MicroStar也比较容易,只需改写与硬件相关的任务创建和调度函数。MicroStar1.0的PC机完全版本的代码约为10KB,针对96单片机用汇编语言写成的版本为1.4KB。本文附带的演示示例,都在TC2.0下编译通过,可直接在PC机上运行。第一个示例启动了三个用户任务:① WatchTask任务在屏幕中央显示一个以10ms为计时单位的跑表。② KeyTask 任务每隔200ms读一次键盘,按“Q”键系统退出执行。③ MicroStar 任务显示MicroStar相关信息,每隔1.5s更新一帧。
演示程序及内核源码见本刊网站(www.dpj.com.cn)。
结 语
本文提出了基于事件的优先级这一观念,使任务优先级的安排更为合理。介绍了微型多任务实时内核——MicroStar的设计与实现。消息和信号两种通信方式的提供,使其对事件驱动编程有很好的支持。较为完善的定时器服务和齐全的任务同步函数库,给用户提供了更多、更灵活的选择。有限的功能,使其与其它实时操作系统相比,减小了从技术掌握上所花费的时间。加上较低的存储器消耗,总体上说,MicroStar是比较适合在中低端MCU平台上运行的。