/** * 日期: 2025-03-08 * 作者: coffee * 描述: 毫秒级定时器, 最小堆实现 */ #ifndef __H_TIMER_H__ #define __H_TIMER_H__ #include // 无效值 #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; ///< 需要重新调度 (原子操作) } 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__