在单片机裸机开发中,通常延时功能函数是以同步阻塞方式实现,的确在很多设备驱动中需要同步阻塞来匹配硬件时序,但这只能存在于硬件驱动层,应用层开发时使用阻塞延时便大大降低了系统实时性和安全性,不可预测就是一块心病。为此我分享出一段由朋友:流星原创的event_delay异步延时方案。使用此库便可以给N个函数增加指定延时时间,异步非阻塞方式,数据结构简单,合作式调度方式。另:此代码已在很多实体项目中使用,稳定安全。
以下为C文件:
#include "main.h"
#include "event_delay.h"
EventDelay_TypeDef Event[EVENT_MAX_NUM];
u8 event_num = 0;
/*添加功能和延时*/
void Event_Add(event_type event,void *point,u16 time)
{
if(event_num < EVENT_MAX_NUM)
{
Event[event_num].event = event;
Event[event_num].DelayTime = time;
Event[event_num].Time = time;
Event[event_num].Point = point;
event_num++;
}
}
/*定时调用*/
void Event_TimeTick(void)
{
static u8 event_num_now = 0;
Event[event_num_now].Time--;
if(Event[event_num_now].Time == 0)
{
Event[event_num_now].Run++;
event_num_now++;
if(event_num_now >= event_num)
event_num_now = 0;
Event[event_num_now].Time = Event[event_num_now].DelayTime;
}
}
/*主循环运行*/
void Event_Run(void)
{
for(u16 i = 0;i < event_num;i++){
if(Event[i].Run){
Event[i].Run --;
Event[i].event(Event[i].Point);
}
}
}
以下为H文件:
#ifndef __EVEN_DELAY__H__
#define __EVEN_DELAY__H__
#include "main.h"
#define EVENT_MAX_NUM 10
typedef void (*event_type)(void *);
typedef struct
{
event_type event;
void *Point;
u16 DelayTime;
u16 Time;
u16 Run;
}EventDelay_TypeDef;
extern void Event_Add(event_type event,void *point,u16 time);
extern void Event_TimeTick(void);
extern void Event_Run(void);
#endif
这个库源码也就几十行,数据结构不复杂,傻瓜式的代码逻辑,非常好移植到自己的单片机工程中。当然这也是嵌入式中比较常用的调度方式,我在个人开发的多线程核中也使用了类似的调度器,目前已经实现了多线程机制,也已成功做出了增删任务的API,在实现了CPU资源回收机制后就将源码放出。届时还烦请广大网友实际测试反馈BUG。
感恩,感谢... ...
使用过程中出现任何BUG请联系我本人QQ:951253606,说明bug现象以及重现过程。
寻求MCU产品开发请联系我本人QQ:951253606。