- 之前写了一个软件定时器,发现不够优化,和友好,现在重写了
- soft_timer.h
#ifndef _SOFT_TIMER_H_
#define _SOFT_TIMER_H_
#include "sys.h"
typedef void (*timer_callback_function)(void*);
typedef enum {
TIMER_ENABLE,
TIMER_DISABLE
}SoftTimerStatus;
typedef enum {
TIMER_MALLOC_ERR=-1,
TIMER_PRARM_ERR=-2,
TIMER_OK=-3
}SoftTimerReturn;
typedef enum {
/*立即调用一次*/
IMMEDIATE_CALL_MODE,
/*等待定时器时间到后调用*/
WAIT_CALL_MODE
}SoftTimerMode;
typedef struct SOFT_TIMER{
timer_callback_function timerFunc;
SoftTimerStatus sTimerStatus;
SoftTimerMode sTimeMode;
u32 timerStartTime;
u32 timerTime;
u16 timerIndex;
/*指向下一个定时器*/
struct SOFT_TIMER* nextTimer;
/*指向前一个定时器*/
struct SOFT_TIMER* frontTimer;
}soft_Timer;
void soft_TimerInit(void);
SoftTimerReturn soft_TimerCreate(soft_Timer** timer,timer_callback_function fn,SoftTimerMode mode,SoftTimerStatus status,u32 time,u16 timer_index);
SoftTimerReturn soft_TimerDelete(soft_Timer* timer);
void soft_TimerTickUpdate(void);
void soft_TimerTask(void);
u32 soft_TimerTime(void);
void soft_TimerCmd(soft_Timer* timer,SoftTimerStatus status);
u16 soft_TimerNum(void);
void soft_TimerTest(void);
#endif // _SOFT_TIMER_H_
#include "soft_timer.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
//#define NULL 0
u16 softTimerNum=0;
soft_Timer* TimerHead=NULL;
/*系统时间单位ms*/
u32 system_time=0;
void soft_TimerInit(void)
{
soft_Timer* tempTimer=NULL;
while(TimerHead!=NULL)
{
tempTimer=TimerHead;
TimerHead=TimerHead->nextTimer;
free(tempTimer);
tempTimer=NULL;
}
}
SoftTimerReturn soft_TimerCreate(soft_Timer** timer,timer_callback_function fn,SoftTimerMode mode,SoftTimerStatus status,u32 time,u16 timer_index)
{
soft_Timer* tempTimer;
tempTimer=TimerHead;
/*为定时器分配空间*/
TimerHead=(soft_Timer*)malloc(sizeof(soft_Timer));
/*分配空间失败*/
if(TimerHead==NULL)return TIMER_MALLOC_ERR;
/*定时器模式*/
TimerHead->sTimeMode=mode;
/*定时器功能*/
TimerHead->timerFunc=fn;
/*定时器索引号*/
TimerHead->timerIndex=timer_index;
/*定时器时间*/
TimerHead->timerTime=time;
/*定时器状态*/
TimerHead->sTimerStatus=status;
/*下一个定时器*/
TimerHead->nextTimer=tempTimer;
/*前一个定时器*/
if(tempTimer!=NULL)
tempTimer->frontTimer=TimerHead;
/*前一个定时器*/
TimerHead->frontTimer=NULL;
/*定时器启动时间*/
if(mode==IMMEDIATE_CALL_MODE)
TimerHead->timerStartTime=system_time-time;
else
TimerHead->timerStartTime=system_time;
/*定时器数*/
softTimerNum++;
/*返回定时器指针*/
*timer=TimerHead;
return TIMER_OK;
}
SoftTimerReturn soft_TimerDelete(soft_Timer* timer)
{
/*参数错误*/
if(timer==NULL)return TIMER_PRARM_ERR;
if(timer==TimerHead)
{
TimerHead=TimerHead->nextTimer;
if(TimerHead!=NULL)
TimerHead->frontTimer=NULL;
free(timer);
timer=NULL;
}
else
{
if(timer->nextTimer==NULL)
{
timer->frontTimer->nextTimer=NULL;
free(timer);
timer=NULL;
}
else
{
timer->frontTimer->nextTimer=timer->nextTimer;
timer->nextTimer->frontTimer=timer->frontTimer;
free(timer);
timer=NULL;
}
}
softTimerNum--;
return TIMER_OK;
}
void soft_TimerTickUpdate(void)
{
system_time++;
}
u16 soft_TimerNum(void)
{
return softTimerNum;
}
void soft_TimerTask(void)
{
soft_Timer* tempTimer;
tempTimer=TimerHead;
while(tempTimer!=NULL)
{
/*定时器使能状态*/
if(tempTimer->sTimerStatus==TIMER_ENABLE)
{
/*计时是否达到*/
if((system_time-tempTimer->timerStartTime)>=tempTimer->timerTime)
{
/*执行回调函数*/
tempTimer->timerFunc(tempTimer);
/*更新起始时间*/
tempTimer->timerStartTime=system_time;
}
}
tempTimer=tempTimer->nextTimer;
}
}
u32 soft_TimerTime(void)
{
return system_time;
}
void soft_TimerCmd(soft_Timer* timer,SoftTimerStatus status)
{
timer->sTimerStatus=status;
}
void callfun(void* arg)
{
static u32 cnt=0;
soft_Timer* st;
st=(soft_Timer*)arg;
// printf("this is a soft timer test %d.\r\n",cnt++);
// printf("timer index is %d\r\ntimer time is %d\r\n timer mode is %d\r\ntimer num is %d\r\n",st->timerIndex,st->timerTime,st->sTimeMode,soft_TimerNum());
}
void soft_TimerTest(void)
{
soft_Timer* st;
soft_Timer* st1;
soft_TimerInit();
soft_TimerCreate(&st,callfun,IMMEDIATE_CALL_MODE,TIMER_ENABLE,1000,4);
soft_TimerCreate(&st1,callfun,IMMEDIATE_CALL_MODE,TIMER_ENABLE,1000,4);
soft_TimerCreate(&st,callfun,IMMEDIATE_CALL_MODE,TIMER_ENABLE,1000,4);
soft_TimerDelete(st1);
while(1)
{
soft_TimerTickUpdate();
soft_TimerTask();
}
}