236 lines
5.8 KiB
C
236 lines
5.8 KiB
C
|
|
|
|
#include "HTimer.h"
|
|
#include "HDLog.h"
|
|
#include <string.h>
|
|
|
|
// 用于拷贝定时器文件使用可直接删除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;
|
|
}
|
|
|