定时任务:有时候需要定时执行一些任务,刚毕业时候我一般在定时器中断写flag,在主循环里判断flag成立再执行函数,现在将这个过程写成了一些函数,我称为时间管理函数,用来简化写flag的过程。主要思想是在定义一个TimeManager结构体包含另外一个结构体数组TimeRegObj,中断函数每次会减去TimeManager中的计时值,一直减到小于0为止。而在主循环中会不停的查询TimeManager中的计时值是不是小于0的,是则执行TimeRegObj中的函数,并且将计时值重新给TimeManager。这里有个问题在于执行函数里面如果有很多延时操作,那定时执行会有误差。
typedef struct TimeManager{
TimeRegObj TimeRegObjHandle[15];
int TimeRegObjCountMs_32[15];
int TimeRegObjCountMsTemp_32[15];
TimeMangerRegObjSta[15];
} TimeManager;
其中TimeRegObj用来存放各个要执行的函数指针以及定时时间和标志
typedef void (*TimeRegHandleFptr)(void);
typedef struct TimeRegObj{
TimeRegHandleFptr funptr;
int TimeReg_32;
int funcdoCount;
char LoopCan;
}TimeRegObj;
以下是c和h文件·
#include "tim.h"
// 另外一种类,管理类
static unsigned char TimeManagerAdd( TimeManager* base, TimeRegObj *obj);
void TimeManagerCreate( TimeManager* base){
unsigned char i_u8 = 0,len_u8 = 0;
if(base != 0){
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
base->TimeRegObjCountMs_32[i_u8] = 0;//客房时间调整
base->TimeRegObjCountMsTemp_32[i_u8] = 0;//客房时间调整
base->TimeRegObjHandle[i_u8].TimeReg_32 = 0;//客房打扫
base->TimeRegObjHandle[i_u8].funcdoCount = 0;//客房打扫
base->TimeRegObjHandle[i_u8].LoopCan = 0;//客房打扫
base->TimeRegObjHandle[i_u8].funptr = 0;//客人不再入住
}
}
}
void TimeManagerScanTimeMs( TimeManager* base,int freq_ms_32){//由中断触发执行
unsigned char i_u8 = 0,len_u8 = 0;
if(base != 0){
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(0 == base->TimeRegObjHandle[i_u8].funptr) continue;//管理会员区域没有被注册过
if(base->TimeRegObjCountMs_32[i_u8] < 0) continue;
base->TimeRegObjCountMs_32[i_u8]-=freq_ms_32;
}
}
}
void TimeManagerScan( TimeManager* base){
unsigned char i_u8 = 0,len_u8 = 0;
if(base == 0)return;
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(0 != (base->TimeRegObjHandle[i_u8].funptr)){
//重新装值,从会员类的值里得到数据
if(base->TimeRegObjCountMs_32[i_u8] > 0) continue;
if('k' == base->TimeRegObjHandle[i_u8].LoopCan){
((TimeRegHandleFptr)(base->TimeRegObjHandle[i_u8].funptr))();//执行函数
base->TimeRegObjCountMs_32[i_u8] = base->TimeRegObjHandle[i_u8].TimeReg_32;
}else if('n' == base->TimeRegObjHandle[i_u8].LoopCan){
if(0 == base->TimeRegObjHandle[i_u8].funcdoCount) continue;//会员执行次数为0
if(0 != (TimeRegHandleFptr*)(base->TimeRegObjHandle[i_u8].funptr)){//会员的执行函数存在
((TimeRegHandleFptr)(base->TimeRegObjHandle[i_u8].funptr))();
base->TimeRegObjHandle[i_u8].funcdoCount--;
base->TimeRegObjCountMs_32[i_u8] = base->TimeRegObjHandle[i_u8].TimeReg_32;
}
if(0 == base->TimeRegObjHandle[i_u8].funcdoCount){
TimeManagerDelete(base,(TimeRegObj *)&(base->TimeRegObjHandle[i_u8]));//属于多次性的会员
}
}
}
}
}
TimeRegObj *TimeManagerCheck( TimeManager* base, TimeRegObj *obj){//检测一个会员是不是注册过,否则返回0
unsigned char i_u8 = 0,len_u8 = 0;
if((base != 0) && (0 != obj)){
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(base->TimeRegObjHandle[i_u8].funptr == obj->funptr){//该会员已经注册过了
return &base->TimeRegObjHandle[i_u8];//r是已经注册好了
}
}
return 0;
}
return 0;
}
unsigned char TimeManagerCheckTimeIsOver( TimeManager* base, TimeRegObj *obj){
unsigned char i_u8 = 0,len_u8 = 0;
if(base == 0)return 'n';
if(obj == 0)return 'n';
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
if(0 != TimeManagerCheck(base,obj)){//该会员已经注册过了
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(base->TimeRegObjHandle[i_u8].funptr == obj->funptr){//该会员已经注册过了
if('k' == base->TimeRegObjHandle[i_u8].LoopCan){//永久会员
if(base->TimeRegObjCountMs_32[i_u8] > 0){
return 'n';
}else{
return 'k';
}
}else if('n' == base->TimeRegObjHandle[i_u8].LoopCan){
if(0 == base->TimeRegObjHandle[i_u8].funcdoCount) return 'n';//会员执行次数为0
return 'k';
}
}
}
}
return 'n';
}
static unsigned char TimeManagerAdd( TimeManager* base, TimeRegObj *obj){//增加一个会员
unsigned char i_u8 = 0,len_u8 = 0;
if((base != 0) && (0 != obj)){
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(base->TimeRegObjHandle[i_u8].funptr == obj->funptr){//该会员已经注册过了
return 'r';//r是已经注册好了
}
if(0 == base->TimeRegObjHandle[i_u8].funptr){
base->TimeRegObjHandle[i_u8].funptr = obj->funptr;
base->TimeRegObjHandle[i_u8].LoopCan = obj->LoopCan;
base->TimeRegObjHandle[i_u8].TimeReg_32 = obj->TimeReg_32;
base->TimeRegObjCountMs_32[i_u8] = obj->TimeReg_32;
return 'k';
}
}
printf("bad !!! in time\n");
return 'n';
}
return 'n';
}
void TimeManagerDelete( TimeManager* base, TimeRegObj *obj){//从管理员的会员列表中删除删除一个会员
unsigned char i_u8 = 0,len_u8 = 0;
if(0 == base){return;}
if(0 == obj){return;}
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(&base->TimeRegObjHandle[i_u8] == obj){//该会员已经注册过了
base->TimeRegObjHandle[i_u8].funptr = 0;
base->TimeRegObjHandle[i_u8].LoopCan = 0;
base->TimeRegObjCountMs_32[i_u8] = 0;
base->TimeRegObjCountMsTemp_32[i_u8] = 0;
}
}
}
// 删除旗下所有的会员
void TimeManagerDelAll(TimeManager* base){
unsigned char i_u8 = 0,len_u8 = 0;
if(base == 0)return;
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(0 != base->TimeRegObjHandle[i_u8].funptr){//该会员已经注册过了
TimeRegObjDestory(base,&base->TimeRegObjHandle[i_u8]);
base->TimeRegObjHandle[i_u8].funptr = 0;
base->TimeRegObjCountMs_32[i_u8] = 0;
}
}
}
void TimeManagerUpdataTime( TimeManager* base, TimeRegObj *obj,int time_32){
unsigned char i_u8 = 0,len_u8 = 0;
if(0 == base){return;}
if(0 == obj){return;}
len_u8 = sizeof(base->TimeRegObjHandle)/sizeof(base->TimeRegObjHandle[0]);
for(i_u8 = 0;i_u8 < len_u8;i_u8 ++){
if(&base->TimeRegObjHandle[i_u8] == obj){//该会员已经注册过了
base->TimeRegObjCountMs_32[i_u8] = time_32;//客房时间调整
base->TimeRegObjCountMsTemp_32[i_u8] = 0;//客房时间调整
}
}
}
static int mallocok_count = 0;
static int mallocer_count = 0;
static int free_count = 0;
// 会员类
//添加一个会员,如果这个会员已经存在,返回的是原先的值,默认会员是永久类型
TimeRegObj * TimeRegObjCreate(void (*Handle)(),int time_32, TimeManager *Manager){//Manager是会员的管理员
TimeRegObj obj;
TimeRegObj * ret_obj;
unsigned char res = 0;
obj.funptr = (TimeRegHandleFptr)Handle;
obj.TimeReg_32 = time_32;
obj.LoopCan = 'k';
if((0 == Handle) || (0 == Manager)){
return 0;
}
res = TimeManagerAdd(Manager,&obj);
if(('r' == res) || ('k' == res)){//添加成功,会员注册过,或者注册成功
ret_obj = TimeManagerCheck(Manager,&obj);
return ret_obj;
}else{
//添加失败
// while(1){;}
return 0;
}
}
//解除会员关系会员的消失
void TimeRegObjDestory( TimeManager* base, TimeRegObj *obj){
if(0 != obj){
if(base == 0)return;
TimeManagerDelete(base,obj);//记账本清理
obj = 0;//房卡归还
}
}
// 更新会员的时间,包括管理员的时间
void TimeRegObjUpdataTime(TimeManager *Manager,TimeRegObj *obj,int time_32){
if(0 == obj) return ;
if(0 == Manager) return;
obj->TimeReg_32 = time_32;
TimeManagerUpdataTime(Manager,obj,time_32);
}
// 设置一个会员是普通会员,只能运行count_32次
void TimeRegObjRunCount( TimeRegObj *obj,int count_32){
if(0 == obj) return ;
obj->funcdoCount = count_32;
obj->LoopCan = 'n';
}
// 会员
#ifndef __TimeServer
#define __TimeServer
#include <stdio.h>
// 会员类 有多个
typedef void (*TimeRegHandleFptr)(void);//会员要执行的函数指针
typedef struct TimeRegObj{
TimeRegHandleFptr funptr;
int TimeReg_32;
int funcdoCount;
char LoopCan;
}TimeRegObj;
typedef void (*TimeHandle)(void);
typedef struct TimeManager TimeManager;
typedef struct TimeRegObj TimeRegObj;
typedef struct TimeManager{
TimeRegObj TimeRegObjHandle[15];
int TimeRegObjCountMs_32[15];
int TimeRegObjCountMsTemp_32[15];
// unsigned char TimeMangerRegObjSta[15];//执行状态
} TimeManager;
void TimeManagerCreate( TimeManager* base);
void TimeManagerScanTimeMs( TimeManager* base,int freq_ms_32);//放入中断中
void TimeManagerScan( TimeManager* base);//放在主循环里
TimeRegObj *TimeManagerCheck( TimeManager* base, TimeRegObj *obj);//返回找到的地址 没有找到是0
void TimeManagerDelAll( TimeManager* base);
void TimeManagerUpdataTime( TimeManager* base, TimeRegObj *obj,int time_32);
unsigned char TimeManagerCheckTimeIsOver( TimeManager* base, TimeRegObj *obj);
TimeRegObj * TimeRegObjCreate(void (*Handle)(),int time_32, TimeManager *Manager);
void TimeRegObjDestory( TimeManager* base, TimeRegObj *obj);
void TimeRegObjUpdataTime(TimeManager *Manager,TimeRegObj *obj,int time_32);
void TimeRegObjRunCount( TimeRegObj *obj,int count_32);
void TimeManagerDelete( TimeManager* base, TimeRegObj *obj);
#endif
使用前需要 TimeManagerCreate(&TimeManagerForAll);
RtcTimeGet = TimeRegObjCreate(GetRtcYyMmDdHhMmSs,400,&TimeManagerForAll);创建一个函数400ms调用一次
主循环里写上
TimeManagerScan(&TimeManagerForAll);
中断函数中写上
TimeManagerScanTimeMs(&TimeManagerForAll,100);//100ms的扫描频率。