117 lines
3.3 KiB
C
117 lines
3.3 KiB
C
/**
|
|
* 日期: 2025-03-08
|
|
* 作者: coffee
|
|
* 描述: 毫秒级定时器, 最小堆实现
|
|
*/
|
|
|
|
|
|
#ifndef __H_TIMER_H__
|
|
#define __H_TIMER_H__
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
// 无效值
|
|
#ifndef HTIMER_INVALID
|
|
#define HTIMER_INVALID (-1)
|
|
#endif
|
|
|
|
// 定时器长度/索引类型,方便统一修改
|
|
typedef uint8_t HTimerLen_t;
|
|
#define HTIMER_LEN_MAX UINT8_MAX
|
|
|
|
// 检查添加定时任务超出限制后进入死循环, 方便调试
|
|
#ifdef HTIMER_CHECK_LOOP
|
|
#define HTIMER_CHECK_INVALID_LOOP
|
|
#endif
|
|
|
|
// 是否使用用户数据
|
|
#ifndef HTIMER_USE_USERDATA
|
|
#define HTIMER_USE_USERDATA 0
|
|
#endif
|
|
|
|
typedef enum
|
|
{
|
|
kHTimerOnce = 0, ///< 仅执行一次
|
|
kHTimerLoop, ///< 循环执行
|
|
} eHTimerFlags;
|
|
|
|
typedef void (*HTimerCallType)();
|
|
typedef int16_t HTimer_t;
|
|
|
|
///< 定时器信息
|
|
typedef struct HTimerInfo {
|
|
uint32_t flags : 1; ///< 定时器标志, eHTimerFlags
|
|
uint32_t curr : 1; ///< 当前回调者
|
|
uint32_t duration : 28; ///< 定时触发时长, 毫秒为计数单元
|
|
|
|
volatile uint8_t state; ///< 定时器状态 (内部使用, 原子操作)
|
|
HTimerLen_t heapIndex; ///< 堆索引, HTIMER_LEN_MAX 表示不在堆中
|
|
HTimerLen_t heapMem; ///< 堆内存, 提供给最小堆使用
|
|
|
|
uint32_t lastTime; ///< 上次触发时间
|
|
HTimerCallType call; ///< 定时触发函数
|
|
|
|
#if HTIMER_USE_USERDATA
|
|
long userData; ///< 用户数据
|
|
#endif
|
|
} HTimerInfo;
|
|
|
|
///< 定时器注册信息
|
|
typedef struct TimeRegisterInfo {
|
|
HTimerInfo *timers; ///< 定时器信息数组
|
|
HTimerLen_t heapSize; ///< 堆当前大小
|
|
HTimerLen_t len; ///< 定时器个数
|
|
volatile uint8_t schedu; ///< 需要重新调度 (原子操作)
|
|
uint8_t run : 1; ///< 运行中
|
|
} TimeRegisterInfo;
|
|
|
|
///< 初始化毫秒定时器, 需要传递获取毫秒的函数
|
|
void HTimerInitMs(uint32_t (*func)(void));
|
|
|
|
///< 获取毫秒
|
|
uint32_t HTimerGetMs();
|
|
|
|
/**
|
|
* @brief 注册定时器注册列表信息内存
|
|
* @param info 定时器注册信息数组
|
|
* @param len 定时器个数
|
|
*/
|
|
void HTimerInitRegister(TimeRegisterInfo *info, HTimerLen_t len);
|
|
|
|
/**
|
|
* @brief 注册定时器信息
|
|
* @param id 定时器ID
|
|
* @param info 定时器信息数组
|
|
* @param infoLen 定时器信息长度
|
|
* @return 1成功 0失败
|
|
*/
|
|
uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen);
|
|
|
|
///< 运行定时器可执行任务, 需要在主循环中调用
|
|
void HTimerRun(uint8_t id);
|
|
|
|
///< 添加一个定时任务, 添加失败返回 HTIMER_INVALID, ms不超过31比特
|
|
HTimer_t HTimerAdd(uint8_t id, uint32_t ms, HTimerCallType call, eHTimerFlags flags);
|
|
|
|
///< 移除一个定时任务
|
|
void HTimerRemove(HTimer_t index);
|
|
|
|
#if HTIMER_USE_USERDATA
|
|
///< 设置定时器用户数据
|
|
void HTimerSetUserData(HTimer_t index, long data);
|
|
|
|
///< 获取定时器用户数据, 不存在返回 0
|
|
long HTimerGetUserData(HTimer_t index);
|
|
|
|
///< 获取当前调用定时器的用户数据
|
|
long HTimerGetCurrCallUserData(uint8_t id);
|
|
|
|
#else
|
|
static inline void HTimerSetUserData(HTimer_t index, long data) { (void)index; (void)data; }
|
|
static inline long HTimerGetUserData(HTimer_t index) { (void)index; return 0; }
|
|
static inline long HTimerGetCurrCallUserData(uint8_t id) { (void)id; return 0; }
|
|
#endif
|
|
|
|
#endif //__H_TIMER_H__
|