朱德良,吴国强,陈新春
(中电装备山东电子有限公司,济南 250101)
在以51系列单片机为内核的嵌入式产品开发过程中经常使用简单的前后台系统,在超级循环中依照一定次序进行任务调用,而实时任务利用中断进行处理,这样做的好处是处理起来比较简单方便。但其缺点也很明显,尤其是在智能电能表领域中,随着用户对智能电表功能要求的不断增加,需要处理的任务量不断上升时,任务执行的实时性往往难以保证,而且一旦面临更换硬件平台的情况,几乎没有移植性可言,需要重复较大的工作量。因此,在嵌入式系统中使用实时操作系统来管理任务的调度是嵌入式应用的一个重要趋势,是单片机高水平应用开发的一个标识[1-3]。
目前嵌入式实时操作系统有很多,如Vxworks、linux、μC/OSII等,但其系统本身就占用了大量的CPU资源,对于8位的51系列单片机来说太过奢侈[4];文献[5]在时间触发的基础上设计了一种多任务调度器,利用消息传递的方式使得控制器在多个任务之间进行切换,得到了较好的效果;文献[6]则对常用的RTX51实时系统的优缺点进行分析,提出了抢占任务实时处理的重要性。
本文在时间触发系统的基础上,增加了抢占式内核的特性,对单片机中多任务操作系统设计提出了具体方法,提高了对抢占任务处理的实时性,并将其成功应用在智能电表中,证明了可行性,且对系统的维护和移植工作提供了方便。
在嵌入式系统设计时,通常采用时间触发和事件触发两种方式来实现[1],时间触发机制为各种任务提供了一个共享的定时器中断,通过定时器形成对任务的周期性调度,完成任务之间的切换。这种系统在规定事件内只有一个任务在调用直到结束,因此是可预测的、可靠的,但对外部紧急任务可能造成延误;而事件触发系统主要是依靠系统的中断来实现,所以能够对外部事件进行快速的响应,但如果多个中断源随机时间间隔中断,则中断响应可能遗漏[1]。
本系统在时间触发系统的基础上添加抢占的特性,对普通任务以时间触发形式按照调度器周期按部就班的进行调用;对紧急任务以抢占式系统进行处理,满足了紧急任务实时性处理的要求。
任务的结构如下组织,是任务中必要的信息,为了得到快速的存取速度,建议存放在DATA区中。
typedef struct
{
unsigned char realtask;//抢占任务标识
unsigned char priority;//任务优先级,以延时时间为衡量delay,deadline
unsigned char ready;// 任务状态
unsigned char period;// 时间间隔
TASK(*p_task)(void);// 任务指针}TASK[MAX_TASK]
MAX_TASK定义其大小,一般在10个以内为佳。
在系统的初期,初始化调度器是必要的一步,其主要作用是对时间触发的定时器进行初始化工作,根据系统要求,设定定时器的各个参数,利用定时器中断形成时间触发的调度驱动。
在8051系列的单片机中,可以使用定时器T0来完成此项工作,其具体初始化过程为
Initial_Timer0()
{
1)清空任务序列
2)设置定时器时间间隔数值
3)使能定时器中断
4)开启定时器
}
其中,定时器时间间隔数值的设定比较重要,如果时间间隔设定的较长,系统的反应时间就会有影响,造成有的任务执行延误;如果时间间隔设置过短,反而会降低系统的执行效率,因为过于频繁的任务调度会消耗过多的系统资源。因此在设定时间间隔数值时应谨慎考虑,建议在 (1~5)ms比较合适。
调度器的刷新任务主要是通过定时器的中断服务程序对任务进行调度。本系统是允许有抢占式紧急任务和合作式任务共存的,抢占式任务是需要立刻进行处理的,所以在系统中具有最高的优先级,但是抢占式任务的出现打乱了普通任务的执行,所以只有紧系事件才能设为抢占任务,而且处理时间要尽可能的短。这样,在调度器的每次刷新过程中都要检测是否有抢占式任务,如果有就直接执行抢占任务;否则判断各普通任务的优先级,也就是延迟时间,如果到了0说明该任务已需执行,则任务的状态ready+1,交由调度函数去执行。具体流程如图1所示。
图1 调度器的刷新流程图Fig.1 Flow chart of scheduler updating
void update(void)interrupt2 using1
{
Reset定时器;
检测是否有抢占任务要运行;
检测是否有普通任务要运行,ready+1;
还没有需要运行的任务,优先级减1;
}
任务的添加函数new_Task()是在系统运行初期将每个任务添加到任务队列中,成功时返回值为新任务号task_ID,否则为出错信息。它有三个参数:分别是任务的函数指针;任务的周期;任务类型。如果任务现有任务量没有达到最大,将各个参数赋值给TASK结构,则插入任务队列尾,并返回task_ID;否则返回错误(有全局变量task_Num来记录当前)。
相应的,当任务执行结束后(不需要周期执行的任务),可以将任务从任务队列中删除,以保证资源的有效利用。其过程与添加函数正好相反。
调度函数是在主循环中运行的唯一函数,将其与刷新函数相分离是为了防止长任务对系统的影响,其主要作用就是将已经就绪的任务进行执行。其过程为从任务队列中取出就绪任务 (TASK[i].ready>0)进行执行,并将其中的优先级恢复为设定的时间间隔period重新开始,如果此任务是一次性任务,则调用任务删除函数进行清理。
目前基于51系列内核的单片机和soc芯片不计其数,本文所描述的操作系统是业余标准的8051系列芯片,因此可以在任何基于8051系列芯片的嵌入式系统中进行移植。
智能电能表系统是一个比较复杂的嵌入式系统,它的MCU需要处理大量的内部外部的任务和设备,其中主要任务有485通信、LCD液晶显示、按键、读写E2PROM,红外通讯,读取计量芯片、蜂鸣器、ESAM模块、载波模块等,如图2所示。基于传统的前后台系统中对于其开发越发复杂,也更加不可控,而将本文所述的系统运用在其中,则有效地降低了开发的复杂性,提高了系统的可控性和鲁棒
性,并且可以在相同系列的系统中进行移植,大大节约了开发时间。其主程序可以描述为
void main(void)
{
1)初始化调度器;
2)初始化各个模块信息;
3)调用任务添加函数将任务加载到任务序列;
while(1)
{
各任务调度函
}
}
图2 智能电表系统任务示意图Fig.2 Drawing of smart meter system tasks
在嵌入式系统中使用实时操作系统来管理任务的调度是嵌入式应用的一个重要趋势,但大部分商业实时系统需要很大的系统开销,对51单片机来说很难实现。本文在时间触发系统的基础上,增加了抢占式内核的特性,提高了对抢占任务处理的实时性,并将其成功应用在智能电表中,证明了可行性,且对系统的维护和移植工作提供了方便。
[1] Michael J Pont.时间触发嵌入式系统设计模式[M].北京:中国电力出版社,2004.
[2] 郑宗汉.实时系统软件基础[M].北京:清华大学出版社,2003.
[3] 陈明计,周立功.嵌入式实时操作系统SmallRTOS 51原理及应用[M].北京:北京航空航天大学出版社,2004.
[4] 朱凤新,姚竹亭.基于AVR的时间触发嵌入式系统[J].工业控制计算机,2006,19(7):56-57.
[5] 李奇,樊晓平.一种时间触发的多任务调度器设计[J].单片机与嵌入式系统应用,2008(5):17-19.
[6] 徐哲.论RTX51单片机实时操作系统[J].齐齐哈尔工程学院学报,2012,6(3):22-24.