1. 重改定时器
2. 增加HList
This commit is contained in:
parent
fa9a7df818
commit
9cebbd2bc7
@ -140,6 +140,14 @@ uint8_t HDProtocolCurrSend(const void *data, int len);
|
||||
*/
|
||||
void HDProtocolSendPort(uint8_t dst, const void *data, int len);
|
||||
|
||||
/**
|
||||
* @brief 直接根据目标数据口发送(不等待回送的特殊接口)
|
||||
* @param dst 需要往那个目标数据口发送
|
||||
* @param data 发送数据
|
||||
* @param len 发送数据长度
|
||||
*/
|
||||
void HDProtocolDirectSendPort(uint8_t dst, const void *data, int len);
|
||||
|
||||
/**
|
||||
* @brief 临时路由发送(用于发送目标端口的数据后, 解析端临时更改目标端口, 通过 HDProtocolGetDest 获取目标端口)
|
||||
* @param src 发送源端口
|
||||
|
||||
108
include/HList.h
Normal file
108
include/HList.h
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 日期: 2026-04-01
|
||||
* 作者: coffee
|
||||
* 描述: 侵入式双向链表基础组件
|
||||
* 用法类似内核 list, 节点嵌入到用户结构体中
|
||||
*/
|
||||
|
||||
#ifndef _H_LIST_H_
|
||||
#define _H_LIST_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct HList {
|
||||
struct HList *next;
|
||||
struct HList *prev;
|
||||
} HList;
|
||||
|
||||
|
||||
#define HLIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define HLIST_HEAD(name) HList name = HLIST_HEAD_INIT(name)
|
||||
|
||||
#define HLIST_CONTAINER_OF(ptr, type, member) \
|
||||
((type *)((uint8_t *)(ptr) - offsetof(type, member)))
|
||||
|
||||
#define HLIST_ENTRY(ptr, type, member) \
|
||||
HLIST_CONTAINER_OF(ptr, type, member)
|
||||
|
||||
#define HLIST_FIRST_ENTRY(head, type, member) \
|
||||
HLIST_ENTRY((head)->next, type, member)
|
||||
|
||||
#define HLIST_LAST_ENTRY(head, type, member) \
|
||||
HLIST_ENTRY((head)->prev, type, member)
|
||||
|
||||
#define HLIST_FOR_EACH(pos, head) \
|
||||
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
||||
|
||||
#define HLIST_FOR_EACH_TYPE(pos, head) \
|
||||
for (HList *(pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
||||
|
||||
#define HLIST_FOR_EACH_SAFE(pos, n, head) \
|
||||
for ((pos) = (head)->next, (n) = (pos)->next; (pos) != (head); \
|
||||
(pos) = (n), (n) = (pos)->next)
|
||||
|
||||
#define HLIST_FOR_EACH_SAFE_TYPE(pos, n, head) \
|
||||
for (HList *(pos) = (head)->next, (n) = (pos)->next; (pos) != (head); \
|
||||
(pos) = (n), (n) = (pos)->next)
|
||||
|
||||
|
||||
/**
|
||||
* @brief 初始化链表头或节点
|
||||
*/
|
||||
void HListInit(HList *list);
|
||||
|
||||
/**
|
||||
* @brief 判断节点是否已经独立初始化
|
||||
*/
|
||||
uint8_t HListIsSelf(const HList *list);
|
||||
|
||||
/**
|
||||
* @brief 判断链表是否为空
|
||||
*/
|
||||
uint8_t HListEmpty(const HList *head);
|
||||
|
||||
/**
|
||||
* @brief 获取链表节点数量
|
||||
*/
|
||||
size_t HListLen(const HList *head);
|
||||
|
||||
/**
|
||||
* @brief 头插
|
||||
*/
|
||||
void HListAdd(HList *node, HList *head);
|
||||
|
||||
/**
|
||||
* @brief 尾插
|
||||
*/
|
||||
void HListAddTail(HList *node, HList *head);
|
||||
|
||||
/**
|
||||
* @brief 删除节点, 删除后节点会重新初始化成独立状态
|
||||
*/
|
||||
void HListDel(HList *node);
|
||||
|
||||
/**
|
||||
* @brief 替换节点
|
||||
*/
|
||||
void HListReplace(HList *oldNode, HList *newNode);
|
||||
|
||||
/**
|
||||
* @brief 移动节点到目标链表头部
|
||||
*/
|
||||
void HListMove(HList *node, HList *head);
|
||||
|
||||
/**
|
||||
* @brief 移动节点到目标链表尾部
|
||||
*/
|
||||
void HListMoveTail(HList *node, HList *head);
|
||||
|
||||
/**
|
||||
* @brief 弹出头节点
|
||||
* @return 成功返回节点指针, 空链表返回 NULL
|
||||
*/
|
||||
HList *HListPop(HList *head);
|
||||
|
||||
#endif // _H_LIST_H_
|
||||
@ -10,15 +10,11 @@
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 定时器注册最大数量
|
||||
#ifndef HTIMER_REGISTER_MAX
|
||||
#define HTIMER_REGISTER_MAX (5)
|
||||
#endif
|
||||
#include "HList.h"
|
||||
|
||||
// 无效值
|
||||
#ifndef HTIMER_INVALID
|
||||
#define HTIMER_INVALID -1
|
||||
#define HTIMER_INVALID (NULL)
|
||||
#endif
|
||||
|
||||
// 检查添加定时任务超出限制后进入死循环, 方便调试
|
||||
@ -38,21 +34,28 @@ typedef enum
|
||||
} eHTimerFlags;
|
||||
|
||||
typedef void (*HTimerCallType)();
|
||||
typedef int16_t HTimer_t;
|
||||
typedef void * HTimer_t;
|
||||
|
||||
///< 注册的定时器信息, 定义为数组, 数量由外部控制
|
||||
typedef struct HTimerInfo {
|
||||
uint32_t flags : 1; ///< 定时器标志, eTimerFlags
|
||||
volatile uint32_t enable: 2; ///< 定时器使能
|
||||
uint32_t curr : 1; ///< 当前回调者
|
||||
uint32_t duration : 28; ///< 定时触发时长, 毫秒为计数单元
|
||||
uint32_t duration : 31; ///< 定时触发时长, 毫秒为计数单元
|
||||
uint32_t lastTime; ///< 上次触发时间
|
||||
HTimerCallType call; ///< 定时触发函数
|
||||
#if HTIMER_USE_USERDATA
|
||||
long userData; ///< 用户数据
|
||||
#endif
|
||||
HList node; ///< 定时器节点
|
||||
uint8_t id; ///< 定时器ID
|
||||
} HTimerInfo;
|
||||
|
||||
typedef struct TimeRegisterInfo {
|
||||
HList workNode; ///< 工作节点
|
||||
HList idleNode; ///< 空闲节点
|
||||
#if HTIMER_USE_USERDATA
|
||||
HList *currNode; ///< 当前节点
|
||||
#endif
|
||||
} TimeRegisterInfo;
|
||||
|
||||
///< 初始化毫秒定时器, 需要传递获取毫秒的函数
|
||||
void HTimerInitMs(uint32_t (*func)(void));
|
||||
@ -61,7 +64,14 @@ void HTimerInitMs(uint32_t (*func)(void));
|
||||
uint32_t HTimerGetMs();
|
||||
|
||||
/**
|
||||
* @brief 注册定时器信息
|
||||
* @brief 注册定时器注册列表信息内存(外部提供数组)
|
||||
* @param info 定时器注册信息
|
||||
* @param len 定时器个数
|
||||
*/
|
||||
void HTimerInitRegister(TimeRegisterInfo *info, uint8_t len);
|
||||
|
||||
/**
|
||||
* @brief 注册定时器信息(外部提供定时器数组)
|
||||
* @param id 定时器ID
|
||||
* @param info 定时器信息, 由外部提供定时器数组
|
||||
* @param infoLen 定时器信息长度
|
||||
@ -69,24 +79,15 @@ uint32_t HTimerGetMs();
|
||||
*/
|
||||
uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen);
|
||||
|
||||
///< 移除定时器信息
|
||||
void HTimerRemoveRegister(uint8_t id);
|
||||
|
||||
///< 运行定时器可执行任务, 需要在主循环中调用
|
||||
void HTimerRun(uint8_t id);
|
||||
|
||||
///< 添加一个定时任务, 添加失败返回 HTIMER_INVALID, ms不超过24比特
|
||||
///< 添加一个定时任务, 添加失败返回 HTIMER_INVALID, ms不超过31比特
|
||||
HTimer_t HTimerAdd(uint8_t id, uint32_t ms, HTimerCallType call, eHTimerFlags flags);
|
||||
|
||||
///< 移除一个定时任务
|
||||
void HTimerRemove(HTimer_t index);
|
||||
|
||||
///< 在定时器回调任务中获取当前定时器ID
|
||||
uint8_t HTimerGetCurrentId();
|
||||
|
||||
///< 在定时器回调任务中获取当前定时器调用者索引, 不存在返回 HTIMER_INVALID
|
||||
HTimer_t HTimerGetCurrentCaller(uint8_t id);
|
||||
|
||||
#if HTIMER_USE_USERDATA
|
||||
///< 设置定时器用户数据
|
||||
void HTimerSetUserData(HTimer_t index, long data);
|
||||
@ -94,12 +95,13 @@ void HTimerSetUserData(HTimer_t index, long data);
|
||||
///< 获取定时器用户数据, 不存在返回 0
|
||||
long HTimerGetUserData(HTimer_t index);
|
||||
|
||||
///< 定时器回调时, 获取对应的定时器用户数据, 不存在返回 0
|
||||
long HTimerGetCurrCallUserData();
|
||||
///< 获取当前调用定时器的用户数据
|
||||
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() { return 0; }
|
||||
static inline long HTimerGetCurrCallUserData(uint8_t id) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif //__H_TIMER_H__
|
||||
|
||||
@ -301,6 +301,24 @@ void HDProtocolSendPort(uint8_t dst, const void *data, int len)
|
||||
sInfo.writeCall(&sInfo.info[dst], (const uint8_t *)data, len);
|
||||
}
|
||||
|
||||
void HDProtocolDirectSendPort(uint8_t dst, const void *data, int len)
|
||||
{
|
||||
if (data == NULL || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sInfo.writeCall == NULL || sInfo.info == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dst >= sInfo.infoLen) {
|
||||
LogE("index[%d] is out of range[%d]", dst, sInfo.infoLen);
|
||||
return;
|
||||
}
|
||||
|
||||
sInfo.writeCall(&sInfo.info[dst], (const uint8_t *)data, len);
|
||||
}
|
||||
|
||||
void HDProtocolTmpSend(uint8_t src, uint8_t feedbackRoute, const void *data, int len, uint8_t needReadCount, uint8_t waitCount)
|
||||
{
|
||||
if (data == NULL || len == 0) {
|
||||
|
||||
128
src/HList.c
Normal file
128
src/HList.c
Normal file
@ -0,0 +1,128 @@
|
||||
/**
|
||||
* 日期: 2026-04-01
|
||||
* 作者: coffee
|
||||
* 描述: 侵入式双向链表实现
|
||||
*/
|
||||
|
||||
#include "HList.h"
|
||||
|
||||
|
||||
static void __HListAdd(HList *node, HList *prev, HList *next) {
|
||||
next->prev = node;
|
||||
node->next = next;
|
||||
node->prev = prev;
|
||||
prev->next = node;
|
||||
}
|
||||
|
||||
static void __HListDel(HList *prev, HList *next) {
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
void HListInit(HList *list) {
|
||||
if (list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
uint8_t HListIsSelf(const HList *list) {
|
||||
if (list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (list->next == list && list->prev == list) ? 1u : 0u;
|
||||
}
|
||||
|
||||
uint8_t HListEmpty(const HList *head) {
|
||||
if (head == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (head->next == head) ? 1u : 0u;
|
||||
}
|
||||
|
||||
size_t HListLen(const HList *head) {
|
||||
size_t len = 0;
|
||||
const HList *pos;
|
||||
|
||||
if (head == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (pos = head->next; pos != head; pos = pos->next) {
|
||||
++len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void HListAdd(HList *node, HList *head) {
|
||||
if (node == NULL || head == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
__HListAdd(node, head, head->next);
|
||||
}
|
||||
|
||||
void HListAddTail(HList *node, HList *head) {
|
||||
if (node == NULL || head == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
__HListAdd(node, head->prev, head);
|
||||
}
|
||||
|
||||
void HListDel(HList *node) {
|
||||
if (node == NULL || node->next == NULL || node->prev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
__HListDel(node->prev, node->next);
|
||||
HListInit(node);
|
||||
}
|
||||
|
||||
void HListReplace(HList *oldNode, HList *newNode) {
|
||||
if (oldNode == NULL || newNode == NULL ||
|
||||
oldNode->next == NULL || oldNode->prev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
newNode->next = oldNode->next;
|
||||
newNode->next->prev = newNode;
|
||||
newNode->prev = oldNode->prev;
|
||||
newNode->prev->next = newNode;
|
||||
HListInit(oldNode);
|
||||
}
|
||||
|
||||
void HListMove(HList *node, HList *head) {
|
||||
if (node == NULL || head == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
HListDel(node);
|
||||
HListAdd(node, head);
|
||||
}
|
||||
|
||||
void HListMoveTail(HList *node, HList *head) {
|
||||
if (node == NULL || head == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
HListDel(node);
|
||||
HListAddTail(node, head);
|
||||
}
|
||||
|
||||
HList *HListPop(HList *head) {
|
||||
HList *node;
|
||||
|
||||
if (HListEmpty(head)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = head->next;
|
||||
HListDel(node);
|
||||
return node;
|
||||
}
|
||||
289
src/HTimer.c
289
src/HTimer.c
@ -11,90 +11,102 @@
|
||||
|
||||
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)
|
||||
#define CHECK_VALUE (0x7FFFFFFF)
|
||||
|
||||
|
||||
struct __attribute__((packed)) TimeRegisterInfo {
|
||||
uint16_t enable : 1; ///< 定时器使能
|
||||
uint16_t curr : 1; ///< 当前定时器
|
||||
uint16_t len : 14; ///< 定时器个数
|
||||
HTimerInfo *timers; ///< 定时器
|
||||
struct __attribute__((packed)) TimerInfo {
|
||||
TimeRegisterInfo *info;
|
||||
uint8_t infoLen;
|
||||
};
|
||||
|
||||
static struct TimeRegisterInfo sTimeRegisters[HTIMER_REGISTER_MAX];
|
||||
static struct TimerInfo sInfo;
|
||||
|
||||
|
||||
static void CallTimer(uint8_t id, int16_t index) {
|
||||
if (id >= HTIMER_REGISTER_MAX) {
|
||||
static void InsertWorkNode(uint8_t id, HList *node) {
|
||||
if (id >= sInfo.infoLen) {
|
||||
LogD("error id[%d]", id);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= sTimeRegisters[id].len) {
|
||||
LogD("error index[%d], len[%d]", index, sTimeRegisters[id].len);
|
||||
HTimerInfo *info = HLIST_ENTRY(node, HTimerInfo, node);
|
||||
const uint32_t triggerTime = info->lastTime + info->duration;
|
||||
HList *entry = NULL;
|
||||
|
||||
HLIST_FOR_EACH(entry, &sInfo.info[id].workNode) {
|
||||
HTimerInfo *nodeInfo = HLIST_ENTRY(entry, HTimerInfo, node);
|
||||
if ((nodeInfo->lastTime + nodeInfo->duration) < triggerTime) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HListAddTail(node, entry);
|
||||
return;
|
||||
}
|
||||
|
||||
HListAddTail(node, entry);
|
||||
}
|
||||
|
||||
static void CallTimer(uint8_t id, HList *node) {
|
||||
if (id >= sInfo.infoLen) {
|
||||
LogD("error id[%d]", id);
|
||||
return ;
|
||||
}
|
||||
|
||||
sTimeRegisters[id].curr = 1;
|
||||
sTimeRegisters[id].timers[index].curr = 1;
|
||||
if (sTimeRegisters[id].timers[index].flags == kHTimerOnce) {
|
||||
sTimeRegisters[id].timers[index].enable = 0;
|
||||
#if HTIMER_USE_USERDATA
|
||||
sInfo.info[id].currNode = node;
|
||||
#endif
|
||||
HTimerInfo *info = HLIST_ENTRY(node, HTimerInfo, node);
|
||||
if (info->call) {
|
||||
info->call();
|
||||
}
|
||||
#if HTIMER_USE_USERDATA
|
||||
sInfo.info[id].currNode = NULL;
|
||||
#endif
|
||||
|
||||
info->lastTime = GetCurrentMs();
|
||||
if (!HListIsSelf(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sTimeRegisters[id].timers[index].call();
|
||||
sTimeRegisters[id].curr = 0;
|
||||
sTimeRegisters[id].timers[index].curr = 0;
|
||||
sTimeRegisters[id].timers[index].lastTime = GetCurrentMs();
|
||||
// 如果是单次的, 直接移动到空闲队列, 循环的, 按触发时间重新插入工作队列
|
||||
if (info->flags == kHTimerOnce) {
|
||||
HListAddTail(node, &sInfo.info[id].idleNode);
|
||||
} else {
|
||||
InsertWorkNode(id, node);
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call, eHTimerFlags flags) {
|
||||
static HList * 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) {
|
||||
if (id >= sInfo.infoLen) {
|
||||
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;
|
||||
#if HTIMER_USE_USERDATA
|
||||
sTimeRegisters[id].timers[i].userData = 0;
|
||||
#endif
|
||||
return CREATE_INDEX(id, i);
|
||||
HList *node = HListPop(&sInfo.info[id].idleNode);
|
||||
if (node == NULL) {
|
||||
LogD("timers full, id[%d], duration[%d], flags[%d]", id, duration, flags);
|
||||
return HTIMER_INVALID;
|
||||
}
|
||||
|
||||
LogD("timers full, id[%d], duration[%d], flags[%d]", id, duration, flags);
|
||||
return HTIMER_INVALID;
|
||||
HTimerInfo *info = HLIST_ENTRY(node, HTimerInfo, node);
|
||||
info->duration = duration;
|
||||
info->lastTime = GetCurrentMs();
|
||||
info->call = call;
|
||||
info->flags = flags;
|
||||
#if HTIMER_USE_USERDATA
|
||||
info->userData = 0;
|
||||
#endif
|
||||
|
||||
InsertWorkNode(id, node);
|
||||
return node;
|
||||
}
|
||||
|
||||
void HTimerInitMs(uint32_t (*func)(void)) {
|
||||
@ -109,32 +121,30 @@ uint32_t HTimerGetMs() {
|
||||
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;
|
||||
void HTimerInitRegister(TimeRegisterInfo *info, uint8_t len)
|
||||
{
|
||||
sInfo.info = info;
|
||||
sInfo.infoLen = len;
|
||||
for (uint8_t i = 0; i < len; ++i) {
|
||||
HListInit(&info[i].workNode);
|
||||
HListInit(&info[i].idleNode);
|
||||
}
|
||||
|
||||
if (sTimeRegisters[id].enable == 1) {
|
||||
LogD("id[%d] already register", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(info, 0, infoLen);
|
||||
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 ;
|
||||
uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen) {
|
||||
if (id >= sInfo.infoLen) {
|
||||
LogD("error id[%d], max[%d]", id, sInfo.infoLen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sTimeRegisters[id].enable = 0;
|
||||
sTimeRegisters[id].len = 0;
|
||||
sTimeRegisters[id].timers = 0;
|
||||
memset(info, 0, sizeof(*info) * infoLen);
|
||||
for (uint16_t i = 0; i < infoLen; ++i) {
|
||||
info[i].id = id;
|
||||
HListInit(&info[i].node);
|
||||
HListAddTail(&info[i].node, &sInfo.info[id].idleNode);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void HTimerRun(uint8_t id) {
|
||||
@ -142,38 +152,33 @@ void HTimerRun(uint8_t id) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (id >= HTIMER_REGISTER_MAX) {
|
||||
if (id >= sInfo.infoLen) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (sTimeRegisters[id].enable == 0) {
|
||||
// 检查是否有任务
|
||||
if (HListEmpty(&sInfo.info[id].workNode)) {
|
||||
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;
|
||||
HList readyNode;
|
||||
HListInit(&readyNode);
|
||||
// 工作队列按触发时间有序, 只需要连续取出队头的就绪任务
|
||||
while (!HListEmpty(&sInfo.info[id].workNode)) {
|
||||
HTimerInfo *info = HLIST_FIRST_ENTRY(&sInfo.info[id].workNode, HTimerInfo, node);
|
||||
uint32_t diff = GetCurrentMs() - info->lastTime;
|
||||
uint32_t timeDuration = info->duration;
|
||||
if (diff < timeDuration) {
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
CallTimer(id, i);
|
||||
HListMoveTail(&info->node, &readyNode);
|
||||
}
|
||||
|
||||
// 执行就绪队列
|
||||
while (!HListEmpty(&readyNode)) {
|
||||
HList *node = HListPop(&readyNode);
|
||||
CallTimer(id, node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,47 +199,9 @@ void HTimerRemove(HTimer_t index) {
|
||||
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;
|
||||
HTimerInfo *info = HLIST_ENTRY(index, HTimerInfo, node);
|
||||
HListDel(&info->node);
|
||||
HListAddTail(&info->node, &sInfo.info[info->id].idleNode);
|
||||
}
|
||||
|
||||
#if HTIMER_USE_USERDATA
|
||||
@ -244,19 +211,8 @@ void HTimerSetUserData(HTimer_t index, long data)
|
||||
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].userData = data;
|
||||
HTimerInfo *info = HLIST_ENTRY(index, HTimerInfo, node);
|
||||
info->userData = data;
|
||||
}
|
||||
|
||||
long HTimerGetUserData(HTimer_t index)
|
||||
@ -265,25 +221,22 @@ long HTimerGetUserData(HTimer_t index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t id = GET_ID(index);
|
||||
index = GET_INDEX(index);
|
||||
if (id >= HTIMER_REGISTER_MAX) {
|
||||
LogD("error id[%d]", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= sTimeRegisters[id].len) {
|
||||
LogD("error index[%d]", index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sTimeRegisters[id].timers[index].userData;
|
||||
HTimerInfo *info = HLIST_ENTRY(index, HTimerInfo, node);
|
||||
return info->userData;
|
||||
}
|
||||
|
||||
long HTimerGetCurrCallUserData()
|
||||
long HTimerGetCurrCallUserData(uint8_t id)
|
||||
{
|
||||
HTimer_t index = HTimerGetCurrentCaller(HTimerGetCurrentId());
|
||||
return HTimerGetUserData(index);
|
||||
}
|
||||
#endif
|
||||
if (id >= sInfo.infoLen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sInfo.info[id].currNode == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HTimerInfo *info = HLIST_ENTRY(sInfo.info[id].currNode, HTimerInfo, node);
|
||||
return info->userData;
|
||||
}
|
||||
|
||||
#endif // HTIMER_USE_USERDATA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user