首页> 中国专利> 一种微嵌入式实时任务调度器及调度方法

一种微嵌入式实时任务调度器及调度方法

摘要

本发明请求保护一种微嵌入式实时任务调度器及调度方法,涉及工业控制及智能仪器仪表相关领域。本发明在调度过程中,通过对任务控制块中任务状态字的设置来标志任务状态,调度器通过检测任务状态字来确定任务的调度,通过时钟和事件来驱动调度;采用精简内核代码、可剥夺式内核和中断相结合的方式来实现实时性要求;采用一个状态字实现就绪、挂起和延时计数多用途的方式减少任务执行代码,精简调度算法减少内核代码;在任务控制块中加入调度锁标志,用户可以根据具体需要在任务中进行加锁或解锁。解决了中低端智能仪器仪表传统的编程方式存在的问题以及对实时性、低功耗、小内核的要求,提高了编程效率和代码可移植性。

著录项

  • 公开/公告号CN101290588A

    专利类型发明专利

  • 公开/公告日2008-10-22

    原文格式PDF

  • 申请/专利权人 重庆邮电大学;

    申请/专利号CN200810069439.4

  • 申请日2008-03-07

  • 分类号G06F9/48(20060101);G05B19/04(20060101);

  • 代理机构50123 重庆华科专利事务所;

  • 代理人康海燕

  • 地址 400065 重庆市南岸区黄桷娅崇文路2号

  • 入库时间 2023-12-17 20:53:53

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2015-04-29

    未缴年费专利权终止 IPC(主分类):G06F9/48 授权公告日:20100616 终止日期:20140307 申请日:20080307

    专利权的终止

  • 2010-06-16

    授权

    授权

  • 2008-12-17

    实质审查的生效

    实质审查的生效

  • 2008-10-22

    公开

    公开

说明书

技术领域

本发明涉及工业控制网络及智能仪器仪表控制等相关领域。

背景技术

在工业控制领域和仪器仪表行业中,一些控制器和仪表正向数字化、网络化、智能化方向发展,中低端仪器仪表在软件开发过程中存在传统的超循环编程方式,具有效率低、带码可移植性和重用性差等缺点,因此,迫切要求采用具有任务调度功能的调度器或操作系统来改变以前顺序执行的超循环调用方式,以满足资源管理和系统的实时要求。

同时,常用的嵌入式操作系统由于内核大、任务调度处理过于复杂、实时性等方面不能很好地适用智能仪器仪表小内核、高实时、高可靠、低功耗的要求。常见的一些嵌入式操作系统如嵌入式linux由于其内核大、功能强等特点一般用于功能较复杂的场合,如多媒体控制器、手持设备、交换机等。ucos-ii操作系统多用于控制、通信等设备中,但其调度复杂,造成最小内核大。这些常见的嵌入式操作系统普遍存在核心调度器复杂、调度方式不灵活等不足。同时大多数嵌入式操作系统在使用时都需要交纳一定数额的费用,这对一些本身成本较低的控制设备来说是不能接受的。

发明内容

本发明所要解决的技术问题是:针对现有嵌入式操作系统普遍存在核心调度器复杂、最小内核较大,调度方式不灵活等缺陷,设计开发了一种实时性强、调度简单、内核小、成本低的嵌入式任务调度器,以及实时任务调度方法。

本发明设计的嵌入式任务调度器主要包括任务控制模块、任务调度算法模块、时钟驱动调度模块、事件机制控制模块等核心模块。

任务控制模块:定义任务调度相关的堆栈指针、任务状态、优先级、任务入口地址和任务加锁标志等任务属性以及任务就绪表,通过任务状态字描述任务的状态,描述延时节拍以及任务就绪表。

任务调度算法模块:规定任务各种状态切换的条件,任务调度触发方式。任务调度触发方式主要有六种:任务延时、事件等待、任务挂起、事件触发、任务激活、中断,每个任务必须调用除中断外的任何一个或一个以上的任务调度触发方式。通过这六种触发方式使任务调度变得简单快捷,提高了实时性,同时也精简了内核。

时钟驱动调度模块:采用时钟定时中断的方式实现任务的定时切换,根据任务优先级分配每个任务执行的先后顺序,调度函数查找就绪表中优先级最高的任务进入运行态。设定每个任务执行的周期,根据任务优先级来分配执行的先后顺序。每个时钟中断产生时,比较是否任务加锁,如果任务未加锁则进行一次调度,就绪表中处于就绪态的最高优先级任务获得CPU控制权,如果任务加锁,当该任务运行任务解锁时,才产生调度。这样既保证了每个任务得到执行,又可以根据具体需要设定每个任务执行的周期,提高了任务的实时性。

事件机制控制模块:定义任务事件的结构形式,实现任务事件在任务调度中的实现方式等。任务事件由一个结构体来定义,包括事件等待任务名称、事件状态标志、事件值指针、事件值长度等。事件机制控制包括等待事件和触发事件,等待事件设置任务为挂起状态,产生调度;激活事件设置等待任务状态为就绪态,产生调度。

同时该调度器还设置任务抢占机制,当中断产生时,调度程序根据就绪表中处于最高优先级任务的优先级和当前任务优先级的高低以及加锁标志来确定是否进行调度。如果当前任务的优先级低于就绪表中的就绪态任务优先级且加锁标志为无效,则进行调度。否则不进行调度。这样保证了系统运行的实时性和可靠性。

本发明还提出一种微嵌入式实时任务调度方法,该方法具体包括,首先创建任务,初始化任务控制模块;就绪表中最高优先级任务获得运行权,进入主函数的空循环等待时钟中断产生任务调度,任务调度算法模块的调度函数根据任务控制模块中的任务入口地址进入任务运行,当任务进入系统延时、任务挂起、事件等待之一时,运行任务让出CPU控制权进入挂起或等待状态;当任务系统延时结束、任务被其他任务激活或等待事件产生有效等情况之一发生时,任务控制模块控制任务由其他状态进入就绪状态;当中断服务程序结束,任务调度算法模块的调度函数先检查被中断任务是否加锁,如果加锁则直接返回任务;如果未加锁,调度函数检测就绪表中是否存在优先级更高的就绪任务,如果有优先级更高的就绪任务,调度函数将当前任务状态进行压栈保护,然后调用任务级任务切换函数进行任务调度,执行完任务调度后,恢复被中断任务状态,继续运行被中断任务。

调度产生的条件主要有以下六种:①当任务进入系统延时时,系统延时函数根据时钟驱动模块中的时钟节拍设置当前任务控制块中的状态标志,任务进入延时等待状态,然后调用任务调度算法模块中调度函数进行调度。②当任务控制模块中的事件等待函数进入等待事件产生时,事件等待函数中设置当前任务状态标志,任务进入挂起状态,然后调用调度函数进行调度。③当任务完成当前操作,暂时不执行其他操作时,调用挂起函数设置当前任务状态标志,任务进入挂起状态,然后调用调度函数进行调度。④当系统时钟中断延时完成时产生时钟中断,时钟驱动调度模块在时钟中断服务程序中将各个延时任务的状态标志大于1的减1,比较是否存在延时结束任务,如果存在,表示该任务的状态进入就绪态,比当前任务优先级更高的就绪任务,如果有,进行调度;在其他中断产生后,先运行中断服务程序,然后比较被中断任务是否加锁,如果未加锁,则进行调度。⑤当挂起任务等待的事件产生或被其他任务激活时,其状态变量被设置为就绪态,然后进行调度。⑥任务运行到某个时刻,需要激活被挂起任务时,事件机制控制模块调用激活任务函数,然后调用调度函数进行调度。

由于在任务控制模块、调度算法、调度机制等方面采用了更有效的实现方法,既保证系统运行的实时性和可靠性,又减小了调度器的内核大小,在保证系统要求的前提下使得调度器的成本远低于操作系统的成本。

本发明解决了工业现场设备和中低端仪器仪表对操作系统高实时、小内核、低成本的要求。和现行的常用嵌入式操作系统相比,该调度器可以方便的移植到各种8位、16位单片机上,创建任务方便,内核可以减少2KB以内,任务切换可以达到5us以内,能够满足这些设备的要求,并大大降低了硬件成本和软件成本。和传统的超循环方式编程相比,由于采用了调度器,不同功能的模块可以用不同任务来管理,在产品换代或系统更新时,可以快速方便地将原来的代码移植到新的系统或产品上。

附图说明

图1本发明调度器总体控制流程图

图2任务调度算法状态描述示意图

图3任务切换示意图

图4时钟中断任务切换流程图

具体实施方式

本发明针对微嵌入式实时任务调度器的多任务、实时性、小内核的要求,设计了调度器的核心数据结构、任务调度算法、事件机制、调度算法的时钟驱动调度。

1.多任务:针对多任务要求,本发明采用常见的4种任务状态:就绪状态、运行状态、等待状态和挂起状态。就绪状态描述的是等待运行的任务状态;运行态描述了任务正在运行的状态;等待状态描述了任务处于延时等待的状态;挂起态描述任务当前操作完成或正在等待事件产生的状态。在调度过程中,通过对任务控制块中任务状态字的设置来标志任务状态,调度器通过检测任务状态字来确定任务的调度。

2.实时性:针对实时性要求,本发明采用精简内核代码、可剥夺式内核和中断相结合的方式来实现实时性要求。精简内核使执行的时间减少,可剥夺内核保证了实时性较高的任务优先执行的要求,中断保证了硬件实时通信。通过设置实时性要求较高的任务为更高优先级,时钟中断产生时,比较当前任务和就绪态的其他任务的优先级,如果有更高优先级的任务处于就绪态,就进行任务切换。同时通过中断来响应外部信号。这样可满足工业控制器及仪器仪表的实时性的需要。

3.小内核:为了解决内核大小问题,本发明采用单任务队列,通过精简任务控制块,采用一个状态字描述就绪、挂起和延时节拍计数三种状态的方式减少任务执行代码,通过事件来实现任务间的基本通信,精简调度算法减少内核代码,以实现小内核的要求。

4.调度锁:针对一些任务要求执行过程中不能被其他任务中断,本发明在任务控制块中加入调度锁标志,在中断服务程序执行完成后,检查被中断任务是否加锁,如果加锁不进行调度,直接返回被中断任务。保证个别任务执行的高可靠性和高实时性。用户可以根据具体需要在任务中进行加锁或解锁,加锁和解锁在每个任务中必须是成对出现。在调用事件等待/触发函数、延时函数、任务挂起/激活函数之前必须解锁。

下面针对附图和具体实施方式对本发明的实施作进一步的说明。

该嵌入式实时任务调度器包括,任务控制模块、任务调度算法模块、时钟驱动调度模块、事件机制控制模块。任务控制模块定义任务调度相关的堆栈指针、任务状态、任务优先级、任务入口地址和任务加锁标志以及任务就绪表,通过任务状态字描述任务状态、延时节拍以及任务就绪表;任务调度算法模块:通过调度函数描述任务状态切换的各种条件,任务调度机制,每个任务调用除中断外的任何一个或几个触发方式,任务调度器才进行调度;时钟驱动调度模块:采用时钟定时中断的方式实现任务的定时切换,根据任务优先级分配每个任务执行的先后顺序,调度切换执行优先级最高的就绪任务;事件机制控制模块:定义任务事件的结构形式,实现任务事件在任务调度中的实现方式,根据任务就绪表中处于最高优先级任务的优先级和当前任务优先级的高低以及加锁标志,激活函数确定是否进行任务调度切换。

同时该调度器还设置任务抢占机制,当中断产生时,调度程序根据就绪表中处于最高优先级任务的优先级和当前任务优先级的高低以及加锁标志来确定是否进行调度。如果当前任务的优先级低于就绪表中的就绪态任务优先级且加锁标志为无效,则进行调度,否则不进行调度。这样保证了系统运行的实时性和可靠性。

该调度器主要通过任务控制模块、任务调度算法模块、时钟驱动调度模块、事件机制控制模块等核心模块实现。任务控制模块通过定义任务调度相关的堆栈指针、任务状态、优先级、任务入口地址和任务加锁标志等任务属性以及任务就绪表,通过这些参数来描述任务的状态、调度的条件。任务调度算法模块描述任务各种状态切换的条件,任务调度触发方式。时钟驱动调度模块设定每个任务执行的周期,通过时钟中断来产生任务切换的节拍,完成任务的定时调度,以保证调度器的实时性。事件机制控制模块定义任务事件的结构形式,实现任务事件在任务调度中的实现方式等。任务控制块和调度算法是调度器的核心,事件、时钟中断是触发调度的条件,为调度算法服务。

调度器总体控制流程图如附图1所示。首先创建任务,初始化任务控制模块;就绪表中最高优先级任务获得运行权,进入主函数的空循环等待时钟中断产生任务调度,调度函数根据任务控制模块中的任务入口地址进入任务运行,当任务调用系统延时、事件等待、挂起三个函数之一,事件机制控制模块控制任务由运行状态进入等待或挂起状态,调用任务调度算法模块中调度函数,让出CPU控制权。当出现时钟中断、事件触发、任务激活三种情况之一时,事件机制控制模块控制任务状态从挂起或等待状态变为就绪态,调用调度函数,任务获得CPU控制权。

任务延时:当前任务由于需要延时调用系统延时函数设置当前任务状态标志为延时节拍,使任务由运行态进入等待状态,然后进行任务调度;事件等待:由于当前任务通过调用事件等待函数等待某个未发生的事件,设置当前任务状态标志为0而使任务进入挂起状态,然后进行任务调度;任务挂起通过设置当前任务的状态标志为0使当前运行任务从运行态进入挂起状态,然后进行任务调度;事件驱动函数是某个任务运行时触发某个事件有效时,调用事件触发函数设置事件状态标志为1和事件等待任务状态标志为1使等待该事件的任务从挂起状态直接进入就绪状态,然后进行任务调度;而激活任务函数是指某个任务运行到某个阶段需要启动一个挂起的任务执行时调用激活任务函数设置该挂起任务的状态标志为1来使该任务从挂起状态进入就绪态,然后进行任务调度。时钟中断可以使延时节拍依次减少,当减为1时,任务从等待状态进入就绪态;其他中断如果调用了事件驱动函数或任务激活函数,可以使事件等待任务从挂起状态进入就绪态;在被中断任务未加锁的情况下,中断都会调用调度函数。

整个任务调度就是通过任务延时、事件等待、任务挂起、事件触发、任务激活、中断这六种情况之一来实现任务状态的改变,从而实现调度的触发。

在本发明中采用了相应的数据结构、调度逻辑顺序和调度规则来具体实现。以下对该调度器中各控制模块的具体技术实施进行详细描述。

1.任务控制模块

任务控制模块,主要由一个结构体来管理任务执行相关的参数,每个任务在创建时复制一个相同的任务控制块结构体。任务控制块结构体由任务堆栈、任务入口地址、任务状态字、任务优先级和任务加锁标志5个部分组成。定义任务调度相关的堆栈指针、任务状态、优先级、任务入口地址和任务加锁标志等任务属性以及任务就绪表,通过任务状态字描述任务的状态,描述延时节拍以及任务就绪表。这样可以大大减小任务相关的参数,从而减小内核大小。

任务堆栈用于保护被中断或高优先级打断的现场数据,用一个长整型指针来指向堆栈空间的初始地址,初始化时指向任务堆栈空间的顶部。任务在切换时通过入口地址从堆栈空间压入或推出保护的任务数据。

任务入口地址是任务运行时的初始地址,是一个长整型指针,在任务创建时初始化指向任务函数名。

任务状态字,用来表示任务当前的状态和延迟的时间节拍数,用一个整型或长整型变量描述,0表示挂起状态,1表示就绪状态,大于1的值表示延时节拍数,在任务创建时初始化0。延时节拍根据时钟中断周期值计算出延时减1需要的中断次数。具体计算是:中断次数=1次延时节拍时间/系统时钟中断周期。比如状态标志大于1的数表示延时多少个毫秒,而时钟中断周期为200微毫秒,则时钟中断产生5次状态标志减1。任务状态标志通过任务延时、事件等待、事件触发、任务挂起、任务激活、时钟中断来进行设置,通过调度函数来进行判别。

任务优先级表示任务优先获得运行权的级别,保证实时性要求高的任务得到运行。根据操作系统允许的最大任务数来定义数据类型,如最多支持的任务数为64个,用一个8位数据描述。数字越小优先级越高,可以用任务号来表示。任务切换时,就绪列表中优先级最高的任务进入运行态。

调度锁主要作用是保证部分任务执行的实时性和可靠性,用一个无符号字符型变量表示。任务加锁标志表示中断处理完成后,根据被中断任务加锁标志值来确定是否进行调度,0表示未加锁,被中断任务可以被抢占,调用调度函数实现任务切换;1表示加锁,被中断任务不能被强占,中断完成后返回被中断任务。任务的加锁和解锁通过专门的函数来实现,任务中必须是成对出现,否则,可能造成系统只运行加锁任务。

在调度器任务控制模块中设置一个全局任务控制块数组来表示任务控制块列表,每个任务在创建时复制一个对应的任务控制块来描述任务的属性。创建任务就是调用任务创建函数把任务函数名赋给任务控制块数组中任务入口地址;为任务开辟堆栈空间,初始化该任务的任务堆栈;每个任务设置一个且仅有一个优先级,任务的优先级也可以用任务的ID号来表示;任务初始状态设置为就绪态;加锁标志初始状态为空,用户可根据具体情况在任务中调用加锁、解锁函数进行设置。

2.任务调度算法模块

任务调度算法模块规定描述任务状态切换的条件,任务调度触发方式,它具体表现在操作系统产生任务调度的执行条件中。任务调度触发方式主要有六种:事件等待、事件触发、中断、任务延时、任务挂起和任务激活,这六种方式中都包含了任务调度函数的调用,每个任务必须调用除中断外的任何一个或一个以上的任务调度触发方式来调用调度函数。

所有任务的状态字组成了整个操作系统的就绪表,采用一个变量实现了三种状态的描述,精简了调度器的内核。任务调度算法模块在这六种触发方式的作用下设置对应的任务状态标志,然后在就绪列表中找到优先级最高的任务,并把这个任务切换到运行状态。在任务控制块列表中使用任务在列表中的相对位置表示优先级的高低,并不需要实际的对任务优先级进行比较,这样可以节省调度时间。如图2所示为任务调度算法状态描述示意图。具体的方法如下:

(1)任务状态切换主要由任务延时、事件等待、任务挂起、事件触发、任务激活、中断服务程序等函数的调度组成。任务的状态由任务控制块中的任务状态字给出。

当系统产生中断时,不管是时钟中断还是其他中断,操作系统进入中断服务程序,如果是系统时钟中断,则检查各延时任务的状态标志是否大于1,如果大于1,则减1,如果减1后等于1,表示任务延时结束,延时任务进入就绪态。

当某个事件产生时,设置事件状态标志为1,事件触发函数通过该事件属性找到等待该事件对应的等待任务,将该任务的任务状态设置为1,事件等待任务进入就绪态。

当当前任务调用任务激活函数激活某个被挂起的任务时,置被激活任务状态标志为1,被激活任务从挂起状态进入就绪态。

当系统产生中断时,不管是时钟中断还是其他中断,操作系统进入中断服务程序,如果是系统时钟中断,则检查各延时任务的状态标志是否大于1,如果大于1,则减1,如果减1后等于1,表示任务延时结束,延时任务进入就绪态。

当某个事件产生时,事件触发函数通过该事件属性找到等待该事件对应的等待任务,将该任务的任务状态设置为1,事件等待任务进入就绪态。

当当前任务调用任务激活函数激活某个被挂起的任务时,置被激活任务状态标志为1,被激活任务从挂起状态进入就绪态。

如图3所示为任务切换示意图,描述了任务切换过程。具体切换过程包括,当前事件运行在任务延时、事件等待、任务挂起、事件触发、任务激活、五种任务状态之一时,或者中断产生且被中断任务未加锁时,进入任务调度。

然后,任务调度算法模块在就绪表从任务控制块队列的头部(即任务优先级为0的任务)开始依次检查任务就绪标志,如果任务状态标志≠1,表示当前任务为非就绪状态,继续检查下一个优先级的任务。如果任务状态标志为1,则找到最高优先级任务。

最后,调度函数比较当前最高优先级任务和当前运行任务是否相同,如果相同则退出调度,否则,先按照顺序保存当前任务状态到任务栈空间,再将CPU的堆栈指针指向需运行的任务栈顶,从栈空间将任务状态值,恢复程序计数器值,运行该任务。

内核采用可剥夺式内核,在其他中断服务程序完成后,调度函数先检查被中断任务是否加锁,如果加锁则直接返回任务;如果未加锁,调度函数检测就绪表中是否存在优先级更高的就绪任务,如果有,调度函数将当前任务状态进行压栈保护,然后调用任务级任务切换函数进行任务调度,执行完成后,恢复被中断任务状态。由于内核较小,控制任务不多,本调度器不允许中断嵌套。

3.时钟驱动调度模块

设定每个任务执行的周期,根据任务优先级来分配每个任务执行的先后顺序。每个时钟中断产生时,时钟中断服务程序比较是否任务加锁,每个任务的加锁和解锁是成对出现的,如果任务未加锁则进行一次调度,就绪表中处于就绪态的最高优先级任务获得CPU控制权,如果任务加锁,当该任务运行到任务解锁时,才产生调度。这样既保证了每个任务得到执行,又可以根据具体需要设定每个任务执行的周期,提高了任务的实时性和可靠性。

为了确保调度器的实时性,使每个任务都能得到实时调度,在时钟驱动调度模块中采用时钟定时中断的方式来实现任务的定时切换。时钟每产生一次中断就比较一次就绪表中的就绪任务的优先级任务,每次查找优先级最高的就绪任务,然后调度切换执行优先级最高的就绪任务。用户可以根据实时性要求设置时钟中断的周期。

同时,系统时钟节拍函数自动检查每个被延迟的任务,当任务的延时结束时,时钟驱动调度模块自动将任务状态设置为就绪状态并进行一次任务调度。时钟中断任务切换驱动调度过程见附图4,具体算法如下:

(1)时钟中断服务程序从任务控制块列表头部开始顺序检查各任务状态字,根据延时节拍周期计算需要的时钟节拍数,当延时周期满足要求后将所有延迟任务的任务状态字减1。

判断延时状态标志是否大于1,如不大于1,执行步骤(3);如大于1,延时状态标志减1,检查各个延时任务状态标志是否为1;

(2)当当前延迟任务的状态标志变为1时,表示任务进入就绪态,该任务延时结束,判断当前运行任务是否加锁;

(3)任务调度函数判断被中断任务是否加锁,如果加锁,时钟中断服务程序返回被中断任务继续运行;如果未加锁,检测就绪态任务优先级是否大于当前任务,如是,进入中断级调度,返回被中断任务进行一次任务调度。

4.事件机制控制模块

事件机制控制模块定义任务事件的结构形式,实现任务事件在任务调度中的实现方式及事件操作函数等。任务事件由一个结构体来定义,包括事件等待任务名称、事件状态标志、事件值指针、事件值长度等。每个与至少两个以上的任务事件相关联,其中一个任务等待事件,其它任务设置事件。事件的操作包括等待事件和触发事件,等待事件设置任务的状态标志为挂起状态,调用调度函数进行调度;触发事件设置等待任务状态为就绪态,调用调度函数进行调度。

该调度器采用事件机制来实现任务间的通信及调度驱动。事件结构模块中主要包括事件的关联任务、事件状态标志、事件值、事件值长度等。在事件初始化时必须配置事件的等待关联任务,用等待任务名初始化,事件状态标志表示该事件是否产生,定义事件状态标志为1表示产生事件,为0表示未产生事件。当任务运行过程中需要等待某个事件产生后才能继续运行该任务,任务通过事件等待函数等待一个事件的产生,通过检测事件状态标志的值来确定是否进行调度。如果事件状态标志为1,表示事件有效,则读取事件值,继续运行该任务;如果事件状态标志为0,表示事件没有产生,则置当前任务进入挂起状态,进行任务调度。如其他任务或中断触发该事件产生,则通过事件驱动函数设置该事件状态标志为1,同时设置等待事件任务状态为1,同时设置相应的事件值和长度,然后调用调度函数进行调度。等待事件任务根据优先级进入运行态后,通过事件获取相应的事件值,完成任务间的通信。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号