[重构] libtask 完整重写 + 全项目注释中文化
libtask 变更(对比原工程无功能遗漏):
- 定时器: timerfd + epoll 精确毫秒级(替代简单轮询)
- 事件: TASK_EVENT_FLAG_AND/OR/CLEAR, TASK_EVENT_WAIT_FOREVER
- 消息队列: 长度前缀存储, send/send_timeout/recv/try_recv
- 引用计数: task_event/timer/msgq 安全析构
- 新增 task_sleep_ms 通用延时函数
- 回调类型修正为 void(*)(void*)
注释中文化:
- myBase.h/list.h/myMd5.h/myLog.h → 全部中文
- myFunc.c 节标题 → 中文
- myTask.h/c → 全部中文注释
风格修复:
- 一行一语句, {} 独占行, } 后空行, return 前空行
- 运算符前后空格, 逗号分号后空格
This commit is contained in:
parent
f2a099e4b9
commit
2a692cada5
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* @file list.h
|
* @file list.h
|
||||||
* @brief 内核风格侵入式双向循环链表(纯头文件,C/C++ 兼容)
|
* @brief Linux 内核风格侵入式双向循环链表(纯头文件,C/C++ 兼容)
|
||||||
*
|
* @details 将 struct list_head 嵌入宿主结构体,通过 list_entry 取回宿主指针。
|
||||||
* 用法:将 struct list_head 嵌入你的结构体,通过 list_entry 取回宿主指针。
|
* 所有操作 O(1),遍历 O(n)。
|
||||||
* 所有操作 O(1),遍历 O(n)。C++ 兼容:不用 new/class/typeof 等关键字。
|
* C++ 兼容:变量名不使用 new/class/typeof 等关键字。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIST_H_
|
#ifndef _LIST_H_
|
||||||
|
|
@ -16,7 +16,7 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---- 节点 ---- */
|
/* ---- 链表节点 ---- */
|
||||||
struct list_head
|
struct list_head
|
||||||
{
|
{
|
||||||
struct list_head *next;
|
struct list_head *next;
|
||||||
|
|
@ -27,13 +27,16 @@ struct list_head
|
||||||
#define LIST_HEAD_INIT(n) { &(n), &(n) }
|
#define LIST_HEAD_INIT(n) { &(n), &(n) }
|
||||||
#define LIST_HEAD(n) struct list_head n = LIST_HEAD_INIT(n)
|
#define LIST_HEAD(n) struct list_head n = LIST_HEAD_INIT(n)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 运行时初始化链表头
|
||||||
|
*/
|
||||||
static inline void INIT_LIST_HEAD(struct list_head *h)
|
static inline void INIT_LIST_HEAD(struct list_head *h)
|
||||||
{
|
{
|
||||||
h->next = h;
|
h->next = h;
|
||||||
h->prev = h;
|
h->prev = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 内部:在 prev 和 next 之间插入 node ---- */
|
/* ---- 内部辅助:在 prev 和 next 之间插入 node ---- */
|
||||||
static inline void __list_add(struct list_head *node,
|
static inline void __list_add(struct list_head *node,
|
||||||
struct list_head *prev,
|
struct list_head *prev,
|
||||||
struct list_head *next)
|
struct list_head *next)
|
||||||
|
|
@ -44,7 +47,7 @@ static inline void __list_add(struct list_head *node,
|
||||||
prev->next = node;
|
prev->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 内部:删除 prev 和 next 之间的节点 ---- */
|
/* ---- 内部辅助:移除 prev 和 next 之间的节点 ---- */
|
||||||
static inline void __list_del(struct list_head *prev,
|
static inline void __list_del(struct list_head *prev,
|
||||||
struct list_head *next)
|
struct list_head *next)
|
||||||
{
|
{
|
||||||
|
|
@ -52,43 +55,54 @@ static inline void __list_del(struct list_head *prev,
|
||||||
prev->next = next;
|
prev->next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 添加 ---- */
|
/* ---- 添加操作 ---- */
|
||||||
|
|
||||||
|
/** 头插法:插入到 head 之后(作为第一个元素) */
|
||||||
static inline void list_add(struct list_head *node, struct list_head *head)
|
static inline void list_add(struct list_head *node, struct list_head *head)
|
||||||
{
|
{
|
||||||
__list_add(node, head, head->next);
|
__list_add(node, head, head->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 尾插法:插入到 head 之前(作为最后一个元素) */
|
||||||
static inline void list_add_tail(struct list_head *node, struct list_head *head)
|
static inline void list_add_tail(struct list_head *node, struct list_head *head)
|
||||||
{
|
{
|
||||||
__list_add(node, head->prev, head);
|
__list_add(node, head->prev, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 删除 ---- */
|
/* ---- 删除操作 ---- */
|
||||||
|
|
||||||
|
/** 从链表移除节点(不释放内存) */
|
||||||
static inline void list_del(struct list_head *e)
|
static inline void list_del(struct list_head *e)
|
||||||
{
|
{
|
||||||
__list_del(e->prev, e->next);
|
__list_del(e->prev, e->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 移除并重新初始化节点(安全删除,防止悬空指针) */
|
||||||
static inline void list_del_init(struct list_head *e)
|
static inline void list_del_init(struct list_head *e)
|
||||||
{
|
{
|
||||||
__list_del(e->prev, e->next);
|
__list_del(e->prev, e->next);
|
||||||
INIT_LIST_HEAD(e);
|
INIT_LIST_HEAD(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 移动 ---- */
|
/* ---- 移动操作 ---- */
|
||||||
|
|
||||||
|
/** 将节点移动到新链表头部 */
|
||||||
static inline void list_move(struct list_head *l, struct list_head *h)
|
static inline void list_move(struct list_head *l, struct list_head *h)
|
||||||
{
|
{
|
||||||
__list_del(l->prev, l->next);
|
__list_del(l->prev, l->next);
|
||||||
list_add(l, h);
|
list_add(l, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 将节点移动到新链表尾部 */
|
||||||
static inline void list_move_tail(struct list_head *l, struct list_head *h)
|
static inline void list_move_tail(struct list_head *l, struct list_head *h)
|
||||||
{
|
{
|
||||||
__list_del(l->prev, l->next);
|
__list_del(l->prev, l->next);
|
||||||
list_add_tail(l, h);
|
list_add_tail(l, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 替换 ---- */
|
/* ---- 替换操作 ---- */
|
||||||
|
|
||||||
|
/** 用 node 替换 old */
|
||||||
static inline void list_replace(struct list_head *old, struct list_head *node)
|
static inline void list_replace(struct list_head *old, struct list_head *node)
|
||||||
{
|
{
|
||||||
node->next = old->next;
|
node->next = old->next;
|
||||||
|
|
@ -97,6 +111,7 @@ static inline void list_replace(struct list_head *old, struct list_head *node)
|
||||||
node->prev->next = node;
|
node->prev->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 替换后初始化被替换节点 */
|
||||||
static inline void list_replace_init(struct list_head *old,
|
static inline void list_replace_init(struct list_head *old,
|
||||||
struct list_head *node)
|
struct list_head *node)
|
||||||
{
|
{
|
||||||
|
|
@ -104,43 +119,56 @@ static inline void list_replace_init(struct list_head *old,
|
||||||
INIT_LIST_HEAD(old);
|
INIT_LIST_HEAD(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 判断 ---- */
|
/* ---- 判断操作 ---- */
|
||||||
|
|
||||||
|
/** 判断链表是否为空 */
|
||||||
static inline int list_empty(const struct list_head *h)
|
static inline int list_empty(const struct list_head *h)
|
||||||
{
|
{
|
||||||
return h->next == h;
|
return h->next == h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 判断节点是否已链入链表 */
|
||||||
static inline int list_is_linked(const struct list_head *e)
|
static inline int list_is_linked(const struct list_head *e)
|
||||||
{
|
{
|
||||||
return e->next != e;
|
return e->next != e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 宿主指针 ---- */
|
/* ---- 节点 ↔ 宿主指针转换 ---- */
|
||||||
|
|
||||||
|
/** 从链表节点指针取回宿主结构体指针 */
|
||||||
#define list_entry(ptr, type, member) \
|
#define list_entry(ptr, type, member) \
|
||||||
((type *)((char *)(ptr) - offsetof(type, member)))
|
((type *)((char *)(ptr) - offsetof(type, member)))
|
||||||
|
|
||||||
|
/** 获取第一个宿主元素 */
|
||||||
#define list_first_entry(h, type, member) \
|
#define list_first_entry(h, type, member) \
|
||||||
list_entry((h)->next, type, member)
|
list_entry((h)->next, type, member)
|
||||||
|
|
||||||
|
/** 获取最后一个宿主元素 */
|
||||||
#define list_last_entry(h, type, member) \
|
#define list_last_entry(h, type, member) \
|
||||||
list_entry((h)->prev, type, member)
|
list_entry((h)->prev, type, member)
|
||||||
|
|
||||||
|
/** 安全获取第一个元素(链表空返回 NULL) */
|
||||||
#define list_first_entry_or_null(h, type, member) \
|
#define list_first_entry_or_null(h, type, member) \
|
||||||
(list_empty(h) ? NULL : list_first_entry(h, type, member))
|
(list_empty(h) ? NULL : list_first_entry(h, type, member))
|
||||||
|
|
||||||
/* ---- 遍历 ---- */
|
/* ---- 遍历操作 ---- */
|
||||||
|
|
||||||
|
/** 遍历链表节点(仅获取 struct list_head 指针) */
|
||||||
#define list_for_each(pos, head) \
|
#define list_for_each(pos, head) \
|
||||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||||
|
|
||||||
|
/** 安全遍历节点(可在遍历中删除 pos) */
|
||||||
#define list_for_each_safe(pos, n, head) \
|
#define list_for_each_safe(pos, n, head) \
|
||||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||||
pos = n, n = pos->next)
|
pos = n, n = pos->next)
|
||||||
|
|
||||||
|
/** 遍历宿主元素 */
|
||||||
#define list_for_each_entry(pos, head, member) \
|
#define list_for_each_entry(pos, head, member) \
|
||||||
for (pos = list_first_entry(head, __typeof__(*pos), member); \
|
for (pos = list_first_entry(head, __typeof__(*pos), member); \
|
||||||
&pos->member != (head); \
|
&pos->member != (head); \
|
||||||
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
||||||
|
|
||||||
|
/** 安全遍历宿主元素(可在遍历中删除 pos) */
|
||||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||||
for (pos = list_first_entry(head, __typeof__(*pos), member), \
|
for (pos = list_first_entry(head, __typeof__(*pos), member), \
|
||||||
n = list_entry(pos->member.next, __typeof__(*pos), member); \
|
n = list_entry(pos->member.next, __typeof__(*pos), member); \
|
||||||
|
|
@ -148,7 +176,9 @@ static inline int list_is_linked(const struct list_head *e)
|
||||||
pos = n, \
|
pos = n, \
|
||||||
n = list_entry(n->member.next, __typeof__(*n), member))
|
n = list_entry(n->member.next, __typeof__(*n), member))
|
||||||
|
|
||||||
/* ---- 拼接 ---- */
|
/* ---- 拼接操作 ---- */
|
||||||
|
|
||||||
|
/** 将 src 链表拼接到 dst 头部,src 被清空 */
|
||||||
static inline void list_splice_init(struct list_head *src,
|
static inline void list_splice_init(struct list_head *src,
|
||||||
struct list_head *dst)
|
struct list_head *dst)
|
||||||
{
|
{
|
||||||
|
|
@ -169,4 +199,5 @@ static inline void list_splice_init(struct list_head *src,
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif /* _LIST_H_ */
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
/**
|
/**
|
||||||
* @file myBase.h
|
* @file myBase.h
|
||||||
* @brief Public base definitions — shared macros, types, constants
|
* @brief 公共基础定义 — 所有模块共享的宏、类型、常量
|
||||||
* @details Written from scratch, functionally aligned with RTU original.
|
* @details 从零编写,功能对齐 RTU 原工程。
|
||||||
|
* 包含:终端颜色、字节序转换、数据类型常量等。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_BASE_H_
|
#ifndef _MY_BASE_H_
|
||||||
|
|
@ -22,7 +23,7 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* === Terminal colors === */
|
/* === 终端颜色码 === */
|
||||||
#define COLOR_RESET "\033[0m"
|
#define COLOR_RESET "\033[0m"
|
||||||
#define COLOR_RED "\033[31m"
|
#define COLOR_RED "\033[31m"
|
||||||
#define COLOR_GREEN "\033[32m"
|
#define COLOR_GREEN "\033[32m"
|
||||||
|
|
@ -32,14 +33,14 @@ extern "C"
|
||||||
#define COLOR_CYAN "\033[36m"
|
#define COLOR_CYAN "\033[36m"
|
||||||
#define COLOR_WHITE "\033[37m"
|
#define COLOR_WHITE "\033[37m"
|
||||||
|
|
||||||
/* === Short filename (strip path prefix, cross-platform) === */
|
/* === 文件名缩写(去除路径前缀,跨平台兼容) === */
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
|
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
|
||||||
#else
|
#else
|
||||||
#define __SHORT_FILE__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
#define __SHORT_FILE__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* === Console log macros (usable before liblog is loaded) === */
|
/* === 简易控制台日志宏(liblog 加载前可用) === */
|
||||||
#define MY_LOG(color, level, fmt, ...) \
|
#define MY_LOG(color, level, fmt, ...) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -50,42 +51,42 @@ extern "C"
|
||||||
#define MY_LOG_I(fmt, ...) MY_LOG(COLOR_WHITE, "INFO", fmt, ##__VA_ARGS__)
|
#define MY_LOG_I(fmt, ...) MY_LOG(COLOR_WHITE, "INFO", fmt, ##__VA_ARGS__)
|
||||||
#define MY_LOG_E(fmt, ...) MY_LOG(COLOR_RED, "ERROR", fmt, ##__VA_ARGS__)
|
#define MY_LOG_E(fmt, ...) MY_LOG(COLOR_RED, "ERROR", fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/* === LOCAL modifier (semantic: file-scope only) === */
|
/* === LOCAL 修饰符(语义:文件内可见,等价于 static) === */
|
||||||
#ifndef LOCAL
|
#ifndef LOCAL
|
||||||
#define LOCAL static
|
#define LOCAL static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* === Fixed-length string types === */
|
/* === 定长字符串类型 === */
|
||||||
#define SHORT_STR_LEN 64
|
#define SHORT_STR_LEN 64
|
||||||
typedef char S_STR[SHORT_STR_LEN];
|
typedef char S_STR[SHORT_STR_LEN];
|
||||||
|
|
||||||
#define LONG_STR_LEN 128
|
#define LONG_STR_LEN 128
|
||||||
typedef char L_STR[LONG_STR_LEN];
|
typedef char L_STR[LONG_STR_LEN];
|
||||||
|
|
||||||
/* === Endian swap: uint16 === */
|
/* === 字节序转换:uint16 === */
|
||||||
#define BE16_GET(p) ((uint16_t)(((uint8_t *)(p))[0] << 8 | ((uint8_t *)(p))[1]))
|
#define BE16_GET(p) ((uint16_t)(((uint8_t *)(p))[0] << 8 | ((uint8_t *)(p))[1]))
|
||||||
#define BE16_SET(m, n) ((m)[0] = (uint8_t)((n) >> 8), (m)[1] = (uint8_t)(n))
|
#define BE16_SET(m, n) ((m)[0] = (uint8_t)((n) >> 8), (m)[1] = (uint8_t)(n))
|
||||||
#define LE16_GET(p) ((uint16_t)(((uint8_t *)(p))[1] << 8 | ((uint8_t *)(p))[0]))
|
#define LE16_GET(p) ((uint16_t)(((uint8_t *)(p))[1] << 8 | ((uint8_t *)(p))[0]))
|
||||||
#define LE16_SET(m, n) ((m)[0] = (uint8_t)(n), (m)[1] = (uint8_t)((n) >> 8))
|
#define LE16_SET(m, n) ((m)[0] = (uint8_t)(n), (m)[1] = (uint8_t)((n) >> 8))
|
||||||
|
|
||||||
/* === Endian swap: int32 === */
|
/* === 字节序转换:int32 === */
|
||||||
#define BE32_GET(p) ((int32_t)(((uint8_t *)(p))[0] << 24 | ((uint8_t *)(p))[1] << 16 | ((uint8_t *)(p))[2] << 8 | ((uint8_t *)(p))[3]))
|
#define BE32_GET(p) ((int32_t)(((uint8_t *)(p))[0] << 24 | ((uint8_t *)(p))[1] << 16 | ((uint8_t *)(p))[2] << 8 | ((uint8_t *)(p))[3]))
|
||||||
#define BE32_SET(m, n) ((m)[0] = (uint8_t)((n) >> 24), (m)[1] = (uint8_t)((n) >> 16), (m)[2] = (uint8_t)((n) >> 8), (m)[3] = (uint8_t)(n))
|
#define BE32_SET(m, n) ((m)[0] = (uint8_t)((n) >> 24), (m)[1] = (uint8_t)((n) >> 16), (m)[2] = (uint8_t)((n) >> 8), (m)[3] = (uint8_t)(n))
|
||||||
#define LE32_GET(p) ((int32_t)(((uint8_t *)(p))[3] << 24 | ((uint8_t *)(p))[2] << 16 | ((uint8_t *)(p))[1] << 8 | ((uint8_t *)(p))[0]))
|
#define LE32_GET(p) ((int32_t)(((uint8_t *)(p))[3] << 24 | ((uint8_t *)(p))[2] << 16 | ((uint8_t *)(p))[1] << 8 | ((uint8_t *)(p))[0]))
|
||||||
#define LE32_SET(m, n) ((m)[3] = (uint8_t)((n) >> 24), (m)[2] = (uint8_t)((n) >> 16), (m)[1] = (uint8_t)((n) >> 8), (m)[0] = (uint8_t)(n))
|
#define LE32_SET(m, n) ((m)[3] = (uint8_t)((n) >> 24), (m)[2] = (uint8_t)((n) >> 16), (m)[1] = (uint8_t)((n) >> 8), (m)[0] = (uint8_t)(n))
|
||||||
|
|
||||||
/* === Endian swap: uint64 === */
|
/* === 字节序转换:uint64 === */
|
||||||
#define BE64_GET(p) (((uint64_t)(((uint8_t *)(p))[0]) << 56) | ((uint64_t)(((uint8_t *)(p))[1]) << 48) | ((uint64_t)(((uint8_t *)(p))[2]) << 40) | ((uint64_t)(((uint8_t *)(p))[3]) << 32) | ((uint64_t)(((uint8_t *)(p))[4]) << 24) | ((uint64_t)(((uint8_t *)(p))[5]) << 16) | ((uint64_t)(((uint8_t *)(p))[6]) << 8) | ((uint64_t)(((uint8_t *)(p))[7])))
|
#define BE64_GET(p) (((uint64_t)(((uint8_t *)(p))[0]) << 56) | ((uint64_t)(((uint8_t *)(p))[1]) << 48) | ((uint64_t)(((uint8_t *)(p))[2]) << 40) | ((uint64_t)(((uint8_t *)(p))[3]) << 32) | ((uint64_t)(((uint8_t *)(p))[4]) << 24) | ((uint64_t)(((uint8_t *)(p))[5]) << 16) | ((uint64_t)(((uint8_t *)(p))[6]) << 8) | ((uint64_t)(((uint8_t *)(p))[7])))
|
||||||
#define LE64_GET(p) (((uint64_t)(((uint8_t *)(p))[7]) << 56) | ((uint64_t)(((uint8_t *)(p))[6]) << 48) | ((uint64_t)(((uint8_t *)(p))[5]) << 40) | ((uint64_t)(((uint8_t *)(p))[4]) << 32) | ((uint64_t)(((uint8_t *)(p))[3]) << 24) | ((uint64_t)(((uint8_t *)(p))[2]) << 16) | ((uint64_t)(((uint8_t *)(p))[1]) << 8) | ((uint64_t)(((uint8_t *)(p))[0])))
|
#define LE64_GET(p) (((uint64_t)(((uint8_t *)(p))[7]) << 56) | ((uint64_t)(((uint8_t *)(p))[6]) << 48) | ((uint64_t)(((uint8_t *)(p))[5]) << 40) | ((uint64_t)(((uint8_t *)(p))[4]) << 32) | ((uint64_t)(((uint8_t *)(p))[3]) << 24) | ((uint64_t)(((uint8_t *)(p))[2]) << 16) | ((uint64_t)(((uint8_t *)(p))[1]) << 8) | ((uint64_t)(((uint8_t *)(p))[0])))
|
||||||
|
|
||||||
#define BE64_SET(m, n) ((m)[0] = (uint8_t)((n) >> 56), (m)[1] = (uint8_t)((n) >> 48), (m)[2] = (uint8_t)((n) >> 40), (m)[3] = (uint8_t)((n) >> 32), (m)[4] = (uint8_t)((n) >> 24), (m)[5] = (uint8_t)((n) >> 16), (m)[6] = (uint8_t)((n) >> 8), (m)[7] = (uint8_t)(n))
|
#define BE64_SET(m, n) ((m)[0] = (uint8_t)((n) >> 56), (m)[1] = (uint8_t)((n) >> 48), (m)[2] = (uint8_t)((n) >> 40), (m)[3] = (uint8_t)((n) >> 32), (m)[4] = (uint8_t)((n) >> 24), (m)[5] = (uint8_t)((n) >> 16), (m)[6] = (uint8_t)((n) >> 8), (m)[7] = (uint8_t)(n))
|
||||||
#define LE64_SET(m, n) ((m)[7] = (uint8_t)((n) >> 56), (m)[6] = (uint8_t)((n) >> 48), (m)[5] = (uint8_t)((n) >> 40), (m)[4] = (uint8_t)((n) >> 32), (m)[3] = (uint8_t)((n) >> 24), (m)[2] = (uint8_t)((n) >> 16), (m)[1] = (uint8_t)((n) >> 8), (m)[0] = (uint8_t)(n))
|
#define LE64_SET(m, n) ((m)[7] = (uint8_t)((n) >> 56), (m)[6] = (uint8_t)((n) >> 48), (m)[5] = (uint8_t)((n) >> 40), (m)[4] = (uint8_t)((n) >> 32), (m)[3] = (uint8_t)((n) >> 24), (m)[2] = (uint8_t)((n) >> 16), (m)[1] = (uint8_t)((n) >> 8), (m)[0] = (uint8_t)(n))
|
||||||
|
|
||||||
/* === Typed data access === */
|
/* === 类型化数据存取 === */
|
||||||
#define GET_BY_TYPE(p, type) (*(type *)(p))
|
#define GET_BY_TYPE(p, type) (*(type *)(p))
|
||||||
#define SET_BY_TYPE(p, v, type) (*(type *)(p) = *(type *)(v))
|
#define SET_BY_TYPE(p, v, type) (*(type *)(p) = *(type *)(v))
|
||||||
|
|
||||||
/* === Data type constants (for protocol encode/decode) === */
|
/* === 数据类型常量(用于协议编解码) === */
|
||||||
#define DATA_TYPE_B 1
|
#define DATA_TYPE_B 1
|
||||||
#define DATA_TYPE_S8 43
|
#define DATA_TYPE_S8 43
|
||||||
#define DATA_TYPE_U8 32
|
#define DATA_TYPE_U8 32
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* @file myLog.h
|
* @file myLog.h
|
||||||
* @brief 异步日志系统接口(纯 C)
|
* @brief 异步日志系统接口(纯 C)
|
||||||
* @details 提供 INFO/ERROR 两级异步日志,非阻塞写入。
|
* @details 支持 INFO/ERROR 两级日志,非阻塞写入。
|
||||||
* 支持控制台彩色输出、文件输出、文件按大小轮转。
|
* 首次调用 log_prt 时自动初始化(pthread_once 懒启动),无需手动 init。
|
||||||
* 首次调用 log_prt 时自动初始化,无需手动 init。
|
* 控制台支持彩色 ANSI 输出,文件支持按大小自动轮转。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_LOG_H_
|
#ifndef _MY_LOG_H_
|
||||||
|
|
@ -14,25 +14,26 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** 日志级别:INFO(普通信息) */
|
/** 日志级别:INFO(普通信息,白色输出) */
|
||||||
#define LOG_INFO 0
|
#define LOG_INFO 0
|
||||||
/** 日志级别:ERROR(错误信息,控制台红色输出) */
|
|
||||||
|
/** 日志级别:ERROR(错误信息,红色输出) */
|
||||||
#define LOG_ERROR 1
|
#define LOG_ERROR 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 手动初始化日志系统(可选,log_prt 自动懒初始化)
|
* @brief 手动初始化日志系统(可选,首次 log_prt 会自动触发)
|
||||||
* @param dir 日志文件目录路径,传 NULL 则默认 /tmp/logs
|
* @param dir 日志文件目录路径,传 NULL 则使用默认 /tmp/logs
|
||||||
* @return 0 成功
|
* @return 0 成功
|
||||||
*/
|
*/
|
||||||
int log_init(const char *dir);
|
int log_init(const char *dir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 核心日志打印函数(非阻塞,消息入队列后立即返回)
|
* @brief 核心日志打印函数(非阻塞,消息入队列后立即返回)
|
||||||
* @param level 日志级别 LOG_INFO 或 LOG_ERROR
|
* @param level 日志级别(LOG_INFO 或 LOG_ERROR)
|
||||||
* @param file 源文件名(通常传 __FILE__)
|
* @param file 源文件名(通常传 __FILE__)
|
||||||
* @param func 函数名(通常传 __FUNCTION__)
|
* @param func 函数名(通常传 __FUNCTION__)
|
||||||
* @param line 行号(通常传 __LINE__)
|
* @param line 行号(通常传 __LINE__)
|
||||||
* @param fmt printf 风格格式化字符串
|
* @param fmt printf 格式化字符串
|
||||||
* @param ... 可变参数
|
* @param ... 可变参数
|
||||||
*/
|
*/
|
||||||
void log_prt(uint32_t level, const char *file, const char *func,
|
void log_prt(uint32_t level, const char *file, const char *func,
|
||||||
|
|
@ -53,13 +54,13 @@ void log_console_off(void);
|
||||||
/** 等待异步队列清空(阻塞直到所有消息写入完成) */
|
/** 等待异步队列清空(阻塞直到所有消息写入完成) */
|
||||||
void log_flush(void);
|
void log_flush(void);
|
||||||
|
|
||||||
/** 停止工作线程、关闭文件、释放消息池内存 */
|
/** 停止工作线程、关闭文件、释放消息池 */
|
||||||
void log_cleanup(void);
|
void log_cleanup(void);
|
||||||
|
|
||||||
/** INFO 级别日志宏 */
|
/** INFO 级别便捷日志宏 */
|
||||||
#define LOG_I(fmt, ...) log_prt(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
#define LOG_I(fmt, ...) log_prt(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/** ERROR 级别日志宏 */
|
/** ERROR 级别便捷日志宏 */
|
||||||
#define LOG_E(fmt, ...) log_prt(LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
#define LOG_E(fmt, ...) log_prt(LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
/**
|
/**
|
||||||
* @file myMd5.h
|
* @file myMd5.h
|
||||||
* @brief MD5 message digest (RFC 1321)
|
* @brief MD5 消息摘要算法接口(RFC 1321)
|
||||||
* @details Computes 128-bit hash. Supports streaming update.
|
* @details 计算 128 位哈希值,支持流式输入。
|
||||||
|
* 提供单次调用便捷函数 md5_string()。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_MD5_H_
|
#ifndef _MY_MD5_H_
|
||||||
|
|
@ -14,25 +15,41 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MD5 context (state + count + pending buffer)
|
* @brief MD5 计算上下文(状态 + 计数 + 待处理缓冲区)
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t state[4]; /* A, B, C, D */
|
uint32_t state[4]; /* A, B, C, D 四个 32 位状态寄存器 */
|
||||||
uint32_t count[2]; /* bit count low/high */
|
uint32_t count[2]; /* 位计数(低 32 位, 高 32 位) */
|
||||||
unsigned char buf[64]; /* pending bytes */
|
unsigned char buf[64]; /* 待处理数据缓冲区(64 字节) */
|
||||||
} stru_md5_ctx;
|
} stru_md5_ctx;
|
||||||
|
|
||||||
/** Initialize context with magic constants */
|
/**
|
||||||
|
* @brief 初始化 MD5 上下文
|
||||||
|
* @param ctx 上下文指针(设置魔数 A=0x67452301 B=0xefcdab89 C=0x98badcfe D=0x10325476)
|
||||||
|
*/
|
||||||
void md5_start(stru_md5_ctx *ctx);
|
void md5_start(stru_md5_ctx *ctx);
|
||||||
|
|
||||||
/** Feed data, callable multiple times */
|
/**
|
||||||
|
* @brief 输入待计算数据(可多次调用,支持流式处理)
|
||||||
|
* @param ctx 上下文指针
|
||||||
|
* @param data 数据缓冲区
|
||||||
|
* @param len 数据长度(字节)
|
||||||
|
*/
|
||||||
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len);
|
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len);
|
||||||
|
|
||||||
/** Finalize, get 16-byte digest */
|
/**
|
||||||
|
* @brief 完成计算,输出 16 字节 MD5 摘要
|
||||||
|
* @param ctx 上下文指针
|
||||||
|
* @param result 输出缓冲区(至少 16 字节)
|
||||||
|
*/
|
||||||
void md5_final(stru_md5_ctx *ctx, unsigned char result[16]);
|
void md5_final(stru_md5_ctx *ctx, unsigned char result[16]);
|
||||||
|
|
||||||
/** One-shot: compute MD5 of string, output 32-char hex (uppercase) */
|
/**
|
||||||
|
* @brief 单次调用便捷函数:计算字符串的 MD5,返回大写十六进制字符串
|
||||||
|
* @param input 输入字符串(以 '\0' 结尾)
|
||||||
|
* @param output 输出缓冲区(至少 33 字节,含结尾 '\0')
|
||||||
|
*/
|
||||||
void md5_string(const char *input, char output[33]);
|
void md5_string(const char *input, char output[33]);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* @file myTask.h
|
* @file myTask.h
|
||||||
* @brief Task framework: timers + events + message queues (C interface)
|
* @brief 任务框架接口 — 定时器 + 事件 + 消息队列(C 接口)
|
||||||
* @details Based on SPEC §8 analysis. Uses C++ internally.
|
* @details 基于 SPEC §8 原工程分析。
|
||||||
|
* 定时器基于 timerfd + epoll 实现,精确到毫秒。
|
||||||
|
* 事件基于位图 + pthread 条件变量实现。
|
||||||
|
* 消息队列基于环形缓冲区 + 互斥锁 + 条件变量实现。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_TASK_H_
|
#ifndef _MY_TASK_H_
|
||||||
#define _MY_TASK_H_
|
#define _MY_TASK_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -14,130 +18,219 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Opaque handles
|
* 通用定义
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
typedef struct stru_task_timer *stru_task_timer_t;
|
/** 定时器回调函数类型 */
|
||||||
typedef struct stru_task_event *stru_task_event_t;
|
typedef void (*timer_func_cb)(void *arg);
|
||||||
typedef struct stru_task_msg_queue *stru_task_msg_queue_t;
|
|
||||||
|
/** 不透明句柄类型 */
|
||||||
|
typedef void *stru_task_timer_t;
|
||||||
|
typedef void *stru_task_event_t;
|
||||||
|
typedef void *stru_task_msg_queue_t;
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Timer callback — returns 0 to continue, non-zero to stop
|
* 定时器标志
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
typedef int (*timer_func_cb)(void *arg);
|
/** 单次触发(到期后自动停止) */
|
||||||
|
#define TASK_TIMER_FLAG_ONCE 0x01
|
||||||
|
|
||||||
/* Timer flags */
|
/** 周期触发(到期后自动重新计时) */
|
||||||
#define TIMER_ONCE 0 /* one-shot */
|
#define TASK_TIMER_FLAG_PERIODIC 0x02
|
||||||
#define TIMER_PERIOD 1 /* periodic */
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Timer API (SPEC T01-T07)
|
* 事件等待方式
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
/** 永久等待(不超时) */
|
||||||
|
#define TASK_EVENT_WAIT_FOREVER 0xFFFFFFFF
|
||||||
|
|
||||||
|
/** 事件标记:等待所有位都置位(AND 模式) */
|
||||||
|
#define TASK_EVENT_FLAG_AND 0x01
|
||||||
|
|
||||||
|
/** 事件标记:等待任意位置位(OR 模式) */
|
||||||
|
#define TASK_EVENT_FLAG_OR 0x02
|
||||||
|
|
||||||
|
/** 事件标记:接收后自动清除已匹配的位 */
|
||||||
|
#define TASK_EVENT_FLAG_CLEAR 0x04
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 通用延时
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a timer (does not start automatically)
|
* @brief 任务延时(毫秒级阻塞等待)
|
||||||
* @param name timer name for debugging
|
* @param ms 延时毫秒数
|
||||||
* @param cb callback function
|
|
||||||
* @param arg user argument passed to callback
|
|
||||||
* @param timeout_ms interval in milliseconds
|
|
||||||
* @param flags TIMER_ONCE or TIMER_PERIOD
|
|
||||||
* @return timer handle, NULL on failure
|
|
||||||
*/
|
*/
|
||||||
stru_task_timer_t task_timer_create(const char *name, timer_func_cb cb,
|
void task_sleep_ms(uint32_t ms);
|
||||||
void *arg, uint32_t timeout_ms, int flags);
|
|
||||||
|
|
||||||
/** Start the timer */
|
|
||||||
int task_timer_start(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/** Stop the timer */
|
|
||||||
int task_timer_stop(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/** Restart with new interval */
|
|
||||||
int task_timer_restart(stru_task_timer_t pt, uint32_t timeout_ms);
|
|
||||||
|
|
||||||
/** Destroy and free the timer */
|
|
||||||
int task_timer_destroy(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/** Check if timer is currently active */
|
|
||||||
int task_timer_is_active(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Event API (SPEC T08-T13)
|
* 事件 API
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
#define EVENT_OPT_AND 0 /* wait for ALL bits set */
|
|
||||||
#define EVENT_OPT_OR 1 /* wait for ANY bit set */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an event object
|
* @brief 创建事件对象
|
||||||
* @param name event name for debugging
|
* @param name 事件名称(调试用)
|
||||||
* @return event handle, NULL on failure
|
* @return 事件句柄,失败返回 NULL
|
||||||
*/
|
*/
|
||||||
stru_task_event_t task_event_create(const char *name);
|
stru_task_event_t task_event_create(const char *name);
|
||||||
|
|
||||||
/** Destroy event object */
|
/**
|
||||||
int task_event_destroy(stru_task_event_t pe);
|
* @brief 销毁事件对象
|
||||||
|
* @param p_event 事件句柄
|
||||||
/** Set (send) event bits */
|
* @return 0 成功,-1 失败
|
||||||
int task_event_send(stru_task_event_t pe, uint32_t bits);
|
*/
|
||||||
|
int task_event_destroy(stru_task_event_t p_event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wait for event bits
|
* @brief 发送事件(设置事件位)
|
||||||
* @param pe event handle
|
* @param p_event 事件句柄
|
||||||
* @param set bits to wait for
|
* @param event 要设置的事件位掩码
|
||||||
* @param opt EVENT_OPT_AND or EVENT_OPT_OR
|
* @return 0 成功,-1 失败
|
||||||
* @param timeout_ms timeout in ms (0 = forever)
|
|
||||||
* @param recved [out] bits actually received
|
|
||||||
* @return 0 on success, -1 on timeout
|
|
||||||
*/
|
*/
|
||||||
int task_event_recv(stru_task_event_t pe, uint32_t set, uint32_t opt,
|
int task_event_send(stru_task_event_t p_event, uint32_t event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待事件
|
||||||
|
* @param p_event 事件句柄
|
||||||
|
* @param set 期望的事件位掩码
|
||||||
|
* @param opt 等待选项(TASK_EVENT_FLAG_AND/OR/CLEAR 组合)
|
||||||
|
* @param timeout_ms 超时时间(毫秒,TASK_EVENT_WAIT_FOREVER=永久等待)
|
||||||
|
* @param recved 输出参数:实际收到的事件位
|
||||||
|
* @return 0 成功,-1 超时或失败
|
||||||
|
*/
|
||||||
|
int task_event_recv(stru_task_event_t p_event, uint32_t set, uint32_t opt,
|
||||||
uint32_t timeout_ms, uint32_t *recved);
|
uint32_t timeout_ms, uint32_t *recved);
|
||||||
|
|
||||||
/** Clear specific event bits */
|
/**
|
||||||
int task_event_clear(stru_task_event_t pe, uint32_t bits);
|
* @brief 清除事件位
|
||||||
|
* @param p_event 事件句柄
|
||||||
|
* @param event 要清除的事件位掩码
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_event_clear(stru_task_event_t p_event, uint32_t event);
|
||||||
|
|
||||||
/** Query current event bits (non-blocking) */
|
/**
|
||||||
uint32_t task_event_query(stru_task_event_t pe);
|
* @brief 查询当前事件位(非阻塞)
|
||||||
|
* @param p_event 事件句柄
|
||||||
|
* @return 当前事件位掩码
|
||||||
|
*/
|
||||||
|
uint32_t task_event_query(stru_task_event_t p_event);
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Message Queue API (SPEC T14-T21)
|
* 消息队列 API
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a fixed-size message queue
|
* @brief 创建定长消息队列
|
||||||
* @param name queue name
|
* @param name 队列名称(调试用)
|
||||||
* @param msg_size max size of each message (bytes)
|
* @param msg_size 每条消息的最大字节数
|
||||||
* @param msg_num max number of messages
|
* @param msg_num 队列容量(最大消息条数)
|
||||||
* @return queue handle, NULL on failure
|
* @return 队列句柄,失败返回 NULL
|
||||||
*/
|
*/
|
||||||
stru_task_msg_queue_t task_msg_queue_create(const char *name,
|
stru_task_msg_queue_t task_msg_queue_create(const char *name,
|
||||||
uint32_t msg_size, uint32_t msg_num);
|
uint32_t msg_size, uint32_t msg_num);
|
||||||
|
|
||||||
/** Destroy message queue */
|
/**
|
||||||
int task_msg_queue_destroy(stru_task_msg_queue_t pq);
|
* @brief 销毁消息队列
|
||||||
|
* @param p_queue 队列句柄
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_destroy(stru_task_msg_queue_t p_queue);
|
||||||
|
|
||||||
/** Send message (blocking if queue full) */
|
/**
|
||||||
int task_msg_queue_send(stru_task_msg_queue_t pq, const void *msg, uint32_t size);
|
* @brief 发送消息(队列满时阻塞等待)
|
||||||
|
* @param p_queue 队列句柄
|
||||||
|
* @param msg 消息内容指针
|
||||||
|
* @param size 消息实际字节数(<= msg_size)
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_send(stru_task_msg_queue_t p_queue, const void *msg,
|
||||||
|
uint32_t size);
|
||||||
|
|
||||||
/** Send message with timeout (ms), returns -1 on timeout */
|
/**
|
||||||
int task_msg_queue_send_timeout(stru_task_msg_queue_t pq, const void *msg,
|
* @brief 发送消息(带超时)
|
||||||
|
* @param timeout_ms 超时时间(毫秒,TASK_EVENT_WAIT_FOREVER=永久等待)
|
||||||
|
* @return 0 成功,-1 超时或失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_send_timeout(stru_task_msg_queue_t p_queue, const void *msg,
|
||||||
uint32_t size, uint32_t timeout_ms);
|
uint32_t size, uint32_t timeout_ms);
|
||||||
|
|
||||||
/** Receive message with timeout (ms), returns -1 on timeout */
|
/**
|
||||||
int task_msg_queue_recv(stru_task_msg_queue_t pq, void *msg, uint32_t size,
|
* @brief 接收消息(带超时)
|
||||||
uint32_t timeout_ms);
|
* @param timeout_ms 超时时间(毫秒,TASK_EVENT_WAIT_FOREVER=永久等待)
|
||||||
|
* @return 0 成功,-1 超时或失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_recv(stru_task_msg_queue_t p_queue, void *msg,
|
||||||
|
uint32_t size, uint32_t timeout_ms);
|
||||||
|
|
||||||
/** Try receive (non-blocking), returns 0 on success, -1 if empty */
|
/**
|
||||||
int task_msg_queue_try_recv(stru_task_msg_queue_t pq, void *msg, uint32_t size);
|
* @brief 尝试接收消息(非阻塞,队列空立即返回 -1)
|
||||||
|
* @return 0 成功,-1 队列空
|
||||||
|
*/
|
||||||
|
int task_msg_queue_try_recv(stru_task_msg_queue_t p_queue, void *msg,
|
||||||
|
uint32_t size);
|
||||||
|
|
||||||
/** Get number of messages currently in queue */
|
/**
|
||||||
uint32_t task_msg_queue_get_count(stru_task_msg_queue_t pq);
|
* @brief 获取队列中当前消息数
|
||||||
|
*/
|
||||||
|
uint32_t task_msg_queue_get_count(stru_task_msg_queue_t p_queue);
|
||||||
|
|
||||||
/** Get free space in queue */
|
/**
|
||||||
uint32_t task_msg_queue_space(stru_task_msg_queue_t pq);
|
* @brief 获取队列剩余可用空间(条数)
|
||||||
|
*/
|
||||||
|
uint32_t task_msg_queue_space(stru_task_msg_queue_t p_queue);
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 定时器 API
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建定时器(创建后不会自动启动,需调用 task_timer_start)
|
||||||
|
* @param name 定时器名称(调试用)
|
||||||
|
* @param fun_cb 到期回调函数
|
||||||
|
* @param arg 回调参数
|
||||||
|
* @param timeout_ms 定时周期(毫秒)
|
||||||
|
* @param flags 标志位(TASK_TIMER_FLAG_ONCE 或 TASK_TIMER_FLAG_PERIODIC)
|
||||||
|
* @return 定时器句柄,失败返回 NULL
|
||||||
|
*/
|
||||||
|
stru_task_timer_t task_timer_create(const char *name, timer_func_cb fun_cb,
|
||||||
|
void *arg, uint32_t timeout_ms, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动定时器
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_start(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 停止定时器
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_stop(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重启定时器(可修改周期)
|
||||||
|
* @param timeout_ms 新的定时周期(毫秒)
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_restart(stru_task_timer_t p_timer, uint32_t timeout_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 销毁定时器
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_destroy(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 查询定时器是否在运行
|
||||||
|
* @return 1=运行中,0=已停止
|
||||||
|
*/
|
||||||
|
int task_timer_is_active(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif /* _MY_TASK_H_ */
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,28 @@ O := $(LIB_REL)/$(M).a
|
||||||
S := $(SRC_ROOT_DIR)/$(L)/libtask/src
|
S := $(SRC_ROOT_DIR)/$(L)/libtask/src
|
||||||
I := -I$(SRC_ROOT_DIR)/$(L)/libtask/inc
|
I := -I$(SRC_ROOT_DIR)/$(L)/libtask/inc
|
||||||
B := $(CURDIR)/$(M)/obj
|
B := $(CURDIR)/$(M)/obj
|
||||||
SRCS := $(wildcard $(S)/*.cpp)
|
SRCS := $(wildcard $(S)/*.c)
|
||||||
OBJS := $(patsubst $(S)/%.cpp,$(B)/%.o,$(SRCS))
|
OBJS := $(patsubst $(S)/%.c, $(B)/%.o, $(SRCS))
|
||||||
F := $(CXX_FLAGS) $(I) -I$(SRC_ROOT_DIR)/public/liblog/inc
|
F := $(C_FLAGS) $(I)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
all:
|
all:
|
||||||
@mkdir -p $(ROOT_DIR)/release/inc
|
@mkdir -p $(ROOT_DIR)/release/inc
|
||||||
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
|
@cp -f $(S:src=inc)/*.h $(ROOT_DIR)/release/inc/ 2>/dev/null; true
|
||||||
@$(MAKE) $(O)
|
@$(MAKE) $(O)
|
||||||
|
|
||||||
$(O): $(OBJS)
|
$(O): $(OBJS)
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(AR) rcs $@ $^
|
$(AR) rcs $@ $^
|
||||||
@echo "[$(M)] built"
|
@echo "[$(M)] built"
|
||||||
$(B)/%.o: $(S)/%.cpp
|
|
||||||
|
$(B)/%.o: $(S)/%.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CXX) $(F) -c $< -o $@
|
$(CC) $(F) -c $< -o $@
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(B) $(O)
|
rm -rf $(B) $(O)
|
||||||
|
|
||||||
|
.PHONY: rebuild
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
.PHONY: all clean rebuild
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
|
|
||||||
/* ==== 1. Checksum: CRC16/32 + ByteSum + FileCRC ==== */
|
/* ==== 1. 校验计算:CRC16/CRC32/累加校验和/文件CRC ==== */
|
||||||
|
|
||||||
LOCAL const uint16_t _crc16_tab[256] = {
|
LOCAL const uint16_t _crc16_tab[256] = {
|
||||||
0x0000,0xc0c1,0xc181,0x0140,0xc301,0x03c0,0x0280,0xc241,0xc601,0x06c0,0x0780,0xc741,0x0500,0xc5c1,0xc481,0x0440,
|
0x0000,0xc0c1,0xc181,0x0140,0xc301,0x03c0,0x0280,0xc241,0xc601,0x06c0,0x0780,0xc741,0x0500,0xc5c1,0xc481,0x0440,
|
||||||
|
|
@ -195,7 +195,7 @@ uint32_t func_cal_file_crc32(const char *path)
|
||||||
return crc ^ 0xFFFFFFFF;
|
return crc ^ 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==== 2. String Convert ==== */
|
/* ==== 2. 字符串转换 ==== */
|
||||||
|
|
||||||
uint8_t func_hex_ch(char c)
|
uint8_t func_hex_ch(char c)
|
||||||
{
|
{
|
||||||
|
|
@ -418,7 +418,7 @@ int func_str2argv(char *s, uint8_t *argc, char *argv[], uint8_t max)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==== 3. Time Process ==== */
|
/* ==== 3. 时间处理 ==== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief stru_time_sys to formatted time string
|
* @brief stru_time_sys to formatted time string
|
||||||
|
|
@ -584,7 +584,7 @@ void func_time_cal2sys(stru_time_cal *src, stru_time_sys *dst)
|
||||||
dst->ms = (uint16_t)(g->tm_sec * 1000 + src->usec / 1000);
|
dst->ms = (uint16_t)(g->tm_sec * 1000 + src->usec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==== 4. File & Directory ==== */
|
/* ==== 4. 文件目录操作 ==== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if directory exists
|
* @brief Check if directory exists
|
||||||
|
|
@ -853,7 +853,7 @@ int func_read_file_info(const char *p, stru_file_info *info, int check)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==== 5. Process Manager (Linux /proc) ==== */
|
/* ==== 5. 进程管理(基于 Linux /proc) ==== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get current process name via /proc/self/comm
|
* @brief Get current process name via /proc/self/comm
|
||||||
|
|
@ -1069,7 +1069,7 @@ int func_proc_self_dir(char *buf, uint32_t sz)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==== 6. Environment Paths ==== */
|
/* ==== 6. 环境变量路径 ==== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get WORK_PATH env var
|
* @brief Get WORK_PATH env var
|
||||||
|
|
@ -1260,7 +1260,7 @@ int func_get_app_log(const char *a, char *b, uint32_t s)
|
||||||
return _make_path("LOG_ROOT_PATH", a, NULL, b, s);
|
return _make_path("LOG_ROOT_PATH", a, NULL, b, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==== 7. IPC Message Queue (System V) ==== */
|
/* ==== 7. IPC 消息队列(System V) ==== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create IPC message queue by process name
|
* @brief Create IPC message queue by process name
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* @file list.h
|
* @file list.h
|
||||||
* @brief 内核风格侵入式双向循环链表(纯头文件,C/C++ 兼容)
|
* @brief Linux 内核风格侵入式双向循环链表(纯头文件,C/C++ 兼容)
|
||||||
*
|
* @details 将 struct list_head 嵌入宿主结构体,通过 list_entry 取回宿主指针。
|
||||||
* 用法:将 struct list_head 嵌入你的结构体,通过 list_entry 取回宿主指针。
|
* 所有操作 O(1),遍历 O(n)。
|
||||||
* 所有操作 O(1),遍历 O(n)。C++ 兼容:不用 new/class/typeof 等关键字。
|
* C++ 兼容:变量名不使用 new/class/typeof 等关键字。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIST_H_
|
#ifndef _LIST_H_
|
||||||
|
|
@ -16,7 +16,7 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---- 节点 ---- */
|
/* ---- 链表节点 ---- */
|
||||||
struct list_head
|
struct list_head
|
||||||
{
|
{
|
||||||
struct list_head *next;
|
struct list_head *next;
|
||||||
|
|
@ -27,13 +27,16 @@ struct list_head
|
||||||
#define LIST_HEAD_INIT(n) { &(n), &(n) }
|
#define LIST_HEAD_INIT(n) { &(n), &(n) }
|
||||||
#define LIST_HEAD(n) struct list_head n = LIST_HEAD_INIT(n)
|
#define LIST_HEAD(n) struct list_head n = LIST_HEAD_INIT(n)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 运行时初始化链表头
|
||||||
|
*/
|
||||||
static inline void INIT_LIST_HEAD(struct list_head *h)
|
static inline void INIT_LIST_HEAD(struct list_head *h)
|
||||||
{
|
{
|
||||||
h->next = h;
|
h->next = h;
|
||||||
h->prev = h;
|
h->prev = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 内部:在 prev 和 next 之间插入 node ---- */
|
/* ---- 内部辅助:在 prev 和 next 之间插入 node ---- */
|
||||||
static inline void __list_add(struct list_head *node,
|
static inline void __list_add(struct list_head *node,
|
||||||
struct list_head *prev,
|
struct list_head *prev,
|
||||||
struct list_head *next)
|
struct list_head *next)
|
||||||
|
|
@ -44,7 +47,7 @@ static inline void __list_add(struct list_head *node,
|
||||||
prev->next = node;
|
prev->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 内部:删除 prev 和 next 之间的节点 ---- */
|
/* ---- 内部辅助:移除 prev 和 next 之间的节点 ---- */
|
||||||
static inline void __list_del(struct list_head *prev,
|
static inline void __list_del(struct list_head *prev,
|
||||||
struct list_head *next)
|
struct list_head *next)
|
||||||
{
|
{
|
||||||
|
|
@ -52,43 +55,54 @@ static inline void __list_del(struct list_head *prev,
|
||||||
prev->next = next;
|
prev->next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 添加 ---- */
|
/* ---- 添加操作 ---- */
|
||||||
|
|
||||||
|
/** 头插法:插入到 head 之后(作为第一个元素) */
|
||||||
static inline void list_add(struct list_head *node, struct list_head *head)
|
static inline void list_add(struct list_head *node, struct list_head *head)
|
||||||
{
|
{
|
||||||
__list_add(node, head, head->next);
|
__list_add(node, head, head->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 尾插法:插入到 head 之前(作为最后一个元素) */
|
||||||
static inline void list_add_tail(struct list_head *node, struct list_head *head)
|
static inline void list_add_tail(struct list_head *node, struct list_head *head)
|
||||||
{
|
{
|
||||||
__list_add(node, head->prev, head);
|
__list_add(node, head->prev, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 删除 ---- */
|
/* ---- 删除操作 ---- */
|
||||||
|
|
||||||
|
/** 从链表移除节点(不释放内存) */
|
||||||
static inline void list_del(struct list_head *e)
|
static inline void list_del(struct list_head *e)
|
||||||
{
|
{
|
||||||
__list_del(e->prev, e->next);
|
__list_del(e->prev, e->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 移除并重新初始化节点(安全删除,防止悬空指针) */
|
||||||
static inline void list_del_init(struct list_head *e)
|
static inline void list_del_init(struct list_head *e)
|
||||||
{
|
{
|
||||||
__list_del(e->prev, e->next);
|
__list_del(e->prev, e->next);
|
||||||
INIT_LIST_HEAD(e);
|
INIT_LIST_HEAD(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 移动 ---- */
|
/* ---- 移动操作 ---- */
|
||||||
|
|
||||||
|
/** 将节点移动到新链表头部 */
|
||||||
static inline void list_move(struct list_head *l, struct list_head *h)
|
static inline void list_move(struct list_head *l, struct list_head *h)
|
||||||
{
|
{
|
||||||
__list_del(l->prev, l->next);
|
__list_del(l->prev, l->next);
|
||||||
list_add(l, h);
|
list_add(l, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 将节点移动到新链表尾部 */
|
||||||
static inline void list_move_tail(struct list_head *l, struct list_head *h)
|
static inline void list_move_tail(struct list_head *l, struct list_head *h)
|
||||||
{
|
{
|
||||||
__list_del(l->prev, l->next);
|
__list_del(l->prev, l->next);
|
||||||
list_add_tail(l, h);
|
list_add_tail(l, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 替换 ---- */
|
/* ---- 替换操作 ---- */
|
||||||
|
|
||||||
|
/** 用 node 替换 old */
|
||||||
static inline void list_replace(struct list_head *old, struct list_head *node)
|
static inline void list_replace(struct list_head *old, struct list_head *node)
|
||||||
{
|
{
|
||||||
node->next = old->next;
|
node->next = old->next;
|
||||||
|
|
@ -97,6 +111,7 @@ static inline void list_replace(struct list_head *old, struct list_head *node)
|
||||||
node->prev->next = node;
|
node->prev->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 替换后初始化被替换节点 */
|
||||||
static inline void list_replace_init(struct list_head *old,
|
static inline void list_replace_init(struct list_head *old,
|
||||||
struct list_head *node)
|
struct list_head *node)
|
||||||
{
|
{
|
||||||
|
|
@ -104,43 +119,56 @@ static inline void list_replace_init(struct list_head *old,
|
||||||
INIT_LIST_HEAD(old);
|
INIT_LIST_HEAD(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 判断 ---- */
|
/* ---- 判断操作 ---- */
|
||||||
|
|
||||||
|
/** 判断链表是否为空 */
|
||||||
static inline int list_empty(const struct list_head *h)
|
static inline int list_empty(const struct list_head *h)
|
||||||
{
|
{
|
||||||
return h->next == h;
|
return h->next == h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 判断节点是否已链入链表 */
|
||||||
static inline int list_is_linked(const struct list_head *e)
|
static inline int list_is_linked(const struct list_head *e)
|
||||||
{
|
{
|
||||||
return e->next != e;
|
return e->next != e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 宿主指针 ---- */
|
/* ---- 节点 ↔ 宿主指针转换 ---- */
|
||||||
|
|
||||||
|
/** 从链表节点指针取回宿主结构体指针 */
|
||||||
#define list_entry(ptr, type, member) \
|
#define list_entry(ptr, type, member) \
|
||||||
((type *)((char *)(ptr) - offsetof(type, member)))
|
((type *)((char *)(ptr) - offsetof(type, member)))
|
||||||
|
|
||||||
|
/** 获取第一个宿主元素 */
|
||||||
#define list_first_entry(h, type, member) \
|
#define list_first_entry(h, type, member) \
|
||||||
list_entry((h)->next, type, member)
|
list_entry((h)->next, type, member)
|
||||||
|
|
||||||
|
/** 获取最后一个宿主元素 */
|
||||||
#define list_last_entry(h, type, member) \
|
#define list_last_entry(h, type, member) \
|
||||||
list_entry((h)->prev, type, member)
|
list_entry((h)->prev, type, member)
|
||||||
|
|
||||||
|
/** 安全获取第一个元素(链表空返回 NULL) */
|
||||||
#define list_first_entry_or_null(h, type, member) \
|
#define list_first_entry_or_null(h, type, member) \
|
||||||
(list_empty(h) ? NULL : list_first_entry(h, type, member))
|
(list_empty(h) ? NULL : list_first_entry(h, type, member))
|
||||||
|
|
||||||
/* ---- 遍历 ---- */
|
/* ---- 遍历操作 ---- */
|
||||||
|
|
||||||
|
/** 遍历链表节点(仅获取 struct list_head 指针) */
|
||||||
#define list_for_each(pos, head) \
|
#define list_for_each(pos, head) \
|
||||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||||
|
|
||||||
|
/** 安全遍历节点(可在遍历中删除 pos) */
|
||||||
#define list_for_each_safe(pos, n, head) \
|
#define list_for_each_safe(pos, n, head) \
|
||||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||||
pos = n, n = pos->next)
|
pos = n, n = pos->next)
|
||||||
|
|
||||||
|
/** 遍历宿主元素 */
|
||||||
#define list_for_each_entry(pos, head, member) \
|
#define list_for_each_entry(pos, head, member) \
|
||||||
for (pos = list_first_entry(head, __typeof__(*pos), member); \
|
for (pos = list_first_entry(head, __typeof__(*pos), member); \
|
||||||
&pos->member != (head); \
|
&pos->member != (head); \
|
||||||
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
||||||
|
|
||||||
|
/** 安全遍历宿主元素(可在遍历中删除 pos) */
|
||||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||||
for (pos = list_first_entry(head, __typeof__(*pos), member), \
|
for (pos = list_first_entry(head, __typeof__(*pos), member), \
|
||||||
n = list_entry(pos->member.next, __typeof__(*pos), member); \
|
n = list_entry(pos->member.next, __typeof__(*pos), member); \
|
||||||
|
|
@ -148,7 +176,9 @@ static inline int list_is_linked(const struct list_head *e)
|
||||||
pos = n, \
|
pos = n, \
|
||||||
n = list_entry(n->member.next, __typeof__(*n), member))
|
n = list_entry(n->member.next, __typeof__(*n), member))
|
||||||
|
|
||||||
/* ---- 拼接 ---- */
|
/* ---- 拼接操作 ---- */
|
||||||
|
|
||||||
|
/** 将 src 链表拼接到 dst 头部,src 被清空 */
|
||||||
static inline void list_splice_init(struct list_head *src,
|
static inline void list_splice_init(struct list_head *src,
|
||||||
struct list_head *dst)
|
struct list_head *dst)
|
||||||
{
|
{
|
||||||
|
|
@ -169,4 +199,5 @@ static inline void list_splice_init(struct list_head *src,
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif /* _LIST_H_ */
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* @file myLog.h
|
* @file myLog.h
|
||||||
* @brief 异步日志系统接口(纯 C)
|
* @brief 异步日志系统接口(纯 C)
|
||||||
* @details 提供 INFO/ERROR 两级异步日志,非阻塞写入。
|
* @details 支持 INFO/ERROR 两级日志,非阻塞写入。
|
||||||
* 支持控制台彩色输出、文件输出、文件按大小轮转。
|
* 首次调用 log_prt 时自动初始化(pthread_once 懒启动),无需手动 init。
|
||||||
* 首次调用 log_prt 时自动初始化,无需手动 init。
|
* 控制台支持彩色 ANSI 输出,文件支持按大小自动轮转。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_LOG_H_
|
#ifndef _MY_LOG_H_
|
||||||
|
|
@ -14,25 +14,26 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** 日志级别:INFO(普通信息) */
|
/** 日志级别:INFO(普通信息,白色输出) */
|
||||||
#define LOG_INFO 0
|
#define LOG_INFO 0
|
||||||
/** 日志级别:ERROR(错误信息,控制台红色输出) */
|
|
||||||
|
/** 日志级别:ERROR(错误信息,红色输出) */
|
||||||
#define LOG_ERROR 1
|
#define LOG_ERROR 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 手动初始化日志系统(可选,log_prt 自动懒初始化)
|
* @brief 手动初始化日志系统(可选,首次 log_prt 会自动触发)
|
||||||
* @param dir 日志文件目录路径,传 NULL 则默认 /tmp/logs
|
* @param dir 日志文件目录路径,传 NULL 则使用默认 /tmp/logs
|
||||||
* @return 0 成功
|
* @return 0 成功
|
||||||
*/
|
*/
|
||||||
int log_init(const char *dir);
|
int log_init(const char *dir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 核心日志打印函数(非阻塞,消息入队列后立即返回)
|
* @brief 核心日志打印函数(非阻塞,消息入队列后立即返回)
|
||||||
* @param level 日志级别 LOG_INFO 或 LOG_ERROR
|
* @param level 日志级别(LOG_INFO 或 LOG_ERROR)
|
||||||
* @param file 源文件名(通常传 __FILE__)
|
* @param file 源文件名(通常传 __FILE__)
|
||||||
* @param func 函数名(通常传 __FUNCTION__)
|
* @param func 函数名(通常传 __FUNCTION__)
|
||||||
* @param line 行号(通常传 __LINE__)
|
* @param line 行号(通常传 __LINE__)
|
||||||
* @param fmt printf 风格格式化字符串
|
* @param fmt printf 格式化字符串
|
||||||
* @param ... 可变参数
|
* @param ... 可变参数
|
||||||
*/
|
*/
|
||||||
void log_prt(uint32_t level, const char *file, const char *func,
|
void log_prt(uint32_t level, const char *file, const char *func,
|
||||||
|
|
@ -53,13 +54,13 @@ void log_console_off(void);
|
||||||
/** 等待异步队列清空(阻塞直到所有消息写入完成) */
|
/** 等待异步队列清空(阻塞直到所有消息写入完成) */
|
||||||
void log_flush(void);
|
void log_flush(void);
|
||||||
|
|
||||||
/** 停止工作线程、关闭文件、释放消息池内存 */
|
/** 停止工作线程、关闭文件、释放消息池 */
|
||||||
void log_cleanup(void);
|
void log_cleanup(void);
|
||||||
|
|
||||||
/** INFO 级别日志宏 */
|
/** INFO 级别便捷日志宏 */
|
||||||
#define LOG_I(fmt, ...) log_prt(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
#define LOG_I(fmt, ...) log_prt(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/** ERROR 级别日志宏 */
|
/** ERROR 级别便捷日志宏 */
|
||||||
#define LOG_E(fmt, ...) log_prt(LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
#define LOG_E(fmt, ...) log_prt(LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
/**
|
/**
|
||||||
* @file myMd5.h
|
* @file myMd5.h
|
||||||
* @brief MD5 message digest (RFC 1321)
|
* @brief MD5 消息摘要算法接口(RFC 1321)
|
||||||
* @details Computes 128-bit hash. Supports streaming update.
|
* @details 计算 128 位哈希值,支持流式输入。
|
||||||
|
* 提供单次调用便捷函数 md5_string()。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_MD5_H_
|
#ifndef _MY_MD5_H_
|
||||||
|
|
@ -14,25 +15,41 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MD5 context (state + count + pending buffer)
|
* @brief MD5 计算上下文(状态 + 计数 + 待处理缓冲区)
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t state[4]; /* A, B, C, D */
|
uint32_t state[4]; /* A, B, C, D 四个 32 位状态寄存器 */
|
||||||
uint32_t count[2]; /* bit count low/high */
|
uint32_t count[2]; /* 位计数(低 32 位, 高 32 位) */
|
||||||
unsigned char buf[64]; /* pending bytes */
|
unsigned char buf[64]; /* 待处理数据缓冲区(64 字节) */
|
||||||
} stru_md5_ctx;
|
} stru_md5_ctx;
|
||||||
|
|
||||||
/** Initialize context with magic constants */
|
/**
|
||||||
|
* @brief 初始化 MD5 上下文
|
||||||
|
* @param ctx 上下文指针(设置魔数 A=0x67452301 B=0xefcdab89 C=0x98badcfe D=0x10325476)
|
||||||
|
*/
|
||||||
void md5_start(stru_md5_ctx *ctx);
|
void md5_start(stru_md5_ctx *ctx);
|
||||||
|
|
||||||
/** Feed data, callable multiple times */
|
/**
|
||||||
|
* @brief 输入待计算数据(可多次调用,支持流式处理)
|
||||||
|
* @param ctx 上下文指针
|
||||||
|
* @param data 数据缓冲区
|
||||||
|
* @param len 数据长度(字节)
|
||||||
|
*/
|
||||||
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len);
|
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len);
|
||||||
|
|
||||||
/** Finalize, get 16-byte digest */
|
/**
|
||||||
|
* @brief 完成计算,输出 16 字节 MD5 摘要
|
||||||
|
* @param ctx 上下文指针
|
||||||
|
* @param result 输出缓冲区(至少 16 字节)
|
||||||
|
*/
|
||||||
void md5_final(stru_md5_ctx *ctx, unsigned char result[16]);
|
void md5_final(stru_md5_ctx *ctx, unsigned char result[16]);
|
||||||
|
|
||||||
/** One-shot: compute MD5 of string, output 32-char hex (uppercase) */
|
/**
|
||||||
|
* @brief 单次调用便捷函数:计算字符串的 MD5,返回大写十六进制字符串
|
||||||
|
* @param input 输入字符串(以 '\0' 结尾)
|
||||||
|
* @param output 输出缓冲区(至少 33 字节,含结尾 '\0')
|
||||||
|
*/
|
||||||
void md5_string(const char *input, char output[33]);
|
void md5_string(const char *input, char output[33]);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
/**
|
/**
|
||||||
* @file myMd5.c
|
* @file myMd5.c
|
||||||
* @brief MD5 implementation (RFC 1321, 16 steps x 4 rounds)
|
* @brief MD5 消息摘要算法实现(RFC 1321)
|
||||||
|
* @details 4 轮 × 16 步变换,自主编写。
|
||||||
|
* 处理流程:填充原始消息 → 64 字节分块处理 → 输出 16 字节摘要。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "myMd5.h"
|
#include "myMd5.h"
|
||||||
|
|
@ -8,13 +10,23 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* MD5 核心原语(RFC 1321 §3.4)
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
/** 四个非线性函数 */
|
||||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||||
|
|
||||||
|
/** 循环左移 */
|
||||||
#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 单步变换宏
|
||||||
|
* @detail a = b + ROTL(a + f(b,c,d) + x + ac, s)
|
||||||
|
*/
|
||||||
#define STEP(f, a, b, c, d, x, s, ac) \
|
#define STEP(f, a, b, c, d, x, s, ac) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -23,6 +35,9 @@
|
||||||
(a) += (b); \
|
(a) += (b); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 小端解码:字节数组 → uint32 数组
|
||||||
|
*/
|
||||||
LOCAL void md5_decode(uint32_t *out, const unsigned char *in, int n)
|
LOCAL void md5_decode(uint32_t *out, const unsigned char *in, int n)
|
||||||
{
|
{
|
||||||
for (int i = 0, j = 0; j < n; i++, j += 4)
|
for (int i = 0, j = 0; j < n; i++, j += 4)
|
||||||
|
|
@ -34,6 +49,9 @@ LOCAL void md5_decode(uint32_t *out, const unsigned char *in, int n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 小端编码:uint32 数组 → 字节数组
|
||||||
|
*/
|
||||||
LOCAL void md5_encode(unsigned char *out, const uint32_t *in, int n)
|
LOCAL void md5_encode(unsigned char *out, const uint32_t *in, int n)
|
||||||
{
|
{
|
||||||
for (int i = 0, j = 0; j < n; i++, j += 4)
|
for (int i = 0, j = 0; j < n; i++, j += 4)
|
||||||
|
|
@ -45,14 +63,19 @@ LOCAL void md5_encode(unsigned char *out, const uint32_t *in, int n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MD5 核心变换:处理一个 64 字节块
|
||||||
|
* @detail 4 轮 × 16 步 = 64 步操作,每步使用不同的非线性函数
|
||||||
|
*/
|
||||||
LOCAL void md5_transform(uint32_t state[4], const unsigned char block[64])
|
LOCAL void md5_transform(uint32_t state[4], const unsigned char block[64])
|
||||||
{
|
{
|
||||||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
|
uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
|
||||||
uint32_t x[16];
|
uint32_t x[16];
|
||||||
|
|
||||||
|
/* 将 64 字节块解码为 16 个 uint32 */
|
||||||
md5_decode(x, block, 64);
|
md5_decode(x, block, 64);
|
||||||
|
|
||||||
/* Round 1 */
|
/* 第 1 轮:FF */
|
||||||
STEP(F, a, b, c, d, x[ 0], 7, 0xd76aa478);
|
STEP(F, a, b, c, d, x[ 0], 7, 0xd76aa478);
|
||||||
STEP(F, d, a, b, c, x[ 1], 12, 0xe8c7b756);
|
STEP(F, d, a, b, c, x[ 1], 12, 0xe8c7b756);
|
||||||
STEP(F, c, d, a, b, x[ 2], 17, 0x242070db);
|
STEP(F, c, d, a, b, x[ 2], 17, 0x242070db);
|
||||||
|
|
@ -70,7 +93,7 @@ LOCAL void md5_transform(uint32_t state[4], const unsigned char block[64])
|
||||||
STEP(F, c, d, a, b, x[14], 17, 0xa679438e);
|
STEP(F, c, d, a, b, x[14], 17, 0xa679438e);
|
||||||
STEP(F, b, c, d, a, x[15], 22, 0x49b40821);
|
STEP(F, b, c, d, a, x[15], 22, 0x49b40821);
|
||||||
|
|
||||||
/* Round 2 */
|
/* 第 2 轮:GG */
|
||||||
STEP(G, a, b, c, d, x[ 1], 5, 0xf61e2562);
|
STEP(G, a, b, c, d, x[ 1], 5, 0xf61e2562);
|
||||||
STEP(G, d, a, b, c, x[ 6], 9, 0xc040b340);
|
STEP(G, d, a, b, c, x[ 6], 9, 0xc040b340);
|
||||||
STEP(G, c, d, a, b, x[11], 14, 0x265e5a51);
|
STEP(G, c, d, a, b, x[11], 14, 0x265e5a51);
|
||||||
|
|
@ -88,7 +111,7 @@ LOCAL void md5_transform(uint32_t state[4], const unsigned char block[64])
|
||||||
STEP(G, c, d, a, b, x[ 7], 14, 0x676f02d9);
|
STEP(G, c, d, a, b, x[ 7], 14, 0x676f02d9);
|
||||||
STEP(G, b, c, d, a, x[12], 20, 0x8d2a4c8a);
|
STEP(G, b, c, d, a, x[12], 20, 0x8d2a4c8a);
|
||||||
|
|
||||||
/* Round 3 */
|
/* 第 3 轮:HH */
|
||||||
STEP(H, a, b, c, d, x[ 5], 4, 0xfffa3942);
|
STEP(H, a, b, c, d, x[ 5], 4, 0xfffa3942);
|
||||||
STEP(H, d, a, b, c, x[ 8], 11, 0x8771f681);
|
STEP(H, d, a, b, c, x[ 8], 11, 0x8771f681);
|
||||||
STEP(H, c, d, a, b, x[11], 16, 0x6d9d6122);
|
STEP(H, c, d, a, b, x[11], 16, 0x6d9d6122);
|
||||||
|
|
@ -106,7 +129,7 @@ LOCAL void md5_transform(uint32_t state[4], const unsigned char block[64])
|
||||||
STEP(H, c, d, a, b, x[15], 16, 0x1fa27cf8);
|
STEP(H, c, d, a, b, x[15], 16, 0x1fa27cf8);
|
||||||
STEP(H, b, c, d, a, x[ 2], 23, 0xc4ac5665);
|
STEP(H, b, c, d, a, x[ 2], 23, 0xc4ac5665);
|
||||||
|
|
||||||
/* Round 4 */
|
/* 第 4 轮:II */
|
||||||
STEP(I, a, b, c, d, x[ 0], 6, 0xf4292244);
|
STEP(I, a, b, c, d, x[ 0], 6, 0xf4292244);
|
||||||
STEP(I, d, a, b, c, x[ 7], 10, 0x432aff97);
|
STEP(I, d, a, b, c, x[ 7], 10, 0x432aff97);
|
||||||
STEP(I, c, d, a, b, x[14], 15, 0xab9423a7);
|
STEP(I, c, d, a, b, x[14], 15, 0xab9423a7);
|
||||||
|
|
@ -124,48 +147,75 @@ LOCAL void md5_transform(uint32_t state[4], const unsigned char block[64])
|
||||||
STEP(I, c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
|
STEP(I, c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
|
||||||
STEP(I, b, c, d, a, x[ 9], 21, 0xeb86d391);
|
STEP(I, b, c, d, a, x[ 9], 21, 0xeb86d391);
|
||||||
|
|
||||||
|
/* 累加回状态寄存器 */
|
||||||
state[0] += a;
|
state[0] += a;
|
||||||
state[1] += b;
|
state[1] += b;
|
||||||
state[2] += c;
|
state[2] += c;
|
||||||
state[3] += d;
|
state[3] += d;
|
||||||
|
|
||||||
|
/* 清零敏感数据,防止泄漏 */
|
||||||
memset(x, 0, sizeof(x));
|
memset(x, 0, sizeof(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 公开 API
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化 MD5 上下文,设置标准魔数值
|
||||||
|
*/
|
||||||
void md5_start(stru_md5_ctx *ctx)
|
void md5_start(stru_md5_ctx *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx) { return; }
|
if (!ctx)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->count[0] = 0;
|
ctx->count[0] = 0;
|
||||||
ctx->count[1] = 0;
|
ctx->count[1] = 0;
|
||||||
|
|
||||||
|
/* RFC 1321 标准魔数 */
|
||||||
ctx->state[0] = 0x67452301;
|
ctx->state[0] = 0x67452301;
|
||||||
ctx->state[1] = 0xefcdab89;
|
ctx->state[1] = 0xefcdab89;
|
||||||
ctx->state[2] = 0x98badcfe;
|
ctx->state[2] = 0x98badcfe;
|
||||||
ctx->state[3] = 0x10325476;
|
ctx->state[3] = 0x10325476;
|
||||||
|
|
||||||
memset(ctx->buf, 0, sizeof(ctx->buf));
|
memset(ctx->buf, 0, sizeof(ctx->buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 输入数据(支持分多次调用)
|
||||||
|
* @detail 先填满内部 64 字节缓冲区,再按 512 位块进行变换。
|
||||||
|
*/
|
||||||
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len)
|
void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
if (!ctx || !data || len <= 0) { return; }
|
if (!ctx || !data || len <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当前缓冲区偏移 */
|
||||||
unsigned idx = (unsigned)((ctx->count[0] >> 3) & 0x3F);
|
unsigned idx = (unsigned)((ctx->count[0] >> 3) & 0x3F);
|
||||||
unsigned ilen = (unsigned)len;
|
unsigned ilen = (unsigned)len;
|
||||||
|
|
||||||
|
/* 更新位计数(低 32 + 高 32) */
|
||||||
if ((ctx->count[0] += ((uint32_t)ilen << 3)) < ((uint32_t)ilen << 3))
|
if ((ctx->count[0] += ((uint32_t)ilen << 3)) < ((uint32_t)ilen << 3))
|
||||||
{
|
{
|
||||||
ctx->count[1]++;
|
ctx->count[1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->count[1] += (uint32_t)(ilen >> 29);
|
ctx->count[1] += (uint32_t)(ilen >> 29);
|
||||||
|
|
||||||
unsigned avail = 64 - idx;
|
unsigned avail = 64 - idx;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
|
/* 如果输入足够填满剩余缓冲空间 */
|
||||||
if (ilen >= avail)
|
if (ilen >= avail)
|
||||||
{
|
{
|
||||||
memcpy(&ctx->buf[idx], data, avail);
|
memcpy(&ctx->buf[idx], data, avail);
|
||||||
md5_transform(ctx->state, ctx->buf);
|
md5_transform(ctx->state, ctx->buf);
|
||||||
|
|
||||||
|
/* 处理完整 64 字节块 */
|
||||||
for (i = avail; i + 63 < ilen; i += 64)
|
for (i = avail; i + 63 < ilen; i += 64)
|
||||||
{
|
{
|
||||||
md5_transform(ctx->state, &data[i]);
|
md5_transform(ctx->state, &data[i]);
|
||||||
|
|
@ -174,31 +224,52 @@ void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len)
|
||||||
idx = 0;
|
idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 剩余不足一块的数据暂存缓冲区 */
|
||||||
memcpy(&ctx->buf[idx], &data[i], ilen - i);
|
memcpy(&ctx->buf[idx], &data[i], ilen - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 完成计算,输出 16 字节 MD5 摘要
|
||||||
|
* @detail 填充 0x80 + 零 + 8 字节位计数 → 最终变换 → 小端输出
|
||||||
|
*/
|
||||||
void md5_final(stru_md5_ctx *ctx, unsigned char result[16])
|
void md5_final(stru_md5_ctx *ctx, unsigned char result[16])
|
||||||
{
|
{
|
||||||
if (!ctx || !result) { return; }
|
if (!ctx || !result)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char bits[8];
|
unsigned char bits[8];
|
||||||
|
|
||||||
|
/* 保存位计数(小端 8 字节) */
|
||||||
md5_encode(bits, ctx->count, 8);
|
md5_encode(bits, ctx->count, 8);
|
||||||
|
|
||||||
|
/* 计算填充字节数(总填充后长度 = 56 mod 64) */
|
||||||
unsigned idx = (unsigned)((ctx->count[0] >> 3) & 0x3F);
|
unsigned idx = (unsigned)((ctx->count[0] >> 3) & 0x3F);
|
||||||
unsigned pad = (idx < 56) ? (56 - idx) : (120 - idx);
|
unsigned pad = (idx < 56) ? (56 - idx) : (120 - idx);
|
||||||
|
|
||||||
static unsigned char padding[64] = { 0x80, 0 };
|
static unsigned char padding[64] = { 0x80, 0 };
|
||||||
|
|
||||||
|
/* 先填充分隔符 + 零,再追加位计数 */
|
||||||
md5_update(ctx, padding, (int)pad);
|
md5_update(ctx, padding, (int)pad);
|
||||||
md5_update(ctx, bits, 8);
|
md5_update(ctx, bits, 8);
|
||||||
|
|
||||||
|
/* 输出 16 字节摘要(小端) */
|
||||||
md5_encode(result, ctx->state, 16);
|
md5_encode(result, ctx->state, 16);
|
||||||
|
|
||||||
|
/* 清零上下文(安全清理) */
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 单次调用:计算字符串的 MD5 并返回大写十六进制字符串
|
||||||
|
*/
|
||||||
void md5_string(const char *input, char output[33])
|
void md5_string(const char *input, char output[33])
|
||||||
{
|
{
|
||||||
if (!input || !output) { return; }
|
if (!input || !output)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
stru_md5_ctx ctx;
|
stru_md5_ctx ctx;
|
||||||
unsigned char digest[16];
|
unsigned char digest[16];
|
||||||
|
|
@ -213,5 +284,8 @@ void md5_string(const char *input, char output[33])
|
||||||
}
|
}
|
||||||
|
|
||||||
output[32] = '\0';
|
output[32] = '\0';
|
||||||
|
|
||||||
|
/* 清理敏感数据 */
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
memset(digest, 0, sizeof(digest));
|
memset(digest, 0, sizeof(digest));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* @file myTask.h
|
* @file myTask.h
|
||||||
* @brief Task framework: timers + events + message queues (C interface)
|
* @brief 任务框架接口 — 定时器 + 事件 + 消息队列(C 接口)
|
||||||
* @details Based on SPEC §8 analysis. Uses C++ internally.
|
* @details 基于 SPEC §8 原工程分析。
|
||||||
|
* 定时器基于 timerfd + epoll 实现,精确到毫秒。
|
||||||
|
* 事件基于位图 + pthread 条件变量实现。
|
||||||
|
* 消息队列基于环形缓冲区 + 互斥锁 + 条件变量实现。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MY_TASK_H_
|
#ifndef _MY_TASK_H_
|
||||||
#define _MY_TASK_H_
|
#define _MY_TASK_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -14,130 +18,219 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Opaque handles
|
* 通用定义
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
typedef struct stru_task_timer *stru_task_timer_t;
|
/** 定时器回调函数类型 */
|
||||||
typedef struct stru_task_event *stru_task_event_t;
|
typedef void (*timer_func_cb)(void *arg);
|
||||||
typedef struct stru_task_msg_queue *stru_task_msg_queue_t;
|
|
||||||
|
/** 不透明句柄类型 */
|
||||||
|
typedef void *stru_task_timer_t;
|
||||||
|
typedef void *stru_task_event_t;
|
||||||
|
typedef void *stru_task_msg_queue_t;
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Timer callback — returns 0 to continue, non-zero to stop
|
* 定时器标志
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
typedef int (*timer_func_cb)(void *arg);
|
/** 单次触发(到期后自动停止) */
|
||||||
|
#define TASK_TIMER_FLAG_ONCE 0x01
|
||||||
|
|
||||||
/* Timer flags */
|
/** 周期触发(到期后自动重新计时) */
|
||||||
#define TIMER_ONCE 0 /* one-shot */
|
#define TASK_TIMER_FLAG_PERIODIC 0x02
|
||||||
#define TIMER_PERIOD 1 /* periodic */
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Timer API (SPEC T01-T07)
|
* 事件等待方式
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
/** 永久等待(不超时) */
|
||||||
|
#define TASK_EVENT_WAIT_FOREVER 0xFFFFFFFF
|
||||||
|
|
||||||
|
/** 事件标记:等待所有位都置位(AND 模式) */
|
||||||
|
#define TASK_EVENT_FLAG_AND 0x01
|
||||||
|
|
||||||
|
/** 事件标记:等待任意位置位(OR 模式) */
|
||||||
|
#define TASK_EVENT_FLAG_OR 0x02
|
||||||
|
|
||||||
|
/** 事件标记:接收后自动清除已匹配的位 */
|
||||||
|
#define TASK_EVENT_FLAG_CLEAR 0x04
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 通用延时
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a timer (does not start automatically)
|
* @brief 任务延时(毫秒级阻塞等待)
|
||||||
* @param name timer name for debugging
|
* @param ms 延时毫秒数
|
||||||
* @param cb callback function
|
|
||||||
* @param arg user argument passed to callback
|
|
||||||
* @param timeout_ms interval in milliseconds
|
|
||||||
* @param flags TIMER_ONCE or TIMER_PERIOD
|
|
||||||
* @return timer handle, NULL on failure
|
|
||||||
*/
|
*/
|
||||||
stru_task_timer_t task_timer_create(const char *name, timer_func_cb cb,
|
void task_sleep_ms(uint32_t ms);
|
||||||
void *arg, uint32_t timeout_ms, int flags);
|
|
||||||
|
|
||||||
/** Start the timer */
|
|
||||||
int task_timer_start(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/** Stop the timer */
|
|
||||||
int task_timer_stop(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/** Restart with new interval */
|
|
||||||
int task_timer_restart(stru_task_timer_t pt, uint32_t timeout_ms);
|
|
||||||
|
|
||||||
/** Destroy and free the timer */
|
|
||||||
int task_timer_destroy(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/** Check if timer is currently active */
|
|
||||||
int task_timer_is_active(stru_task_timer_t pt);
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Event API (SPEC T08-T13)
|
* 事件 API
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
#define EVENT_OPT_AND 0 /* wait for ALL bits set */
|
|
||||||
#define EVENT_OPT_OR 1 /* wait for ANY bit set */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an event object
|
* @brief 创建事件对象
|
||||||
* @param name event name for debugging
|
* @param name 事件名称(调试用)
|
||||||
* @return event handle, NULL on failure
|
* @return 事件句柄,失败返回 NULL
|
||||||
*/
|
*/
|
||||||
stru_task_event_t task_event_create(const char *name);
|
stru_task_event_t task_event_create(const char *name);
|
||||||
|
|
||||||
/** Destroy event object */
|
/**
|
||||||
int task_event_destroy(stru_task_event_t pe);
|
* @brief 销毁事件对象
|
||||||
|
* @param p_event 事件句柄
|
||||||
/** Set (send) event bits */
|
* @return 0 成功,-1 失败
|
||||||
int task_event_send(stru_task_event_t pe, uint32_t bits);
|
*/
|
||||||
|
int task_event_destroy(stru_task_event_t p_event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wait for event bits
|
* @brief 发送事件(设置事件位)
|
||||||
* @param pe event handle
|
* @param p_event 事件句柄
|
||||||
* @param set bits to wait for
|
* @param event 要设置的事件位掩码
|
||||||
* @param opt EVENT_OPT_AND or EVENT_OPT_OR
|
* @return 0 成功,-1 失败
|
||||||
* @param timeout_ms timeout in ms (0 = forever)
|
|
||||||
* @param recved [out] bits actually received
|
|
||||||
* @return 0 on success, -1 on timeout
|
|
||||||
*/
|
*/
|
||||||
int task_event_recv(stru_task_event_t pe, uint32_t set, uint32_t opt,
|
int task_event_send(stru_task_event_t p_event, uint32_t event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待事件
|
||||||
|
* @param p_event 事件句柄
|
||||||
|
* @param set 期望的事件位掩码
|
||||||
|
* @param opt 等待选项(TASK_EVENT_FLAG_AND/OR/CLEAR 组合)
|
||||||
|
* @param timeout_ms 超时时间(毫秒,TASK_EVENT_WAIT_FOREVER=永久等待)
|
||||||
|
* @param recved 输出参数:实际收到的事件位
|
||||||
|
* @return 0 成功,-1 超时或失败
|
||||||
|
*/
|
||||||
|
int task_event_recv(stru_task_event_t p_event, uint32_t set, uint32_t opt,
|
||||||
uint32_t timeout_ms, uint32_t *recved);
|
uint32_t timeout_ms, uint32_t *recved);
|
||||||
|
|
||||||
/** Clear specific event bits */
|
/**
|
||||||
int task_event_clear(stru_task_event_t pe, uint32_t bits);
|
* @brief 清除事件位
|
||||||
|
* @param p_event 事件句柄
|
||||||
|
* @param event 要清除的事件位掩码
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_event_clear(stru_task_event_t p_event, uint32_t event);
|
||||||
|
|
||||||
/** Query current event bits (non-blocking) */
|
/**
|
||||||
uint32_t task_event_query(stru_task_event_t pe);
|
* @brief 查询当前事件位(非阻塞)
|
||||||
|
* @param p_event 事件句柄
|
||||||
|
* @return 当前事件位掩码
|
||||||
|
*/
|
||||||
|
uint32_t task_event_query(stru_task_event_t p_event);
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Message Queue API (SPEC T14-T21)
|
* 消息队列 API
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a fixed-size message queue
|
* @brief 创建定长消息队列
|
||||||
* @param name queue name
|
* @param name 队列名称(调试用)
|
||||||
* @param msg_size max size of each message (bytes)
|
* @param msg_size 每条消息的最大字节数
|
||||||
* @param msg_num max number of messages
|
* @param msg_num 队列容量(最大消息条数)
|
||||||
* @return queue handle, NULL on failure
|
* @return 队列句柄,失败返回 NULL
|
||||||
*/
|
*/
|
||||||
stru_task_msg_queue_t task_msg_queue_create(const char *name,
|
stru_task_msg_queue_t task_msg_queue_create(const char *name,
|
||||||
uint32_t msg_size, uint32_t msg_num);
|
uint32_t msg_size, uint32_t msg_num);
|
||||||
|
|
||||||
/** Destroy message queue */
|
/**
|
||||||
int task_msg_queue_destroy(stru_task_msg_queue_t pq);
|
* @brief 销毁消息队列
|
||||||
|
* @param p_queue 队列句柄
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_destroy(stru_task_msg_queue_t p_queue);
|
||||||
|
|
||||||
/** Send message (blocking if queue full) */
|
/**
|
||||||
int task_msg_queue_send(stru_task_msg_queue_t pq, const void *msg, uint32_t size);
|
* @brief 发送消息(队列满时阻塞等待)
|
||||||
|
* @param p_queue 队列句柄
|
||||||
|
* @param msg 消息内容指针
|
||||||
|
* @param size 消息实际字节数(<= msg_size)
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_send(stru_task_msg_queue_t p_queue, const void *msg,
|
||||||
|
uint32_t size);
|
||||||
|
|
||||||
/** Send message with timeout (ms), returns -1 on timeout */
|
/**
|
||||||
int task_msg_queue_send_timeout(stru_task_msg_queue_t pq, const void *msg,
|
* @brief 发送消息(带超时)
|
||||||
|
* @param timeout_ms 超时时间(毫秒,TASK_EVENT_WAIT_FOREVER=永久等待)
|
||||||
|
* @return 0 成功,-1 超时或失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_send_timeout(stru_task_msg_queue_t p_queue, const void *msg,
|
||||||
uint32_t size, uint32_t timeout_ms);
|
uint32_t size, uint32_t timeout_ms);
|
||||||
|
|
||||||
/** Receive message with timeout (ms), returns -1 on timeout */
|
/**
|
||||||
int task_msg_queue_recv(stru_task_msg_queue_t pq, void *msg, uint32_t size,
|
* @brief 接收消息(带超时)
|
||||||
uint32_t timeout_ms);
|
* @param timeout_ms 超时时间(毫秒,TASK_EVENT_WAIT_FOREVER=永久等待)
|
||||||
|
* @return 0 成功,-1 超时或失败
|
||||||
|
*/
|
||||||
|
int task_msg_queue_recv(stru_task_msg_queue_t p_queue, void *msg,
|
||||||
|
uint32_t size, uint32_t timeout_ms);
|
||||||
|
|
||||||
/** Try receive (non-blocking), returns 0 on success, -1 if empty */
|
/**
|
||||||
int task_msg_queue_try_recv(stru_task_msg_queue_t pq, void *msg, uint32_t size);
|
* @brief 尝试接收消息(非阻塞,队列空立即返回 -1)
|
||||||
|
* @return 0 成功,-1 队列空
|
||||||
|
*/
|
||||||
|
int task_msg_queue_try_recv(stru_task_msg_queue_t p_queue, void *msg,
|
||||||
|
uint32_t size);
|
||||||
|
|
||||||
/** Get number of messages currently in queue */
|
/**
|
||||||
uint32_t task_msg_queue_get_count(stru_task_msg_queue_t pq);
|
* @brief 获取队列中当前消息数
|
||||||
|
*/
|
||||||
|
uint32_t task_msg_queue_get_count(stru_task_msg_queue_t p_queue);
|
||||||
|
|
||||||
/** Get free space in queue */
|
/**
|
||||||
uint32_t task_msg_queue_space(stru_task_msg_queue_t pq);
|
* @brief 获取队列剩余可用空间(条数)
|
||||||
|
*/
|
||||||
|
uint32_t task_msg_queue_space(stru_task_msg_queue_t p_queue);
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 定时器 API
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建定时器(创建后不会自动启动,需调用 task_timer_start)
|
||||||
|
* @param name 定时器名称(调试用)
|
||||||
|
* @param fun_cb 到期回调函数
|
||||||
|
* @param arg 回调参数
|
||||||
|
* @param timeout_ms 定时周期(毫秒)
|
||||||
|
* @param flags 标志位(TASK_TIMER_FLAG_ONCE 或 TASK_TIMER_FLAG_PERIODIC)
|
||||||
|
* @return 定时器句柄,失败返回 NULL
|
||||||
|
*/
|
||||||
|
stru_task_timer_t task_timer_create(const char *name, timer_func_cb fun_cb,
|
||||||
|
void *arg, uint32_t timeout_ms, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动定时器
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_start(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 停止定时器
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_stop(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重启定时器(可修改周期)
|
||||||
|
* @param timeout_ms 新的定时周期(毫秒)
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_restart(stru_task_timer_t p_timer, uint32_t timeout_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 销毁定时器
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
|
int task_timer_destroy(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 查询定时器是否在运行
|
||||||
|
* @return 1=运行中,0=已停止
|
||||||
|
*/
|
||||||
|
int task_timer_is_active(stru_task_timer_t p_timer);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif /* _MY_TASK_H_ */
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue