HCoreBase/include/HTimer.h
2026-04-04 17:51:09 +08:00

109 lines
3.1 KiB
C

/**
* 日期: 2025-03-08
* 作者: coffee
* 描述: 毫秒级定时器, 添加即可使用, 定时器最大数量为 HTIMER_MAX
*/
#ifndef __H_TIMER_H__
#define __H_TIMER_H__
#include <stdint.h>
#include "HList.h"
// 无效值
#ifndef HTIMER_INVALID
#define HTIMER_INVALID (-1)
#endif
// 检查添加定时任务超出限制后进入死循环, 方便调试
#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; ///< 定时器标志, eTimerFlags
uint32_t enable : 2; ///< 定时器使能
uint32_t curr : 1; ///< 当前回调者
uint32_t duration : 28; ///< 定时触发时长, 毫秒为计数单元
uint32_t lastTime; ///< 上次触发时间
HTimerCallType call; ///< 定时触发函数
#if HTIMER_USE_USERDATA
long userData; ///< 用户数据
#endif
HList node; ///< 定时器节点
uint8_t id; ///< 定时器ID
} HTimerInfo;
typedef struct TimeRegisterInfo {
HList workNode; ///< 工作节点
HTimerInfo *timers; ///< 定时器信息
uint8_t schedu : 1; ///< 需要重新调度工作队列
uint8_t len : 7; ///< 定时器个数
} TimeRegisterInfo;
///< 初始化毫秒定时器, 需要传递获取毫秒的函数
void HTimerInitMs(uint32_t (*func)(void));
///< 获取毫秒
uint32_t HTimerGetMs();
/**
* @brief 注册定时器注册列表信息内存(外部提供数组)
* @param info 定时器注册信息
* @param len 定时器个数
*/
void HTimerInitRegister(TimeRegisterInfo *info, uint8_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) {}
static inline long HTimerGetUserData(HTimer_t index) { return 0; }
static inline long HTimerGetCurrCallUserData(uint8_t id) { return 0; }
#endif
#endif //__H_TIMER_H__