个人嵌入式下编程思想---定时任务TimeManager

定时任务:有时候需要定时执行一些任务,刚毕业时候我一般在定时器中断写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的扫描频率。


猜你喜欢

转载自blog.csdn.net/qq_16711745/article/details/80314067
今日推荐