#include "HTimer.h" #include "HDLog.h" #include // 用于拷贝定时器文件使用可直接删除HDLog.h文件避免依赖 #ifndef LogD #define LogD(...) #endif static uint32_t (*GetCurrentMs)(void); #define CHECK_VALUE (0x0FFFFFFF) #define CREATE_INDEX(id, index) ((id << 8) | index) #define GET_ID(index) ((index >> 8) & 0xFF) #define GET_INDEX(index) (index & 0xFF) struct __attribute__((packed)) TimeRegisterInfo { uint16_t enable : 1; ///< 定时器使能 uint16_t curr : 1; ///< 当前定时器 uint16_t len : 14; ///< 定时器个数 HTimerInfo *timers; ///< 定时器 }; static struct TimeRegisterInfo sTimeRegisters[HTIMER_REGISTER_MAX]; static void CallTimer(uint8_t id, int16_t index) { if (id >= HTIMER_REGISTER_MAX) { LogD("error id[%d]", id); return ; } if (index < 0 || index >= sTimeRegisters[id].len) { LogD("error index[%d], len[%d]", index, sTimeRegisters[id].len); return ; } sTimeRegisters[id].curr = 1; sTimeRegisters[id].timers[index].curr = 1; if (sTimeRegisters[id].timers[index].flags == kHTimerOnce) { sTimeRegisters[id].timers[index].enable = 0; } sTimeRegisters[id].timers[index].call(); sTimeRegisters[id].curr = 0; sTimeRegisters[id].timers[index].curr = 0; sTimeRegisters[id].timers[index].lastTime = GetCurrentMs(); } static int16_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call, eHTimerFlags flags) { if (!GetCurrentMs) { LogD("GetCurrentMs not init"); return HTIMER_INVALID; } if (id >= HTIMER_REGISTER_MAX) { LogD("error id[%d]", id); return HTIMER_INVALID; } if (sTimeRegisters[id].enable == 0) { LogD("not enable, id[%d]", id); return HTIMER_INVALID; } if ((duration & ~CHECK_VALUE) != 0) { LogD("duration overflow, duration[%d]", duration); return HTIMER_INVALID; } for (uint16_t i = 0; i < sTimeRegisters[id].len; ++i) { if (sTimeRegisters[id].timers[i].enable) { continue; } // 防中断导致数据重叠 sTimeRegisters[id].timers[i].enable = 1; if (sTimeRegisters[id].timers[i].enable != 1) { continue; } sTimeRegisters[id].timers[i].enable = 2; sTimeRegisters[id].timers[i].duration = duration; sTimeRegisters[id].timers[i].lastTime = GetCurrentMs(); sTimeRegisters[id].timers[i].call = call; sTimeRegisters[id].timers[i].flags = flags; return CREATE_INDEX(id, i); } LogD("timers full, id[%d], duration[%d], flags[%d]", id, duration, flags); return HTIMER_INVALID; } void HTimerInitMs(uint32_t (*func)(void)) { GetCurrentMs = func; } uint32_t HTimerGetMs() { if (!GetCurrentMs) { return 0; } return GetCurrentMs(); } uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen) { if (id >= HTIMER_REGISTER_MAX) { LogD("error id[%d], max[%d]", id, HTIMER_REGISTER_MAX); return 0; } if (sTimeRegisters[id].enable == 1) { LogD("id[%d] already register", id); return 0; } sTimeRegisters[id].timers = info; sTimeRegisters[id].len = infoLen; sTimeRegisters[id].enable = 1; return 1; } void HTimerRemoveRegister(uint8_t id) { if (id >= HTIMER_REGISTER_MAX) { return ; } sTimeRegisters[id].enable = 0; sTimeRegisters[id].len = 0; sTimeRegisters[id].timers = 0; } void HTimerRun(uint8_t id) { if (!GetCurrentMs) { return ; } if (id >= HTIMER_REGISTER_MAX) { return ; } if (sTimeRegisters[id].enable == 0) { return ; } if (sTimeRegisters[id].curr == 1) { return ; } // 没必要每次都扫描, 当时间更新时再检查 static uint32_t lastMs[HTIMER_REGISTER_MAX]; if (lastMs[id] == GetCurrentMs()) { return ; } lastMs[id] = GetCurrentMs(); for (uint16_t i = 0; i < sTimeRegisters[id].len; ++i) { if (sTimeRegisters[id].timers[i].enable == 0) { continue; } // 这里每次都获取最新时间是因为执行任务期间可能会导致时间变化 uint32_t diff = GetCurrentMs() - sTimeRegisters[id].timers[i].lastTime; uint32_t timeDuration = sTimeRegisters[id].timers[i].duration; if (diff < timeDuration) { continue; } CallTimer(id, i); } } HTimer_t HTimerAdd(uint8_t id, uint32_t ms, HTimerCallType call, eHTimerFlags flags) { #ifdef HTIMER_CHECK_INVALID_LOOP HTimer_t result = AddTimerData(id, ms, call, flags); if (result == HTIMER_INVALID) { while (1); } return result; #else return AddTimerData(id, ms, call, flags); #endif } void HTimerRemove(HTimer_t index) { if (index == HTIMER_INVALID) { return ; } const uint8_t id = GET_ID(index); index = GET_INDEX(index); if (id >= HTIMER_REGISTER_MAX) { LogD("error id[%d]", id); return ; } if (index < 0 || index >= sTimeRegisters[id].len) { LogD("error index[%d]", index); return ; } sTimeRegisters[id].timers[index].enable = 0; } uint8_t HTimerGetCurrentId() { for (uint8_t i = 0; i < HTIMER_REGISTER_MAX; ++i) { if (sTimeRegisters[i].curr == 1) { return i; } } return HTIMER_INVALID; } HTimer_t HTimerGetCurrentCaller(uint8_t id) { if (id >= HTIMER_REGISTER_MAX) { return HTIMER_INVALID; } if (sTimeRegisters[id].curr == 0) { return HTIMER_INVALID; } for (uint16_t i = 0; i < sTimeRegisters[id].len; ++i) { if (sTimeRegisters[id].timers[i].curr == 1) { return CREATE_INDEX(id, i); } } return HTIMER_INVALID; }