发明内容
本发明所要解决的技术问题是,提供一种在嵌入式系统中既能确保多个用户定时器、异步事件的有序控制,又能提高现有用户定时器、异步事件执行效率的方法以及实现该方法的系统。
本发明为解决上述技术问题所采用的技术方案是,一种定时器和异步事件的处理方法,包括以下步骤:
a、系统初始化用户队列与就绪队列,并初始化中断定时器的中断周期,用户队列用于存放用户任务需要调度的异步事件或需要启动的用户定时器转换为线程后对应的节点,就绪队列用于存放调度任务需要立即执行的从用户队列中取出的异步事件线程对应的节点或用户定时器线程对应的节点;
b、调度任务检查就绪队列,就绪队列为空时或者执行完就绪队列中所有节点对应的线程直至就绪队列为空后,调度任务检查用户队列;
c、将异步事件线程对应的节点以及已到期的用户定时器线程对应的节点加入至就绪队列,系统启动中断定时器,并设置中断定时器的中断服务程序和定时间隔;
d、初始化中断定时器的中断周期,在所述定时间隔到期后,中断定时器调用中断服务程序释放一个同步信号量,进入步骤b;
在所述步骤b至d循环执行过程中,当用户任务有需要调度的异步事件或需要启动的定时器时,系统立即将该异步事件或用户定时器转换为线程,并加入用户队列形成用户队列的节点。
本方案中既可以同时启动多个用户定时器也可以同时处理多个异步事件,保证了所述技术方案的通用性,由于用户定时器和异步事件在一个任务(本发明中的调度任务)的多个线程中同时执行,减少了任务间的切换开销,提高了执行效率,并且通过同步信号量的释放有序地控制执行异步事件或用户定时器对应线程。
进一步的,当系统要求支持高精度的用户定时器时,则采用高精度的硬件定时器作为中断定时器,本文所述“高精度”为毫秒级的精度,初始化时设置中断定时器的中断周期为需要的精度,如当前的应用环境需要硬件定时器的精度达到1ms,则设置硬件定时器的中断周期为1ms;否则,中断定时器可以使用软中断定时器。当采用高精度的硬件定时器,很容易实现高精度的系统中断,从而保证了用户定时器能够十分准确的定时。
步骤c中,为了更进一步地提高执行效率,提供一种优选的中断定时器的定时间隔设置方法:当检查到用户队列中有异步事件线程对应的节点或已经到期的用户定时器线程对应的节点时,在将以上节点加入就绪队列后,系统设置中断定时器的定时间隔为零;当检查到用户队列中没有节点时,系统设置中断定时器的定时间隔为系统预设的固定值;当检查到用户队列中仅存在用户定时器节点且所有的用户定时器均未到期时,系统设置中断定时器的定时间隔为所有用户定时器的定时间隔的最小值。
进一步的,为了保证执行的灵活性,所述用户队列、就绪队列可以设置多个。即,系统可以根据异步事件和用户定时器的优先级或类型,选择创建多个不同的用户队列或就绪队列。比如根据类型,系统可以创建两个用户队列:异步事件用户队列和用户定时器用户队列;另外一种类型的用户队列可以根据不同的优先级创建不同的用户队列,调度机制可以根据优先级决定优先处理哪些异步事件和定时器,这样保证了灵活性。
进一步的,为了方便后续的维护和调试,系统对所有用户任务的需要调度的各异步事件和用户定时器提供统一的接口,在将异步事件或用户定时器转换为线程,将线程控制块加入用户队列形成用户队列的节点时,还需注明节点所对应线程的类型、优先级。
嵌入式系统,包括接口模块、队列模块、调度任务模块、中断模块;
所述接口模块包括用于当用户任务有需要调度的异步事件或需要启动的用户定时器时,将该异步事件或用户定时器转换为线程,并加入队列模块中的用户队列形成用户队列的节点的子模块;
所述队列模块包括用于初始化用户队列与就绪队列的子模块;所述用户队列用于接收用户任务通过接口模块存入的异步事件线程对应的节点或用户定时器的线程对应的节点;所述就绪队列用于接收需要被调度任务模块立即执行的异步事件线程对应的节点或用户定时器的线程对应的节点;
所述调度任务模块包括用于检查就绪队列,就绪队列为空时或者执行完就绪队列中所有节点对应的线程直至就绪队列为空后,检查用户队列,将用户队列中的异步事件线程对应的节点和已到期的用户定时器线程对应的节点加入就绪队列,加入完毕后启动中断定时器并设置中断定时器的中断服务程序和定时间隔的子模块;
所述中断模块包括用于初始化中断定时器的中断周期;当定时间隔到期后,调用中断服务释放一个同步信号量给调度任务模块的子模块。
进一步的,调度任务模块还包括用于当检查用户队列中没有节点或已经到期的用户定时器线程对应的节点时,在将以上节点加入就绪队列后,设置中断定时器的定时间隔为零;当检查到用户队列中没有节点时,设置中断定时器的定时间隔为系统预设的固定值;当检查用户队列中仅存在用户定时器节点且所有的用户定时器均未到期时,设置中断定时器的定时间隔为所有用户定时器的定时间隔的最小值的子模块。
进一步的,队列模块还包括用于根据异步事件和定时器的优先级或类型,创建多个不同的用户队列或就绪队列的子模块。
进一步的,接口模块还包括用于在将各用户任务需要调度的异步事件或需要启动的用户定时器转换为线程时,将线程控制块加入用户队列形成用户队列的节点,还需注明节点所对应线程的类型、优先级的子模块。
本发明的有益效果是,系统中既可以同时启动多个用户定时器也可以同时处理多个异步事件,保证了通用性,用户定时器和异步事件在一个任务的多个线程中同时执行,减少了任务间的切换开销,提高了执行效率。进一步的,用户队列和就绪队列可以设置多个不同的队列,保证了灵活性。进一步的,采用高精度的硬件定时器,从而保证了用户定时器能够十分准确的定时。进一步的,将异步事件和用户定时器通过接口统一起来,使用起来较为方便,便于后续的维护和调试。
具体实施方式
本发明利用多线程调度同时处理异步事件和定时器,而需要同时高效处理异步事件和定时器的场景,在数据通信的设备上普遍存在。例如,在双向转发检测协议中,一方面需要启动各种发送报文和检测报文的用户定时器,而且用户定时器需要毫秒级的精度,另一方面又可能随时接收到对端设备发送的控制报文需要及时处理。为适应高精度要求,使用硬件定时器。
如图1所示定时器和异步事件的处理系统包括队列模块、接口模块、调度任务模块、中断模块。
队列模块,负责创建维护就绪队列和用户队列,用户队列负责接收其他任务模块通知的需要执行的异步事件或需要启动的用户定时器,就绪队列则只负责存放将要被调度任务模块执行的线程节点;就绪队列和用户队列可以创建单个的用户队列和单个的就绪队列,也可以根据异步事件和定时器的优先级或类型选择创建多个不同的用户队列、就绪队列;
接口模块,为其他任务模块的外部异步事件或用户定时器提供一个统一的接口,并负责将它们转换一个可被执行的线程控制块,加入到用户队列中形成节点;且加入用户队列前,线程控制块需注明线程的类型、优先级等;
调度任务模块,是多线程执行的主体部分,负责从用户队列中选择需要立即执行的线程(节点)加入到就绪队列,启动硬件定时器并等待同步信号量,获取到同步信号量后,负责从就绪队列中取出各个线程并执行;调度任务模块可以根据优先级选择特定的线程加入到就绪队列,也可以选择不同就绪队列中的线程进行执行;
中断模块,负责根据硬件定时器进行中断控制,当硬件定时器定时到期后执行中断服务程序,中断服务程序释放同步信号量,从而使得调度任务模块可以继续执行。
如图2所示,本发明定时器和异步事件的处理方法包括如下步骤:
a)队列模块初始化用户队列和就绪队列,中断模块初始化设置硬件定时器的中断周期;用户队列负责接收其他任务模块通知的需要执行的异步事件或需要启动的用户定时器,就绪队列则只负责存放将要被调度任务模块执行的线程节点;
b)调度任务模块检查就绪队列中是否存在节点,如果就绪队列为空,或者如果有节点则立即执行该节点所对应的线程,当就绪队列中存在多个节点时,则调度任务模块就不停地取出节点并执行该节点所对应的线程,直至就绪队列中的节点为空;然后调度任务模块检查用户队列;
c)调度任务模块检查用户队列,当检查用户队列中有异步事件线程对应的节点或已经到期的用户定时器线程对应的节点,在将以上节点加入就绪队列后,系统设置硬件定时器的定时间隔为零;当检查用户队列中没有节点时,系统设置硬件定时器的定时间隔为系统预设的固定值;当检查用户队列中仅存在用户定时器节点且所有的用户定时器均未到期,系统设置硬件定时器的定时间隔为所有用户定时器的定时间隔的最小值;。
d)调度任务模块启动中断模块中的硬件定时器,并设置硬件定时器的中断服务程序和定时间隔,之后,调度任务模块进入阻塞状态,中断模块根据硬件定时器对调度任务模块进行中断控制,当硬件定时器的定时间隔到期后,中断模块调用中断服务程序释放一个同步信号量给调度任务模块,调度任务模块接收到同步信号量后调度任务模块返回步骤b)顺序执行;其中,中断服务程序为释放一个同步信号量的函数;
上述步骤a)为初始化步骤,步骤b)至d)的执行是一个无限循环的过程,在步骤b)至d)的执行过程中,当各用户任务有需要调度的异步事件或需要启动的用户定时器时,接口模块立即将该异步事件或用户定时器转换为线程控制块,并加入用户队列形成用户队列的节点。
实施例1
异步事件和用户定时器需要同时多线程调度处理:
在本实施例中,多线程调度需要同时处理异步事件和用户定时器,它们之间发生的顺序是突发的,例如启动用户定时器后,用户定时器并未超时,此时却接收到其他系统的消息或外部设备的控制报文需要所述系统进行处理(异步事件)。本实施例中,有两个需要启动的用户定时器,用户定时器Timer1(定时间隔即超时时间为30毫秒)和用户定时器Timer2(定时间隔即超时时间为50毫秒),无需要调度的异步事件;在第一轮循环中,调度任务模块在等待同步信号量时,由接口模块接收到一个需要调度的异步事件。
如图3所示,详细描述本实施例1多线程调度的过程步骤,其中步骤303-310的执行过程是一个无限循环的过程:
步骤301、队列模块初始化用户队列和就绪队列,此过程包括初始化队列的数据结构、选择队列的种类等。本实施例初始化队列时,选择创建2个用户队列user1和user2以及创建2个就绪队列ready1和ready2,其中,用户队列user1存放异步事件线程对应的节点,用户队列user2存放用户定时器线程对应的节点,就绪队列ready1存放需要立即执行的异步事件线程对应的节点,就绪队列ready2存放已到期的用户定时器线程对应的节点,上述的队列均是由双向链表的数据结构组成。同时,设置硬件定时器的中断周期为1毫秒;
步骤302、当其他用户任务模块有需要调度的异步事件或需要启动的用户定时器时,系统将该异步事件或用户定时器转换为线程,并将线程控制块加入用户队列形成用户队列的节点;本实施例最初有2个需要启动用户定时器,用户定时器Timer1(30毫秒超时)和用户定时器Timer2(50毫秒超时),无需要调度的异步事件;接口模块将两个用户定时器的参数(定时间隔、定时器类型、定时回调函数等)保存到两个线程控制块TCB1和TCB2中,然后将TCB1和TCB2存放到用户队列user2中,使它们成为user2的两个节点;
步骤303、调度任务模块检查就绪队列中是否存在节点,如果存在节点,则转到步骤304,如果不存在节点,则转到步骤305。
步骤304、调度任务模块取出就绪队列中的节点,并执行所述节点所对应的线程。本实施例的本步骤中,第一轮和第二轮循环跳出此步骤;第三轮循环时,调度任务模块执行这TCB1与TCB3两个节点对应的线程,调度任务模块可根据TCB1与TCB3中的优先级信息确定具体执行的先后关系,比如,TCB1的优先级大于TCB3,那么先执行ready1中TCB1相关的线程,再执行TCB3相关的线程,执行完毕后进入步骤305;第四轮循环时,调度任务模块执行这TCB2节点对应的线程,执行完毕后进入步骤305;
步骤305、调度任务模块检查用户队列中是否存在节点,如果不存在节点,则转到步骤307,否则转到步骤306。本实施例中,第一轮循环时,用户队列user2中存在TCB1与TCB2两个节点;第二轮循环时,用户队列user2中存在TCB1与TCB2两个节点,用户队列user1中存在TCB3节点;第三轮循环时,用户队列user2中存在TCB2;用户队列中不存在节点,进入步骤307;
步骤306,如节点为异步事件节点或已到期的用户定时器节点,则将其存放到就绪队列中后,进入步骤307;如节点为未到期的用户定时器,则进入步骤307。本实施例中,第一轮循环时,用户定时器Timer1与用户定时器Timer2均未到期,进入步骤307;第二轮循环时,用户定时器Timer1到期,异步事件已被接口模块接收,则调度任务模块将TCB1与TCB3加入至就绪队列中,进入步骤307;第三轮循环时,用户定时器Timer2到期,将TCB2加入至就绪队列中;
步骤307、调度任务模块计算最小等待时间:如果用户队列中没有节点,则定时器的最小等待时间根据系统需要取一个的固定值;如果用户队列中存在已经到期的定时器节点或异步事件节点,将以上节点加入就绪队列后,将最小等待事件设置为零;如果用户队列中仅有用户定时器节点且所有的用户定时器均未到期,则通过比较线程控制块的定时间隔,最小等待时间为所有定时器的定时间隔的最小值。在本实施例中,第一轮循环中,用户定时器Timer1与用户定时器Timer2均未到期,则比较Timer1和Timer2的定时间隔,最小等待时间为Timer1的定时间隔30毫秒;第二轮循环中,用户队列中存在定时器节点定时已经到期,且就绪队列不为空,将最小等待事件设置为零;第三轮循环时,用户队列中存在定时器节点定时已经到期,将最小等待事件设置为零;第四轮循环时,因用户队列中已无节点,最小等待时间设置一个的固定值,如10毫秒;
步骤308、调度任务模块启动硬件定时器,并设置硬件定时器的中断服务程序和定时间隔,之后调度任务模块进入阻塞状态,进入步骤309。将步骤307中计算的最小等待时间设置为硬件定时器的定时间隔。本实施例,第一轮循环中,硬件定时器的定时间隔设置为30毫秒;第二、三轮循环中,硬件定时器的定时间隔设置为0毫秒;第四轮循环中,硬件定时器的定时间隔设置为10毫秒;
步骤309、中断模块查询硬件定时器是否到期,如果没有到期,则调度任务模块继续等待同步信号量,如果到期,则转到步骤310执行。中断模块的查询可以是通过中断记数,比较记录的数字与用户定时间隔的大小来感知用户中断是否到期,也可以是其它的实现方式。本步骤是已有的技术方案,在此不再赘述。本实施例,第一轮循环中,调度任务模块在等待同步信号量的同时,接口模块接收到异步事件,接口模块首先生成线程控制块TCB3,再将异步事件的控制消息保存在线程控制块中,最后将线程控制块保存在用户队列中,使其成为用户队列user1的一个节点;30毫秒到期后,进入步骤310;第二、三轮循环中,立即进入步骤310;第四轮循环中,10毫秒到期后,进入步骤310;
步骤310、中断模块调用中断服务程序释放一个同步信号量,唤醒调度任务模块继续执行,调度任务模块转到步骤303继续执行。
实施例2
只有异步事件需要多线程调度处理。
除了实施例1的多线程调度过程中同时处理多种异步事件和定时器外,也可以用来只处理异步事件或定时器。本实施例详细描述用来处理异步事件的多线程调度的过程,其中步骤403-409的执行过程是一个无限循环的过程:
在本实施例中,如图4所述,本发明的方法及系统用来处理各种异步事件,根据异步事件的性质,对应于多个不同的优先级,要求高优先级的异步事件优先处理。为便于阐述,异步事件记为event1、event2、event3,它们之间发生的顺序是随机的。
步骤401:队列模块初始化用户队列和就绪队列,并设置硬件定时器的中断周期。在本实施例中,创建三个用户队列user_high、user_middle、user_low,高优先级的异步事件加入user_high队列,中优先级的异步事件加入user_middle队列,低优先级的异步事件加入user_low队列。创建三个就绪队列ready_high、ready_middle、ready_low分别于用户队列相对应。
步骤402、接口模块分别将异步事件event1和event2分别加入到用户队列user_high和user_middle中,其过程为:接口模块首先生成两个线程控制块TCB1和TCB2,将event1和event2的参数信息(回调函数,回调函数参数,事件类型等)分别存放到线程控制块TCB1和TCB2中,将TCB1和TCB2分别加入user_high和user_middle队列中,使其分别成为它们的节点。
步骤403、调度任务模块检查就绪队列中是否存在节点,如果存在节点,则转到步骤404,如果不存在节点,则转到步骤405。本实施例第一轮的循环中,就绪队列ready_high、ready_middle、ready_low均没有节点。
步骤404、调度任务模块取出就绪队列中的节点,并执行所述节点所对应的线程。本实施例的第一轮循环中,直接跳出此步骤。
步骤405、调度任务模块检查用户队列中是否存在节点,如果存在节点,则转到步骤406,如果不存在节点,则转到步骤407。本步骤中,用户队列user_high和user_middle均存在节点。
步骤406、调度任务模块取出用户队列中的节点,并将其放到就绪队列中。在本实施例的本步骤中,将用户队列user_high和user_middle的节点存放到就绪队列ready_high和ready_middle中。
步骤407、调度任务模块启动硬件定时器,并在启动时设置硬件定时器的中断服务程序和定时间隔,硬件定时器到期后,中断模块释放同步信号量,调度任务模块继续执行。本实施例本步骤中,中断服务程序同实施例一,由于就绪队列中加入了两个异步事件节点,故硬件定时器的定时间隔为0,,中断模块释放同步信号量,调度任务模块转到步骤403中继续执行。
本实施例的第2轮循环中,步骤403取出就绪队列ready_high和ready_middle中的线程控制块TCB1和TCB2,分别执行它们所对应的线程;在步骤403到407的循环过程中,异步事件event3可以随时通过接口模块加入到用户队列user_low中,如调度任务模块在第1轮循环的步骤406中将异步事件event3节点加入到就绪队列ready_low中,并在第2轮循环步骤404中执行event3相关的线程。
实施例3
嵌入式多多线程调度系统,所述系统有接口模块,队列模块,调度任务模块和中断模块四部分组成,如图5所示,其中箭头方向代表数据的流向,图中的字母代表模块之间的交互标号。
接口模块,为外部异步事件或定时器提供一个统一的接口,并负责将它们转换为一个可被执行的线程控制块存放到用户队列中,所述线程结构可被调度任务模块识别。
队列模块,负责创建和维护就绪队列和用户队列,其中,用户队列通过接口模块接收其他任务模块通知需要调度的异步事件或需要启动的定时器事件,就绪队列则负责存放将要被调度任务模块执行的线程节点。所述队列模块可以根据系统的需要灵活配置多个就绪队列和多个用户队列,如图5所示配置了多个用户队列和多个就绪队列。为了更好的保证数据完整性,接口模块和队列模块之间交互可能需要一个互斥信号量保护用户队列。
调度任务模块,是多线程执行的主体部分,负责从用户队列中选择合适的线程节点加入到就绪队列,并负责从就绪队列中取出各个线程节点执行,其阻塞是通过等待同步信号量,继续执行需要获取同步信号量。所述调度任务模块需要同队列模块和中断模块进行交互,例如在图5中,调度任务模块从用户队列中获取线程节点,调度任务模块负责将线程节点存放到就绪队列,调度任务模块与中断模块的交互,即调度任务模块在操作用户队列时需要获取互斥信号量,用以保证用户队列中数据的完整性,调度任务模块和用户队列的交互则需要使用互斥信号量来保护用户队列。
中断模块,负责将调度任务模块创建的硬件定时器进行中断控制,当硬件定时器定时到期后执行中断服务程序,释放同步信号量,从而调度任务模块可以继续执行。如果本发明的调度系统要求支持高精度的用户定时器,则中断模块需要高精度的硬件定时器;否则,中断模块中的硬件定时器可以使用一般的软中断定时器替换即可。