有利于低功耗的无累计误差的动态时长定时器实现方法
技术领域
本发明涉及一种有利于低功耗的无累计误差的动态时长定时器实现方法。
背景技术
在嵌入式开发中有很多应用需要使用到定时功能,但硬件设备提供的定时器的数量远远不能满足业务需求,如对外围设备进行周期性访问的需求,一般采用轮询方式。对于周期性获取,传统的实现方案就是利用系统提供的定时器,采取循环定时查询方式。在传统方案下将不利于系统低功耗的实现,并且也会对硬件定时器资源造成巨大的压力。使用这种方式不仅浪费系统资源,而且很难使嵌入式设备整体进入良好的休眠,从而导致功耗的浪费,增加了对电源需求的成本。硬件定时器在可测试性方面,当定时器出现异常问题时,不能方便地获得相关信息,使问题定位困难。
软件定时器的实现方式有很多,大都是当中断达到时候,定时器的值减少一个单位。当一个定时器的值减小到0的时候,它将触发与其相关联的服务程序。或者当中断达到时候,定时器的值增加一个单位,激活定时器处理程序,查询是否有定时器到期。导致了周期性的中断CPU,对有效软件定时器的命中率很低。影响系统性能,不能使CPU进入低功耗。
所以需要本领域技术人员迫切解决的一个技术问题就是:如何能够创新地提出一种有利于低功耗的无累计误差的动态时长定时器实现方法。
发明内容
针对现有技术中存在的问题,本发明的目的在于提供一种有利于低功耗的无累计误差的动态时长定时器实现方法的技术方案。
所述的有利于低功耗的无累计误差的动态时长定时器实现方法,其特征在于由相对时间单元、时钟中断服务单元、定时器处理任务单元、定时器管理单元和预定处理单元配合实现,
所述的相对时间单元是系统从开机到现在所经过的时间,由硬件定时器B构成,配置后持续运行,不会随系统时间的变化而变化,能够用来准确的计算时间;
所述的时间中断服务单元负责更新软件定时器的运行时间,根据最近软件定时器超时时间,设置下一次的硬件时钟源中断产生时间,同时激活定时器处理任务单元,时钟中断由硬件定时器A到期后触发中断;
所述定时器处理任务单元根据当时相对时间单元时间判断软件定时器节点是否到达定时时间,如果判断为定时器超期,则执行预定处理单元的定时器超期处理方法,根据定时器类型判断是循环定时器还是非循环定时器执行相关操作;
所述的定时器管理单元负责相关的初始化及定时器节点的插入、删除操作;创建定时器时,需要记录定时器定时时长、定时器类型、超期后发送的信息,根据定时器定时时长,将定时器增加到定时器等待处理链表,根据插入链表的位置,决定是否需要修改硬件时钟源的超时时间;删除定时器时,根据定时器编号,直接定位到定时器在链表中的位置,删除定时器,根据删除链表的位置,决定是否需要修改硬件时钟源的超时时间。
所述的有利于低功耗的无累计误差的动态时长定时器实现方法,其特征在于所述的硬件定时器A用于根据定时时长触发时钟中断服务单元,硬件定时器A是中断处理单元的构成部分。
所述的有利于低功耗的无累计误差的动态时长定时器实现方法,其特征在于所述的硬件定时器B作为参考时间源构成相对时间单元;定时器管理单元根据最近软件定时器时长设置硬件定时器A的中断触发时间,触发时钟中断服务单元运行;时钟中断服务单元读取硬件定时器B的时间,通过和上一次记录的硬件定时器B的时间进行比较,从而获得时间差,根据时间差更新软件运行时间,激活定时器处理任务单元,定时器处理任务获取相对时间单元时间与定时器节点超期时刻比较,如果当前相对时间单元时间大于定时器节点超期时刻,执行定时器节点中注册的预定处理单元中的函数。
本发明有益效果:传统软件定时器使用单个硬件定时器作为触发源和时间更新源,由硬件定时器产生中断,CPU响应中断,但是CPU响应中断需要消耗时间,以及当硬件定时器中断到来时CPU正在执行某中断服务程序,则需要更长的时间,长期的累积将会造成时间的偏差。而本发明方法采用的是相对时间单元即硬件定时器B作为参考时间源,硬件定时器B不需要触发中断,不需要由CPU响应中断后重新设置时间,因此从本质上避免了由于CPU执行中断服务程序而产生的时间偏差。
附图说明
图1是本发明的总体结构框图;
图2是本发明的软件定时器节点初始化示意图;
图3是本发明的用户信息节点初始化示意图;
图4是本发明的创建定时器流程图;
图5是本发明的定时器等待处理链表结构示意图;
图6是本发明的时钟中断服务流程图;
图7是本发明的定时器处理流程图;
图8是本发明的运行时间更新示意图。
具体实施方式
下面结合说明书附图对本发明作进一步说明:
本发明实施例的核心构思之一在于,通过采用了2个硬件定时器(硬件定时器A和硬件定时器B),其中硬件定时器A用于根据定时时长触发时钟中断服务单元,硬件定时器A是中断处理单元的构成部分。硬件定时器B作为参考时间源构成相对时间单元。定时器管理单元根据最近软件定时器时长设置硬件定时器A的中断触发时间,触发时钟中断服务单元运行。时钟中断服务单元读取相对时间单元时间(硬件定时器B的时间),通过和上一次记录的相对时间单元时间(硬件定时器B的时间)进行比较,从而获得时间差,根据时间差更新软件运行时间,激活定时器处理任务单元,定时器处理任务获取相对时间单元时间与定时器节点超期时刻比较,如果当前相对时间单元时间大于定时器节点超期时刻,执行定时器节点中注册的预定处理单元中的函数。
在软件定时器的累计误差分析方面,首先,把时钟中断服务单元与定时器处理任务单元分开处理,通过信号量异步激活,使得消除时钟中断服务单元,更新软件定时器运行时间的误差,及定时器处理任务单元回调函数执行所带来的函数执行时的时间开销,清除回调误差;其次,使用相对时间单元来进行定时器的时间管理,消除了定时器本身指令执行造成的时间开销。相对时间单元由硬件定时器B构成,配置后持续运行,不会随系统时间的变化而变化,因此可以用来准确的计算时间。
相对时间单元:由硬件定时器B构成,配置后持续运行,不会随系统时间的变化而变化,因此可以用来准确的计算时间。本发明计时单元采用CPU内部的64位定时器实现,该定时器可以分为32位级联模式,及第一个32位定时器(TIM34)用作用做预分频器,另一个用作32位的定时器(TIM12)。该定时器的精度可以高达微秒级别,本发明对其计算只精确到毫秒。
定时器管理单元:包含对硬件定时器的初始化,软件定时器管理资源的初始化,定时器处理任务单元初始化,创建定时器及删除定时器的具体实现方法:
1.初始化:
A.初始化硬件定时器
主要初始化相对时间单元中的硬件定时器B,启动相对时间单元开始计时;由于硬件定时器的精度与硬件选型和该器件的硬件配置相关,具体请参考选型器件的芯片资料;本发明按照毫秒精度进行配置和计算;
B.初始化软件定时器节点
本发明可以根据需要设置软件定时器个数,软件定时器资源采用连续的存储空间,按数组分配固定的序号,即为定时器节点的标识,按双向链表方式组织,通过空闲定时器链表管理;
C.初始化用户信息节点
本发明可以根据需要设置用户信息节点个数,用户信息资源采用连续的存储空间,按双向链表方式组织,通过空闲用户信息链表管理;
D.初始化定时器等待处理链表;
E.初始化系统时间(根据需要可选配置)
系统时间为记录系统的年月日时分秒,设置该功能,需要每秒更新一次系统时间,需要设置一个秒级的定时器超期节点,每秒钟对系统时间增加1秒;
初始化时从空闲定时器链表获取一个定时器节点,设置定时器节点中的处理函数为预定处理单元的系统时间处理函数,设置定时器节点中的处理函数参数为定时器节点的地址,设置定时器节点中的超期时刻为1秒;将定时器节点按超期时刻递增方式插入到定时器等待处理链表;
F.初始化定时器处理任务单元
根据系统的优先级别,创建一个较高的任务用于处理定时器超期;
G.启动软件定时器
根据最近定时器超期时间,设置硬件定时器A;由于最近一次超期定时器在初始化时只有可选的系统时间定时器,所以设置硬件定时器1秒后触发中断;
2.定时器创建:
如图6、图7,用户调用创建定时器函数,需要提供的参数有:定时器类型,定时器周期,超时发送的消息代码,用户标识,参数个数及参数;创建定时器时从空闲用户信息链表获取一个用户信息节点,存储定时器类型,定时器周期,超时发送的消息代码,用户标识,参数个数及参数到用户信息节点中;从空闲定时器链表获取一个定时器节点,将用户信息节点与定时器节点建立关联,即用户信息节点中的定时器节点指针指向定时器节点;设置定时器节点中的处理函数为预定处理单元的用户超期处理函数,设置定时器节点中的处理函数参数为用户信息节点的地址,设置定时器节点中的超期时刻为当期时间与定时器周期的总和,设置定时器节点中的删除函数为预定处理单元的用户删除处理函数;将定时器节点按超期时刻递增方式插入到定时器等待处理链表,根据插入的位置判断是否需要更新硬件定时器A,如果插入到链表头部则需要更新硬件定时器A,重新计算硬件定时器A的触发中断时间;将定时器节点的标识与定时器节点的超期时刻组合成定时器唯一用户标识返回给用户,用于定时器删除使用;
3.定时器删除:
根据定时器唯一用户标识,计算出定时器节点的标识,即为数组组织的索引;定位到定时器节点的地址;将定时器节点放回空闲定时器链表尾部;如果定时器节点的删除函数不为空,则调用删除处理函数;
4.系统时间更新(可选):
在初始化时已经为系统时间更新创建了一个1秒的定时器节点,当定时器节点中的处理函数被调用,即预定处理单元的系统时间处理函数被调用;系统时间发生更新,更新内容为秒增增加1,如果超过60秒归零,分增加1,如果超过60分归零,小时增加1,如果超过24小时归零,进行星期计算,天数增加1,根据年和月计算天的归1,如果天归1则月份增加1 ,如果月份超过12则月份归1,年增加1。
时钟中断服务单元:
时钟中断服务单元由硬件定时器A及时钟中断服务处理函数组成,当硬件定时器A超时后触发中断,触发时钟中断服务处理函数运行,更新软件运行时间及激活定时器处理任务单元;软件运行时间指定时器功能启动后记录的运行时间,软件运行时间的更新由硬件定时器A触发,读取硬件定时器A触发时的相对时间单元即硬件定时器B时间与上次记录的相对时间单元即硬件定时器B时间求时间差,将该时间差用于更新软件运行时间;这样做的好处是即使定时器A是动态变化的也可以准确记录软件运行时间,同时动态变化的时间长度也起到降低功耗作用。
时钟中断服务单元主要处理流程如下:
1.读取相对时间单元即硬件定时器B时间,通过和上一次读取的相对时间单元即硬件定时器B的时间进行比较,从而获得时间差,根据时间差更新软件运行时间,记录当前的相对时间以便下次比较;
2.根据当前相对时间单元时间查找最近的定时器节点中的超时时间,将定时器节点中的超期时刻与当前相对时间单元时间求时间差,时间差作为下一次硬件定时器A触发中断的时间,设置硬件定时器A触发时间;
3.激活定时器处理任务单元。
定时器处理任务单元:
定时器处理任务是实时操作系统中任务优先级较高的进程,由时钟中断服务单元激活,主要处理流程如下:
步骤1.定时器处理任务单元被激活以后,通过相对时间单元即硬件定时器B获取当前时间;
步骤2. 与定时器等待处理链表中的头节点比较是否超期;
步骤3.如果超期,则将该定时器节点从链表中取下,执行该定时器节点的处理函数,根据返回值,确定是否回收定时器节点资源;如果为释放返回值,回收定时器节点,继续执行步骤2;
步骤4.如果未超期,根据最近的定时器节点,判断是否需要更新定时器A;如果最近定时器节点的超期时刻小于当前时间则更新定时器A。
预定处理单元:
用户超期处理函数:
根据超期函数的参数,组织消息内容,将信息发送给指定的用户;根据定时器的类型重新设定时间,或回收定时器相关资源;如果为非循环定时器,则回收定时器保存的用户信息节点,设置释放返回值;如果为循环定时器,根据循环周期重新设置超期时刻,加入定时器等待处理链表;
用户删除处理函数:
作用是将用户信息节点进行回收;即将参数指定的用户信息节点,放回空闲用户信息链表尾部;
系统时间处理函数:
更新从启动开始的秒时间,更新系统时间,根据循环周期重新设置超期时刻,加入定时器等待处理链表。
时间偏差分析:传统软件定时器使用单个硬件定时器作为触发源和时间更新源,由硬件定时器产生中断,CPU响应中断,但是CPU响应中断需要消耗时间,以及当硬件定时器中断到来时CPU正在执行某中断服务程序,则需要更长的时间。长期的累积将会造成时间的偏差。而本发明方法采用的是相对时间单元即硬件定时器B作为参考时间源,硬件定时器B不需要触发中断,不需要由CPU响应中断后重新设置时间,因此从本质上避免了由于CPU执行中断服务程序而产生的时间偏差。
如图8,相对时间单元即硬件定时器B为相对时间,T1,T2,T3,T4,T5,T6,T7,Tn为硬件定时器A中断发生时的所取得的相对时间的值,ST1,ST2,ST3,ST4,ST5,ST6,ST7,STn为根据T1,T2,T3,T4,T5,T6,T7,Tn计算得到的软件运行时间;
ST1=T1,ST2=ST1+(T2-T1) ,ST3=ST2+(T3-T2) ,ST4=ST4+(T4-T3) ,ST5=ST4+(T5-T4) ,ST6=ST5+(T6-T5) ,ST7=ST6+(T7-T6) ,STn=ST(n-1)+(Tn-T(n-1)) ;由这些对软件运行时间的计算可以推出,软件的运行时间与中断处理时间和CPU执行时间无关,只与相对时间单元即硬件定时器B的时间有关,这样就消除了由程序运行及累计所以导致的误差;同时对硬件定时器A的定时器长度是可变的,在不需要长时间运行时可以使CPU进入深度休眠降低功能有很好的作用。