实现自己的软件定时器

为什么要实现软件定时器:

在芯片平台上,地址空间也是相当宝贵的,如果保留了更多的硬件定时器的话,就需要更多的地址空间,那么我们能不能作个折中方案呢?答案是肯定的,我们可以使用一个硬件定时器,来模拟实现一个软件定时器,可以满足更多的定时需求,需要注意的一点就是软件定时器精度可能会有稍微误差,因为会涉及到任务调度、锁中断等,在对定时精度要求不高的场景,可以考虑使用软件定时器。Linux内核中的timer_list精度为10ms,这里我们来实现一套精度为1ms的软件定时器(当然可以实现精度为微秒级的,但是没有必要,微秒级的直接使用硬件定时器了)。

涉及知识点:任务创建与调度、信号量同步、锁中断、中断处理、回调函数、链表操作

设计思想:

对外提供创建定时器、删除定时器、添加定时器、修改定时器超时时间四个接口,创建定时器时,根据用户传入时间折算成物理定时器定时时间,同时做一些软件定时器其他必要操作;添加定时器时,根据超时时间长短添加到超时链表中,一旦超时则处理超时的定时器(通常是链表头部的第一个节点);删除定时器操作把不需要的定时器从超时链表中删除;修改定时器接口主要完成修改超时时间的功能;

在软件定时器模块初始化时,创建超时处理任务,挂接物理定时器中断处理函数,初始化链表、信号量等;超时后中断处理函数释放信号量来激活任务,任务来处理超时链表中的超时定时器。

实现:

1、要实现软件定时器,首先我们需要定义一个结构体来定义对象使用

typedef void (*timer_func)(u32);   /*定义回调函数类型*/

struct softtimer_list{

timer_func    func;  /*超时回调*/

u32               para;/*回调函数参数*/

u32               time_out;/*超时时间,毫秒级别*/

char*              timer_name;/*给定时器起个名字,方便维护*/

struct list_head      entry;/*链表操作使用*/

................         /*其他需要的成员变量,视情况添加*/

};

2、定义接口

模块内部接口

1)static int timer_init(void){

初始化信号量、互斥锁、创建任务、挂接中断等;

return 0;

}

2)static int softtimer_task_func(void *data)

{

等待物理定时器超时释放信号量,处理超时定时器

return 0;

}

3)static irqreturn_t softtimer_interrupt_cb(int irq,void *dev)

{

清中断,释放信号量

}

对外接口:

1)int softtimer_create(struct softtimer_list *timer)

{

参数检查,分配timer id,折算超时时间

}

2)int softtimer_add(struct softtimer_list *timer)

{

根据超时时间,插入到超时链表中,注意插入头部、尾部、中间三种情况的超时时间更新操作;

}

3)int softtimer_delete(struct softtimer_list *timer)

{

删除不需要的定时器,注意删除头部、尾部、中部定时器时需要分别处理。

}

4)int softtimer_mod(struct softtimer_list *timer)

{

更新定时器超时时间。

}

好了,我们的软件定时器设计完成,在节省物理timer资源的同时,满足了对定时要求不高的任务的定时需求,一举两得。

实现自己的软件定时器,布布扣,bubuko.com

时间: 2024-10-21 01:49:14

实现自己的软件定时器的相关文章

毫秒,微妙级别软件定时器

单片机开发中,软件定时器是常用的工具.定时执行特定任务和延时功能,都可以用软件定时器实现. 常见的延时函数的实现做法有: 1. 使用空指令进行延时,通过控制空指令的执行次数,进行延时.优点:不需要占用系统外设.缺点:系统运行指定个空指令的时间不稳定,中途出现的中断处理会严重影响计时的精确性. 2.使用单片机的定时器外设,设定特定的时间产生中断,进行计时.优点:计时准确,不受其他中断影响计时.缺点:浪费单片机外设资源,并且延时处理不能嵌套调用,灵活性不够. 这里要介绍的是利用单片机内部的sysTi

高效软件定时器的设计

软件定时器在协议栈等很多场景都有广泛的应用,有时候会有大量的定时器同时处于工作状态,它们的超时时间各异,要高效的保证每个定时器都能够较为准确的超时并执行到其回调函数并不是一件易事.本文分析嵌入式实时操作系统Nucleus的定时器方案,它巧妙的管理了一条按照相对时间来排序的双向链表,避免每次tick中断都要遍历链表检查超时和更新剩余时间,实现了一种相当高效的软件定时器. 结构体TM_TCB来表示动态创建的定时器,其定义如下 typedef struct TM_TCB_STRUCT { /*Nucl

软件定时器-闹钟提醒我们该吃饭吃饭,该睡觉睡觉

闹钟提醒我们该吃饭吃饭,该睡觉睡觉 原文地址:http://blog.csdn.net/u011833609/article/details/28862125 softwaretimer.h #ifndef _SOFTWARETIMER_H_ #define _SOFTWARETIMER_H_ typedef enum{z_false = 0, z_true = !z_false} z_bool; typedef unsigned char z_uchar; typedef unsigned c

μC/OS-II中使用软件定时器

在试着将μC/OS-II移植到ARM7芯片(LPC2138)上的过程中,发现使用OSTmrCreate创建的OSTmr始终都不能执行CallbackFunction,OS版本是v2.85,最后是这么解决的. 在文档<uCOS-II-RefMan.PDF>中找到了关于“OSTmrSignal()”这个函数的一段描述: OSTmrSignal() is called either by a task or an ISR to indicate that it’s time to update th

软件定时器osTimerCreate返回NULL

CMSIS-RTOS是对FreeRtos的封装,函数名比較适合纯软件编程. 如今的版本号是1.0.2. id1 = osTimerCreate(osTimer(Timer_1), osTimerOnce, NULL); 可是这个osTimerCreate总是返回0x00000000. 就是创建软件定时器不成功. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/di

OSAL之时间管理,软件定时器链表管理

读源码写作,尊重原创: 本博文根据蓝牙4.0, 协议族版本是1.3.2 OSAL的时钟实现在OSAL_CockBLE.c与OSAL_Clock.h两个文件中.OSAL支持完整的UTC(世界统一时间),以2000年1月1日00:00:00为时间起点,可以精确到年.月.日.时.分.秒的时间值. 背景知识 // number of seconds since 0 hrs, 0 minutes, 0 seconds, on the 1st of January 2000 UTC存储自2000年1月1日开

emWin 2天速成实例教程004_软件定时器(Timer)和位图片动画

备注:(1)打开工程目录下的"Exe\GUISimulationDebug.exe"即可看到效果.(2)看完教程000-005就基本会用emWin做项目,其他章节可以需要时再参考.  emWin的TIMER是一个软件定时器,它以OS_TimeMS变量的值作为定时基准,而OS_TimeMS则通过一个硬件定时器每1ms中断加1,在emWin内部程序不断查询OS_TimeMS的变化实现软件定时.  在很多应用场合,我们需要用到定时器,比如每隔一定时间查询某一事件有没有被触发,每隔一定时间改变

uC/OS-III-11.0-uC/OS-III软件定时器

1.软件定时器管理 uC/OS-III提供了软件定时器服务(相关代码在OS_TMR.C中).当设置OS_CFG.H中的OS_CFG_TMR_EN为1时软件定时器服务被使能. 2.uC/OS-III 定时器的分辨率决定于时基频率,也就是变量OS_CFG_TMR_TASK_RATE_HZ的值,它是以 Hz为单位的.如果时基任务的频率设置为 10Hz,所有定时器的分辨率为十分之一秒.事实上, 这是用于定时器的推荐值. 定时器用于不精确时间尺度的任务. 3.uC/OS-III提供了一些函数用于管理定时器

ucosiii浅析内核对象-软件定时器

内核对象和各种内核机制的函数接口都在os.h里声明,实现在各自的.c文件,比如os_tmr.c和os_time.c. C语言全局变量一般会默认初始化:局部变量如若不初始化,会分配垃圾数据的:建议使用时都手动初始化. 其实使用内核对象时,就类似与使用任务,只不过在创建对象之前,要先声明一个内核对象. 好了,上面闲聊了几句,今天来说说ucosiii的几个内核对象. 首先说"软件定时器",其实单纯的讲就是定时作用,这里我们要注意的就是,使用它方法和使用任务类似:那么我们就先来分析分析任务的执