事件驱动的实时嵌入式系统的设计和实现.doc_第1页
事件驱动的实时嵌入式系统的设计和实现.doc_第2页
事件驱动的实时嵌入式系统的设计和实现.doc_第3页
事件驱动的实时嵌入式系统的设计和实现.doc_第4页
事件驱动的实时嵌入式系统的设计和实现.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

事件驱动的实时嵌入式系统的设计和实现 摘 要 嵌入式实时操作系统具有嵌入式软件共有的可裁剪、低功耗等特点;而实时操作系统,可以满足系统对实时性的要求。但嵌入式实时系统需要增加额外的系统开销,随着系统功能的增加,逐渐增加的开销将不容忽视。对于某些功能简单的嵌入式系统,本文提出了一种实时嵌入式系统的设计方法,采用简单的方法和代码来建立一个快速、有效地系统。该嵌入式软件系统主要包括主控循环系统、事件驱动任务、周期循环任务及软件计数器。在冰箱嵌入式系统中进行了具体实现,满足实时性的同时降低了对系统资源的占用率。 关键字 主控循环;事件驱动任务;周期任务;软件计时器1 引言 嵌入式实时系统中采用的操作系统,我们称为嵌入式实时操作系统,它既是嵌入式操作系统,又是实时操作系统。作为一种嵌入式操作系统,它具有嵌入式软件共有的可裁剪、低功耗等特点;而作为一种实时操作系统,可以满足系统对实时性的要求1。 但是,使用嵌入式实时操作系统还需要额外的ROM/RAM开销,2%5%的CPU额外负荷以及内核的费用;同时如果任务之间抢占CPU控制权处理不好,会产生系统崩溃、死机等严重后果;而且随着对嵌入式实时操作系统需求的增长,将越来越多的功能添加到系统中,使其变得越来越臃肿。对许多小型或中等嵌入式设备,尤其是对成本敏感的小型设备,使用嵌入式实时操作系统会大大增加设备的成本,因而在本文中提出一种实时嵌入式软件系统的设计方法。本文的设计思想主要包括主控循环系统、事件驱动任务、周期循环任务及软件计时器四部分。2 系统设计2.1 主控制循环 该系统将软件分成独立的任务模块,支持事件驱动任务,将事件驱动任务输入到事件队列,当接收到恰当地触发事件时,才开始执行。否则,使其空闲,只占用极少地处理时间;以预置地速度执行周期任务(即不需要触发就可执行地任务)3。根据需要,执行速度有准确计时和相对计时(与每次主控循环的执行速度相关联)两种方式。 该系统是非抢占式系统(其他的任务不会无法中断正在运行的任务),不需要使用信号量来保护数据。只有当任务条目函数返回数值时,才会中断所有任务。例如,一个有键盘、LCD、RS-232端口、多个I/O和串行打印机的嵌入式系统。I/O状态的每次改变将导致发送一条RS-232信息、打印输出和LCD更新。RS-232信息的接收将导致打印输出、LCD更新和输出状态更新。 程序1 主控循环int main(void) Init_All(); for (;) IO_Scan(); IO_ProcessOutputs(); KBD_Scan(); PRN_Print(); LCD_Update(); RS232_Receive(); RS232_Send(); TMR_Process(); / 此处可以添加异常处理代码 return (0); 在程序1中,无穷循环中的每个函数调用代表一个独立的任务,无论执行哪个函数,每个任务必须在合理的时间内返回。 该系统的主要工作是事件驱动任务。每个任务都有一个输入事件队列。例如,IO_ProcessOutputs是事件驱动任务,负责控制输出状态,当输出没有状态改变时,该任务处于空闲状态。需要启动输出时,则给该任务发送一条事件消息。在该系统中,有三个任务会向IO_ProcessOutputs发送事件消息: 输入扫描器(IO_Scan)任务,当输入状态改变导致输出状态的改变; RS-232接收任务,当接收到RS-232消息,需要开启或关闭输出; 按键扫描器任务(KBD_Scan),当完成一个条目时,需要开启或关闭输出。 其它的任务是周期任务,无需触发器即可运行。 有些需要运行地快一些,有些需要慢一点。例如,扫描输入需要比LCD的刷新快。为此需要提供一些任务间通讯的简单方法。当输入状态发生急剧地变化时,RS-232无法发送所有的消息。为此,应该降低从RS-232传送的I/O扫描器任务。这可以使用稳定的执行计数器技术来实现。 除上述功能外,还需要另一外些重要功能。如使LCD上的光标按固定的频率刷新。这些功能由TMR_Process间接调用,而不是由主控循环调用。TMR_Process是主控循环中唯一一个非用户定义任务。 程序2 事件输入结构typedef unsigned int word;typedef struct word InPtr; /*缓冲区头 */ word OutPtr; /* 缓冲区尾 */ word Count; /* 计数变量*/ EVENT_TYPE StoreBUFFER_SIZE; /* 数据存储空间*/ INPUT_EVENT_QUEUE_TYPE;2.2 事件驱动任务 每个事件驱动任务都有一个输入队列作为循环缓冲区。提供两个功能:PutEvent 和GetEvent。PutEvent将事件插入队列中,GetEvent从队列中取出事件。5其中,任务独占GetEvent,其他任务无法调用。参见程序2。 对每个任务而言,EVENT_TYPE结构是唯一的。换句话说,任务本身决定其期望接收的事件格式。例如,在IO_ProcessRequests任务中,需要包括输出数量及其新状态。在打印任务中,只需要使PRN_EVENT_TYPE足够大以存储一字串。因为每个任务的EVENT_TYPE不尽相同,用户需要根据INPUT_EVENT_QUEUE_TYPE为每个事件驱动任务定义不同的结构。而且,每个任务都有自己的GetEvent、PutEvent和初始化函数。 循环缓冲区允许异步读、写缓冲区,并将其存储到BUFFER_SIZE目录中。任何任务(包括任务本身)都可以将EVENT_TYPE事件插入到输入循环缓冲区当中。所有任务需要创建OUTPUT_EVENT_TYPE事件并调用OUTPUT_ PutEvent,如程序3所示。 程序3 创建OUTPUT_EVENT_TYPE事件/ 在 RS232 模块中OUTPUT_EVENT_TYPE OutputEvent;OutputEvent.NewState = 1; / 新状态 - onOutputEvent.Number = 1; / 开启输出OUTPUT_PutEvent(&OutputEvent); / 输入一个事件 程序4 发送事件到任务/ 从主控制循环中调用事件void IO_ProcessOutputs(void)word ret;OUTPUT_EVENT_TYPE OutputEvent;/ 此处通常为执行计数处理/ ./ 执行计数处理结束 if (ret = OUTPUT_GetEvent(&OutputEvent) != EMPTY) /缓冲区非空 / 处理 OutputEvent,开启/关闭所需输出 IO_OutputStateChange(OutputEvent.Number,OutputEvent.NewState)用户只需执行输出控制任务,其它的工作由OUTPUT_ PutEvent函数来完成。如程序5所示。2.3 周期任务 该系统可以从主控循环中调用任一函数,但必须注意两个问题:不能频繁地调用任务;不能长时间地延后其它任务的运行。程序5计数器执行处理void LCD_Process(void) #ifdef EXACT_TIMING disable(); /暂时禁止中断#endif if (LCD_ExecCounter = TASK_DISABLED) #ifdef EXACT_TIMING enable();#endif return; #ifdef EXACT_TIMING / 处理此处可能存在的对中断例程的抢占. return; /运行自己定义的任务并重新载入执行计数interrupt void TIMER_IRQ_10ms(void) / 其他任务对第一个问题,有一种机制可延缓任务的执行。分为两种情况:准确计时和相对计时。为此需要两个参数:执行计数器及重新加载数值。执行计数器从重新加载数值递减。当计数器为0时,调用任务,否则退出任务的记录函数。4参见程序4。在准确计时系统中,应避免定时中断抢占任务。在多数情况下,这不是问题,因为16位或32位的读和写是原子操作。最简单的解决方法是当程序处理执行计数器时,在某一段时间内中止所有的中断。参见程序4。其中需要说明地是:(1) 在准确计时系统中,执行计数器以固定的频率递减;在相对计时系统中,任务自己递减计数器。在准确频率系统中,可以确定任务执行的频率。将LCD_TASK_FREQUENCY设为100,使用10ms中断,可以确定该任务的执行频率为:在LCD任务执行计数器递减为0之前,每秒钟加上在该任务之前的其它任务的执行时间。(2) 将TASK_DISABLED尽可能的定义为最大的无符号整数。将执行计数器设为TASK_DISABLED以中止该任务,直至有进一步的需求。可以在其它任务中实现这种操作。例如,重要事件可以中止打印进程,直至有进一步的通知(任务间通讯的简单形式)。(3) 在准确计时系统中,10ms中断处理了大量的工作。但是对其中的一小部分任务,处理器无法进行比较,因此将该中断设为较低的优先权或允许其它中断抢占。目前的问题在于是否需要引入一些更简洁的机制(如德耳塔队列delta queue)以防止在一次中断中有太多的计数器递减。但由于该系统的任务数量不超过30个,因而不需要德尔塔队列。2.4 软件计时器 软件计时器使该系统具有了真正的多任务性。有几百个事件需要在固定的时间内激活一次或周期型激活。5大多数这样的事件需要准确计时,使得10ms的中断非常困难。主控循环将变得冗长和繁杂。因此需要一个简洁的解决方法。 程序5 软件计时器模块的应用接口word TMR_InstallTimeoutHandler(word timer_handle,void (*timeout_func)(word,dword)word TMR_Start (word timer_handle,word timeout,dword parameter);word TMR_Stop (word timer_handle); 程序5中的软件计时器模块为应用任务提供了三个基本函数。用户为每个计时器定义的间歇时间函数,必须在TMR_Start和TMR_Stop函数调用之前装入。通过调用TMR_InstallTimeoutHandler函数来完成。随后可以使用TMR_Start和TMR_Stop函数来启动或停止计时器。 在该系统中,10ms中断是终止计时器循环缓冲区的唯一计时器。由于在给定的时间内有几百个软件计时器在运行。因此应以更加合理地方式运行该部分。在每个10ms中断,递减几百个计时计数器是无法接受的。使用德尔塔队列可以解决这一问题。根据间歇时间值,将计时器插入德尔塔队列,只递减将要终止的计时器5。3 结论与展望 本文提出了一种简单、快速的嵌入式系统,并在冰箱嵌入式软件设计中予以实现。使用主控循环进行任务控制和处理,系统设计了事件驱动任务和周期性任务类型,并利用软件计数器控制周期性任务的执行。经过试验,冰箱嵌入式系统占用的存储空间大大缩减,并且效率和稳定性都有所提高。该论文的思想可以快速地建立一个复杂度合理的管理系统,特别适用于对成本敏感的小型设备,可以使其具有便利灵活、性能价格比高的特点。 但本文的设计思想仅适用于功能较少、需处理任务数量较少的小型设备,对于功能复杂的嵌入式应用,如含网络等功能的嵌入式系统,还需采用通常的嵌入式实时操作系统。参考文献1 王鹏,尤晋元,朱鹏,敖青云译操作系统:设计与实现第二版北京:电子工业出版社,20042 杨立峰LINUX嵌入式实时操作系统开发与应用重庆工学院,20023 D.1.Katcher,H.Arakawa,J.K.StrosniderEngineering and analysis of fixed priority schedulers IEEE Trans.Software1993 (9):920-9344 Donald F.StanatOn Non-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论