diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..452b905 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,66 @@ +# RTU_ALL_AI API 参考文档 + +> 生成日期: 2026-07-07 +> 项目: RTU_ALL_AI — C/C++ 嵌入式通讯装置示例工程 + +--- + +## 文档索引 + +### 基础公共库 (public/) + +| 模块 | 文档 | 语言 | 说明 | +|------|------|------|------| +| myBase.h | [API-myBase.md](public/API-myBase.md) | C 头文件 | 公共宏、类型常量、字节序转换 | +| liblist | [API-liblist.md](public/liblist/API-liblist.md) | 纯 C 头文件 | 侵入式双向循环链表 | +| liblog | [API-liblog.md](public/liblog/API-liblog.md) | 纯 C | 异步日志系统 | +| libfunc | [API-libfunc.md](public/libfunc/API-libfunc.md) | 纯 C | 65 个基础工具函数 | +| libmd5 | [API-libmd5.md](public/libmd5/API-libmd5.md) | 纯 C | MD5 消息摘要 (RFC 1321) | +| libtask | [API-libtask.md](public/libtask/API-libtask.md) | 纯 C | 定时器 + 事件 + 消息队列 | +| libcJSON | [API-libcJSON.md](public/libcJSON/API-libcJSON.md) | 纯 C (开源库) | JSON 解析/生成 | +| libmy_xxhash | [API-libmy_xxhash.md](public/libmy_xxhash/API-libmy_xxhash.md) | 纯 C (开源库) | xxHash 快速哈希 | + +### 模块依赖关系图 + +``` + ┌──────────┐ + │ myBase.h │ (颜色/大小端/类型常量) + └────┬─────┘ + ┌──────────────┼──────────────┐ + ▼ ▼ ▼ + ┌─────────┐ ┌─────────┐ ┌──────────┐ + │ liblist │ │ libfunc │ │ libmd5 │ + │ (链表) │ │ (65函数)│ │ (MD5) │ + └────┬────┘ └────┬────┘ └──────────┘ + │ │ + ▼ ▼ + ┌─────────────────────────┐ + │ liblog │ (异步日志,依赖 + │ (消息池+批量+文件轮转) │ liblist + libfunc) + └─────────────────────────┘ + + ┌──────────┐ ┌──────────────┐ + │ libcJSON │ │ libmy_xxhash │ (开源库,直接使用) + └──────────┘ └──────────────┘ + + ┌────────────────────────────────┐ + │ libtask │ (事件/定时器/消息队列) + │ (timerfd + epoll + pthread) │ + └────────────────────────────────┘ +``` + +### 构建与编译 + +```bash +cd release +./build.sh # x86 本地编译 +./build.sh arm # ARM 交叉编译 +``` + +### 编码规范 + +详见项目内存 `/memories/code-style.md`: +- 一行一语句,`{}` 独占行,`}` 后空行,`return` 前空行 +- 运算符前后空格(`a + b`, `x << 8`),逗号分号后空格 +- 结构体 `stru_` 前缀,枚举 `enum_` 前缀 +- 注释使用 UTF-8 中文 diff --git a/docs/public/API-myBase.md b/docs/public/API-myBase.md new file mode 100644 index 0000000..3d0b4d6 --- /dev/null +++ b/docs/public/API-myBase.md @@ -0,0 +1,112 @@ +# myBase.h — 公共基础定义 API 参考 + +## 模块概述 + +myBase.h 是所有模块共享的基础头文件。提供通用宏、类型别名、字节序转换、数据类型常量等。 + +## 终端颜色码 + +```c +#define COLOR_RESET "\033[0m" // 重置 +#define COLOR_RED "\033[31m" // 红色 +#define COLOR_GREEN "\033[32m" // 绿色 +#define COLOR_YELLOW "\033[33m" // 黄色 +#define COLOR_BLUE "\033[34m" // 蓝色 +#define COLOR_MAGENTA "\033[35m" // 品红 +#define COLOR_CYAN "\033[36m" // 青色 +#define COLOR_WHITE "\033[37m" // 白色 +``` + +**示例**: +```c +printf(COLOR_RED "错误: %s" COLOR_RESET "\n", "连接失败"); +``` + +## 文件名缩写 + +```c +#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) +``` +自动去掉文件路径前缀,跨平台兼容(Linux 用 `/`,Windows 用 `\`)。 + +## 简易日志宏 + +```c +#define MY_LOG(color, level, fmt, ...) // 控制台日志(带颜色) +#define MY_LOG_I(fmt, ...) // INFO(白色) +#define MY_LOG_E(fmt, ...) // ERROR(红色) +``` + +## LOCAL 修饰符 + +```c +#define LOCAL static +``` +语义化表示"文件内可见",等价于 `static`。 + +## 定长字符串类型 + +```c +typedef char S_STR[64]; // 64 字节短字符串 +typedef char L_STR[128]; // 128 字节长字符串 +``` + +## 字节序转换宏 + +### uint16 + +| 宏 | 功能 | +|----|------| +| `BE16_GET(p)` | 大端字节序 → uint16 | +| `BE16_SET(m, n)` | uint16 → 大端字节序 | +| `LE16_GET(p)` | 小端字节序 → uint16 | +| `LE16_SET(m, n)` | uint16 → 小端字节序 | + +### int32 + +| 宏 | 功能 | +|----|------| +| `BE32_GET(p)` / `BE32_SET(m, n)` | 大端 int32 | +| `LE32_GET(p)` / `LE32_SET(m, n)` | 小端 int32 | + +### uint64 + +| 宏 | 功能 | +|----|------| +| `BE64_GET(p)` / `BE64_SET(m, n)` | 大端 uint64 | +| `LE64_GET(p)` / `LE64_SET(m, n)` | 小端 uint64 | + +**示例**: +```c +uint8_t buf[4] = { 0x00, 0x00, 0x00, 0xFF }; +uint32_t val = BE32_GET(buf); +printf("val = %u\n", val); // 255 +``` + +## 类型化数据存取 + +```c +#define GET_BY_TYPE(p, type) (*(type *)(p)) +#define SET_BY_TYPE(p, v, type) (*(type *)(p) = *(type *)(v)) +``` + +## 数据类型常量(22 种,用于协议编解码) + +| 常量 | 值 | 含义 | 常量 | 值 | 含义 | +|------|-----|------|------|-----|------| +| `DATA_TYPE_B` | 1 | bool | `DATA_TYPE_IP` | 100 | IP 地址 | +| `DATA_TYPE_S8` | 43 | int8 | `DATA_TYPE_MAC` | 101 | MAC 地址 | +| `DATA_TYPE_U8` | 32 | uint8 | `DATA_TYPE_C8` | 102 | char[8] | +| `DATA_TYPE_S16` | 33 | int16 | `DATA_TYPE_C32` | 103 | char[32] | +| `DATA_TYPE_U16` | 45 | uint16 | `DATA_TYPE_C64` | 104 | char[64] | +| `DATA_TYPE_S32` | 2 | int32 | `DATA_TYPE_C128` | 105 | char[128] | +| `DATA_TYPE_U32` | 35 | uint32 | `DATA_TYPE_C1` | 106 | char[1] | +| `DATA_TYPE_L64` | 36 | int64 | `DATA_TYPE_STR` | 107 | string | +| `DATA_TYPE_UL64` | 37 | uint64 | | | | +| `DATA_TYPE_F32` | 38 | float | | | | +| `DATA_TYPE_D64` | 39 | double | | | | + +## 依赖关系 + +- **依赖**: 标准 C/POSIX 头文件 +- **被依赖**: 所有模块 diff --git a/docs/public/libcJSON/API-libcJSON.md b/docs/public/libcJSON/API-libcJSON.md new file mode 100644 index 0000000..e82a3aa --- /dev/null +++ b/docs/public/libcJSON/API-libcJSON.md @@ -0,0 +1,118 @@ +# libcJSON — JSON 解析/生成库 API 参考 + +## 模块概述 + +libcJSON 是开源的轻量级 JSON 解析/生成库(MIT 许可证),直接使用原工程版本。 +基于递归下降解析器 + 树状内存模型。支持 object/array/string/number/boolean/null。 + +## 数据结构 + +```c +typedef enum +{ CJSON_NULL = 0, CJSON_FALSE, CJSON_TRUE, + CJSON_NUMBER, CJSON_STRING, CJSON_ARRAY, CJSON_OBJECT +} enum_cjson_type; + +typedef struct cjson +{ + struct cjson *next, *prev; // 兄弟节点链表 + struct cjson *child; // 子节点(对象/数组的第一个子元素) + enum_cjson_type type; + char *key; // 对象键名 + char *val_str; // 字符串值 + double val_num; // 数值 +} stru_cjson; +``` + +## 接口函数 + +### 解析与释放 + +| 函数 | 说明 | +|------|------| +| `cJSON_Parse(json)` | 解析 JSON 字符串,返回根节点 | +| `cJSON_Delete(node)` | 递归释放整棵树 | + +### 查询 + +| 函数 | 说明 | +|------|------| +| `cJSON_GetObjectItem(obj, key)` | 按 key 获取对象成员 | +| `cJSON_GetArraySize(arr)` | 获取数组长度 | +| `cJSON_GetArrayItem(arr, idx)` | 获取数组元素(0-based) | +| `cJSON_GetStringValue(it)` | 获取字符串值 | +| `cJSON_GetNumberValue(it)` | 获取数值 | + +### 创建 + +| 函数 | 说明 | +|------|------| +| `cJSON_CreateObject()` | 创建空对象 `{}` | +| `cJSON_CreateArray()` | 创建空数组 `[]` | +| `cJSON_CreateString(s)` | 创建字符串节点 | +| `cJSON_CreateNumber(n)` | 创建数值节点 | +| `cJSON_CreateBool(b)` | 创建 true/false | +| `cJSON_CreateNull()` | 创建 null | + +### 修改 + +| 函数 | 说明 | +|------|------| +| `cJSON_AddItemToObject(obj, key, item)` | 向对象添加键值对 | +| `cJSON_AddItemToArray(arr, item)` | 向数组追加元素 | +| `cJSON_DeleteItemFromObject(obj, key)` | 删除对象成员 | + +### 序列化 + +| 函数 | 说明 | +|------|------| +| `cJSON_Print(node)` | 序列化为紧凑 JSON 字符串(调用者 free) | + +## 使用示例 + +```c +#include "cJSON.h" +#include +#include + +int main(void) +{ + // --- 解析 JSON --- + const char *json = "{\"name\":\"RTU\",\"addr\":1,\"items\":[1,2,3]}"; + stru_cjson *root = cJSON_Parse(json); + + const char *name = cJSON_GetStringValue(cJSON_GetObjectItem(root, "name")); + double addr = cJSON_GetNumberValue(cJSON_GetObjectItem(root, "addr")); + + printf("name=%s, addr=%.0f\n", name, addr); + // 输出: name=RTU, addr=1 + + // 遍历数组 + stru_cjson *arr = cJSON_GetObjectItem(root, "items"); + int n = cJSON_GetArraySize(arr); + for (int i = 0; i < n; i++) + { + printf(" [%d] = %.0f\n", i, + cJSON_GetNumberValue(cJSON_GetArrayItem(arr, i))); + } + + cJSON_Delete(root); + + // --- 创建 JSON --- + stru_cjson *obj = cJSON_CreateObject(); + cJSON_AddItemToObject(obj, "status", cJSON_CreateString("ok")); + cJSON_AddItemToObject(obj, "code", cJSON_CreateNumber(200)); + + char *out = cJSON_Print(obj); + printf("生成的 JSON: %s\n", out); // {"status":"ok","code":200} + free(out); + cJSON_Delete(obj); + + return 0; +} +``` + +## 依赖关系 + +- **依赖**: `stdlib.h`, `string.h`, `stdio.h`, `math.h` +- **被依赖**: 配置文件解析、Web API 交互 等模块 diff --git a/docs/public/libfunc/API-libfunc.md b/docs/public/libfunc/API-libfunc.md new file mode 100644 index 0000000..8087c29 --- /dev/null +++ b/docs/public/libfunc/API-libfunc.md @@ -0,0 +1,153 @@ +# libfunc — 基础工具函数 API 参考 + +## 模块概述 + +libfunc 提供嵌入式开发中最常用的 65 个基础工具函数,分为 7 大类: +1. 校验计算 +2. 字符串转换 +3. 时间处理 +4. 文件目录操作 +5. 进程管理 +6. 环境变量路径 +7. IPC 消息队列 + +## 一、校验计算 (6 函数) + +| 函数 | 说明 | +|------|------| +| `func_cal_sum_byte(d, n)` | 8 位累加校验和 | +| `func_cal_sum_word(d, n)` | 16 位累加校验和 | +| `func_cal_crc16(d, n)` | CRC16 (Modbus 多项式 0xA001) | +| `func_cal_crc32(d, n)` | CRC32 (标准多项式) | +| `func_cal_file_crc16(path)` | 文件 CRC16(4K 缓冲区流式计算) | +| `func_cal_file_crc32(path)` | 文件 CRC32 | + +**示例**: +```c +uint8_t d[] = { 0x01, 0x02, 0x03 }; +uint16_t crc = func_cal_crc16(d, 3); +printf("CRC16 = 0x%04X\n", crc); // 0x6161 +``` + +## 二、字符串转换 (10 函数) + +| 函数 | 参数 | 说明 | +|------|------|------| +| `func_hex_ch(c)` | char c | 十六进制字符 → 数值 | +| `func_dec_ch(c)` | char c | 十进制字符 → 数值 | +| `func_hex2dec(s)` | char *s | "FF" → 255 | +| `func_dec2dec(s)` | char *s | "255" → 255(支持负号) | +| `func_hex2buf(s, dst, len)` | 3 参数 | 十六进制字符串 → 字节缓冲 | +| `func_dec2str(buf, sz, val, w)` | 4 参数 | int → 十进制字符串 | +| `func_hex2str(buf, sz, val, w)` | 4 参数 | int → 十六进制字符串 | +| `func_float2str(buf, sz, f, w)` | 4 参数 | float → 字符串 | +| `func_buf2str(buf, sz, src, n)` | 4 参数 | 字节数组 → 十六进制字符串 | +| `func_str2argv(s, argc, argv, max)` | 4 参数 | 按空格分割为 argc/argv | + +**示例**: +```c +char buf[64]; +func_dec2str(buf, sizeof(buf), 255, 4); +printf("%s\n", buf); // "0255" + +func_hex2str(buf, sizeof(buf), 255, 0); +printf("%s\n", buf); // "FF" +``` + +## 三、时间处理 (6 函数) + +| 函数 | 说明 | +|------|------| +| `func_time_sys2str(buf, sz, ts)` | 系统时间 → "YYYY-MM-DD HH:MM:SS.mmm" | +| `func_str2time_sys(s, ts)` | 字符串 → 系统时间 | +| `func_get_time(t, type)` | 获取当前时间(type: 1=sys, 2=cal) | +| `func_set_time(t, type)` | 设置系统时间(需 root) | +| `func_time_sys2cal(src, dst)` | 系统时间 → 日历时间 | +| `func_time_cal2sys(src, dst)` | 日历时间 → 系统时间 | + +## 四、文件目录操作 (11 函数) + +| 函数 | 说明 | +|------|------| +| `func_dir_exist(p)` | 目录是否存在 | +| `func_make_dirs(p)` | 递归创建目录 | +| `func_del_dirs(p)` | 递归删除目录 | +| `func_del_dirs_cmd(p)` | 系统命令删除(rm -rf) | +| `func_file_exist(p)` | 文件是否存在 | +| `func_file_size(p)` | 获取文件大小(字节) | +| `func_read_file(p, buf, cap, out)` | 读文件到预分配缓冲 | +| `func_read_file_alloc(p, out)` | 读文件到动态分配缓冲 | +| `func_write_file(p, buf, n)` | 写缓冲到文件 | +| `func_read_file_info(p, info, check)` | 读结构化文件头(256B, CRC 校验) | + +**示例**: +```c +// 创建目录 +func_make_dirs("/tmp/myapp/config"); + +// 读取文件 +uint32_t size = 0; +uint8_t *buf = func_read_file_alloc("/tmp/test.txt", &size); +if (buf) +{ + printf("Read %u bytes: %s\n", size, buf); + free(buf); +} +``` + +## 五、进程管理 (9 函数) + +| 函数 | 说明 | +|------|------| +| `func_proc_self_name(buf, sz)` | 获取本进程名(读 /proc/self/comm) | +| `func_proc_name_by_pid(pid, buf, sz)` | PID → 进程名 | +| `func_proc_pid()` | 获取本进程 PID | +| `func_proc_pid_by_name(name)` | 进程名 → PID | +| `func_proc_exist_by_pid(pid)` | 按 PID 判断进程存在 | +| `func_proc_exist_by_name(name)` | 按名称判断进程存在 | +| `func_proc_path_by_pid(pid, buf, sz)` | PID → 可执行文件路径 | +| `func_proc_self_path(buf, sz)` | 本进程路径 | +| `func_proc_self_dir(buf, sz)` | 本进程目录 | + +## 六、环境变量路径 (12 函数) + +| 函数 | 环境变量 | +|------|---------| +| `func_get_work_path(..)` | WORK_PATH | +| `func_get_syscfg_path(..)` | SYS_CFG_PATH | +| `func_get_app_root(..)` | APP_ROOT_PATH | +| `func_get_his_root(..)` | HIS_ROOT_PATH | +| `func_get_log_root(..)` | LOG_ROOT_PATH | +| `func_get_dbc_root(..)` | DBC_ROOT_PATH | +| `func_get_shell_path(..)` | SHELL_PATH | +| `func_get_update_path(..)` | UPDATE_PATH | +| `func_get_app_path(app, ..)` | 拼接: APP_ROOT/app | +| `func_get_app_cfg(app, ext, ..)` | 拼接: APP_ROOT/app/ext | +| `func_get_app_his(app, ..)` | 拼接: HIS_ROOT/app | +| `func_get_app_log(app, ..)` | 拼接: LOG_ROOT/app | + +**示例**: +```c +char path[256]; +func_get_app_cfg("RTU", "config.json", path, sizeof(path)); +printf("Config path: %s\n", path); // /opt/RTU/config.json +``` + +## 七、IPC 消息队列 (9 函数) + +| 函数 | 说明 | +|------|------| +| `func_ipc_create_by_name(name, qid)` | 按名称创建 System V 消息队列 | +| `func_ipc_create_by_pid(pid, qid)` | 按 PID 创建 | +| `func_ipc_get_by_name(name, qid)` | 按名称获取 | +| `func_ipc_get_by_pid(pid, qid)` | 按 PID 获取 | +| `func_ipc_send_buf(qid, tx, n)` | 发送原始字节 | +| `func_ipc_recv_buf(qid, rx, n)` | 接收原始字节 | +| `func_ipc_send_msg(qid, msg)` | 发送结构体消息 | +| `func_ipc_recv_msg(qid, msg)` | 接收结构体消息 | +| `func_ipc_delete(qid)` | 删除队列 | + +## 依赖关系 + +- **依赖**: myBase.h +- **被依赖**: liblog (进程路径), 所有需要 CRC/文件/进程操作的模块 diff --git a/docs/public/liblist/API-liblist.md b/docs/public/liblist/API-liblist.md new file mode 100644 index 0000000..c9cf3d2 --- /dev/null +++ b/docs/public/liblist/API-liblist.md @@ -0,0 +1,189 @@ +# liblist — 侵入式双向循环链表 API 参考 + +## 模块概述 + +liblist 是 Linux 内核风格的双向循环链表,纯头文件实现,C/C++ 兼容。 +所有增删操作 O(1),遍历 O(n)。核心思想:将 `struct list_head` 嵌入宿主结构体, +通过 `offsetof` 从链表节点指针反推宿主指针。 + +## 数据结构 + +```c +struct list_head +{ + struct list_head *next; // 后继节点 + struct list_head *prev; // 前驱节点 +}; +``` + +## 接口函数 + +### 初始化 + +#### LIST_HEAD(name) +```c +#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) +``` +编译期定义并初始化一个链表头。 + +**示例**: +```c +LIST_HEAD(my_list); // 定义 my_list 并初始化为空链表 +``` + +#### INIT_LIST_HEAD(h) +```c +void INIT_LIST_HEAD(struct list_head *h); +``` +运行时初始化一个已存在的链表头。 + +**示例**: +```c +struct list_head head; +INIT_LIST_HEAD(&head); +``` + +### 添加 + +#### list_add(node, head) +头插法:将 node 插入到 head 之后(作为第一个元素)。 + +```c +void list_add(struct list_head *node, struct list_head *head); +``` + +#### list_add_tail(node, head) +尾插法:将 node 插入到 head 之前(作为最后一个元素)。 + +```c +void list_add_tail(struct list_head *node, struct list_head *head); +``` + +### 删除 + +#### list_del(entry) +从链表中移除节点(不释放内存)。 + +#### list_del_init(entry) +移除节点并重新初始化为自环,防止后续误操作导致悬空指针。 + +### 移动 + +#### list_move(list, head) +将节点移动到新链表头部。 + +#### list_move_tail(list, head) +将节点移动到新链表尾部。 + +### 替换 + +#### list_replace(old, node) +用 node 替换 old 的位置。 + +#### list_replace_init(old, node) +替换后初始化被替换节点。 + +### 判断 + +#### list_empty(head) +判断链表是否为空(头节点的 next 指向自身即为空)。 + +#### list_is_linked(entry) +判断节点是否已链入某个链表(非自环即为已链接)。 + +### 节点转宿主 + +#### list_entry(ptr, type, member) +```c +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr) - offsetof(type, member))) +``` +从链表节点指针取回宿主结构体指针。 + +#### list_first_entry(head, type, member) +获取第一个宿主元素。 + +#### list_last_entry(head, type, member) +获取最后一个宿主元素。 + +#### list_first_entry_or_null(head, type, member) +安全获取第一个元素(链表空返回 NULL)。 + +### 遍历 + +#### list_for_each(pos, head) +遍历链表节点(仅获取 `struct list_head *` 指针)。 + +#### list_for_each_safe(pos, n, head) +安全遍历(可在遍历中删除当前节点 pos)。 + +#### list_for_each_entry(pos, head, member) +遍历宿主元素,最常用。 + +#### list_for_each_entry_safe(pos, n, head, member) +安全遍历宿主元素(可在遍历中删除 pos)。 + +### 拼接 + +#### list_splice_init(src, dst) +将 src 链表拼接到 dst 头部,src 被清空。 + +## 使用示例 + +```c +#include "myBase.h" +#include "list.h" + +// 定义宿主结构体 +struct sensor +{ + int id; + float value; + struct list_head node; // 嵌入的链表节点 +}; + +int main(void) +{ + // 定义链表头 + LIST_HEAD(sensor_list); + + // 创建 3 个传感器 + struct sensor s1 = { .id = 1, .value = 25.5 }; + struct sensor s2 = { .id = 2, .value = 30.0 }; + struct sensor s3 = { .id = 3, .value = 22.1 }; + + // 尾插 + list_add_tail(&s1.node, &sensor_list); + list_add_tail(&s2.node, &sensor_list); + list_add_tail(&s3.node, &sensor_list); + + // 遍历并打印 + struct sensor *pos; + list_for_each_entry(pos, &sensor_list, node) + { + printf("sensor %d: %.1f\n", pos->id, pos->value); + } + // 输出: + // sensor 1: 25.5 + // sensor 2: 30.0 + // sensor 3: 22.1 + + // 安全删除所有节点 + struct sensor *tmp; + list_for_each_entry_safe(pos, tmp, &sensor_list, node) + { + printf("removing sensor %d\n", pos->id); + list_del(&pos->node); + free(pos); // 如果是动态分配的 + } + + printf("list empty: %d\n", list_empty(&sensor_list)); // 1 + + return 0; +} +``` + +## 依赖关系 + +- **依赖**: `` (offsetof) +- **被依赖**: liblog, libdatacenter, 所有需要链表管理的模块 diff --git a/docs/public/liblog/API-liblog.md b/docs/public/liblog/API-liblog.md new file mode 100644 index 0000000..32fdf48 --- /dev/null +++ b/docs/public/liblog/API-liblog.md @@ -0,0 +1,106 @@ +# liblog — 异步日志系统 API 参考 + +## 模块概述 + +liblog 是嵌入式装置专用的异步日志系统。支持 INFO/ERROR 两级日志,非阻塞写入。 +首次调用自动初始化(pthread_once 懒启动)。控制台支持 ANSI 彩色输出, +文件支持按大小自动轮转。 + +**核心特性**: +- **消息池预分配**:10000 条消息槽位,运行时零 malloc +- **批量消费**:工作线程每次最多取 100 条,批量 I/O 减少系统调用 +- **生产者-消费者模型**:`log_prt()` 入队(生产者)→ 工作线程出队写入(消费者) +- **文件轮转**:单文件超过 10MB 自动重命名为 `.1 → .2 → ... → .5` + +## 常量与宏 + +| 宏 | 值 | 说明 | +|----|-----|------| +| `LOG_INFO` | 0 | INFO 级别(白色) | +| `LOG_ERROR` | 1 | ERROR 级别(红色) | +| `LOG_I(fmt, ...)` | — | INFO 便捷宏(自动填充文件名/函数名/行号) | +| `LOG_E(fmt, ...)` | — | ERROR 便捷宏 | + +## 接口函数 + +### log_init(dir) +```c +int log_init(const char *dir); +``` +手动初始化日志系统(可选)。首次调用 `log_prt()` 时会自动触发。 +- `dir`: 日志目录路径,`NULL` 则默认 `/tmp/logs` +- 返回: 0 成功 + +### log_prt(level, file, func, line, fmt, ...) +```c +void log_prt(uint32_t level, const char *file, const char *func, + uint32_t line, const char *fmt, ...); +``` +核心日志函数(非阻塞)。从消息池取空闲块 → 填充时间/来源 → 入队 → 立即返回。 + +**参数**: +- `level`: `LOG_INFO` 或 `LOG_ERROR` +- `file`: `__FILE__`(源文件名) +- `func`: `__FUNCTION__`(函数名) +- `line`: `__LINE__`(行号) +- `fmt, ...`: printf 格式化 + +### log_file_on / log_file_off +```c +void log_file_on(void); +void log_file_off(void); +``` +开启/关闭文件写入。默认关闭,通过 `log_init()` 开启。 + +### log_console_on / log_console_off +```c +void log_console_on(void); +void log_console_off(void); +``` +开启/关闭控制台输出。默认开启。 + +### log_flush(void) +```c +void log_flush(void); +``` +阻塞等待消息队列清空(所有日志写入完成)。 + +### log_cleanup(void) +```c +void log_cleanup(void); +``` +停止工作线程、关闭文件句柄、释放消息池。 + +## 使用示例 + +```c +#include "myLog.h" + +int main(void) +{ + // 手动初始化(可选),指定日志目录 + log_init("/var/log/myapp"); + + // INFO 日志 + LOG_I("系统启动完成, CPU=%.1f%%, MEM=%uMB", 45.2, 128); + + // ERROR 日志(红色输出) + LOG_E("通讯超时: channel=%d, addr=%u", 3, 0x01); + + // 开关控制 + log_console_off(); // 关闭控制台(仅写文件) + LOG_I("仅文件输出"); + log_console_on(); + + // 清理 + log_flush(); + log_cleanup(); + + return 0; +} +``` + +## 依赖关系 + +- **依赖**: liblist (消息队列链表), libfunc (进程路径获取) +- **被依赖**: 所有需要日志的模块 diff --git a/docs/public/libmd5/API-libmd5.md b/docs/public/libmd5/API-libmd5.md new file mode 100644 index 0000000..59d0f69 --- /dev/null +++ b/docs/public/libmd5/API-libmd5.md @@ -0,0 +1,81 @@ +# libmd5 — MD5 消息摘要 API 参考 + +## 模块概述 + +libmd5 实现了 RFC 1321 定义的 MD5 消息摘要算法。128 位输出,支持流式输入 +(分多次调用 `md5_update`)。提供 `md5_string` 便捷函数一步完成字符串 MD5 计算。 + +## 数据结构 + +```c +typedef struct +{ + uint32_t state[4]; // A, B, C, D 四个 32 位状态寄存器 + uint32_t count[2]; // 位计数(低 32 位, 高 32 位) + unsigned char buf[64]; // 待处理数据缓冲区(64 字节) +} stru_md5_ctx; +``` + +## 接口函数 + +### md5_start(ctx) +```c +void md5_start(stru_md5_ctx *ctx); +``` +初始化上下文,设置 RFC 1321 标准魔数: +`A=0x67452301 B=0xefcdab89 C=0x98badcfe D=0x10325476`。 + +### md5_update(ctx, data, len) +```c +void md5_update(stru_md5_ctx *ctx, const unsigned char *data, int len); +``` +输入数据,可多次调用支持流式处理。内部按 64 字节分块,填满即变换。 + +### md5_final(ctx, result) +```c +void md5_final(stru_md5_ctx *ctx, unsigned char result[16]); +``` +完成计算,输出 16 字节 MD5 摘要。内部自动填充 0x80+零+位计数。 + +### md5_string(input, output) +```c +void md5_string(const char *input, char output[33]); +``` +单次调用便捷函数:输入字符串 → 输出 32 字符大写十六进制 + '\0'。 + +## 使用示例 + +```c +#include "myMd5.h" +#include +#include + +int main(void) +{ + // 方式 1: 单次调用 + char hex[33]; + md5_string("hello", hex); + printf("MD5(hello) = %s\n", hex); + // 输出: MD5(hello) = 5D41402ABC4B2A76B9719D911017C592 + + // 方式 2: 流式计算(大文件场景) + stru_md5_ctx ctx; + unsigned char digest[16]; + + md5_start(&ctx); + md5_update(&ctx, (unsigned char *)"hello ", 6); + md5_update(&ctx, (unsigned char *)"world", 5); + md5_final(&ctx, digest); + + printf("流式: "); + for (int i = 0; i < 16; i++) printf("%02X", digest[i]); + printf("\n"); + + return 0; +} +``` + +## 依赖关系 + +- **依赖**: 无 +- **被依赖**: 文件校验、协议认证 等模块 diff --git a/docs/public/libmy_xxhash/API-libmy_xxhash.md b/docs/public/libmy_xxhash/API-libmy_xxhash.md new file mode 100644 index 0000000..f4ddd8e --- /dev/null +++ b/docs/public/libmy_xxhash/API-libmy_xxhash.md @@ -0,0 +1,40 @@ +# libmy_xxhash — xxHash 快速哈希 API 参考 + +## 模块概述 + +xxHash 是极速非加密哈希算法(BSD 2-Clause 许可证),直接使用原工程版本。 +提供 XXH32(32 位)和 XXH64(64 位)两种哈希。用于数据中心信号点快速索引。 + +## 接口函数 + +### XXH32(input, len, seed) +```c +uint32_t XXH32(const void *input, size_t len, uint32_t seed); +``` +计算 32 位哈希值。`seed` 通常传 0。 + +### XXH64(input, len, seed) +```c +uint64_t XXH64(const void *input, size_t len, uint64_t seed); +``` +计算 64 位哈希值。 + +## 使用示例 + +```c +#include "xxhash.h" +#include + +int main(void) +{ + const char *data = "hello world"; + + uint32_t h32 = XXH32(data, strlen(data), 0); + uint64_t h64 = XXH64(data, strlen(data), 0); + + printf("XXH32 = 0x%08X\n", h32); + printf("XXH64 = 0x%016llX\n", (unsigned long long)h64); + + return 0; +} +``` diff --git a/docs/public/libtask/API-libtask.md b/docs/public/libtask/API-libtask.md new file mode 100644 index 0000000..52ac716 --- /dev/null +++ b/docs/public/libtask/API-libtask.md @@ -0,0 +1,146 @@ +# libtask — 任务框架 API 参考 + +## 模块概述 + +libtask 是嵌入式装置的通用任务调度框架,包含三个子系统: +- **定时器**:基于 timerfd + epoll 精确毫秒级定时 +- **事件**:基于位图 + pthread 条件变量的同步原语 +- **消息队列**:基于环形缓冲区的线程安全 FIFO + +## 常量与类型 + +### 定时器标志 +| 宏 | 值 | 说明 | +|----|-----|------| +| `TASK_TIMER_FLAG_ONCE` | 0x01 | 单次触发 | +| `TASK_TIMER_FLAG_PERIODIC` | 0x02 | 周期触发 | + +### 事件标志 +| 宏 | 值 | 说明 | +|----|-----|------| +| `TASK_EVENT_WAIT_FOREVER` | 0xFFFFFFFF | 永久等待 | +| `TASK_EVENT_FLAG_AND` | 0x01 | AND 模式(所有位都置位) | +| `TASK_EVENT_FLAG_OR` | 0x02 | OR 模式(任意位置位) | +| `TASK_EVENT_FLAG_CLEAR` | 0x04 | 接收后自动清除 | + +### 回调类型 +```c +typedef void (*timer_func_cb)(void *arg); +``` + +### 不透明句柄 +```c +typedef void *stru_task_timer_t; +typedef void *stru_task_event_t; +typedef void *stru_task_msg_queue_t; +``` + +## 接口函数 + +### 通用延时 + +#### task_sleep_ms(ms) +毫秒级精度延时(内部使用 nanosleep)。 + +### 定时器 + +| 函数 | 说明 | +|------|------| +| `task_timer_create(name, cb, arg, timeout_ms, flags)` | 创建定时器(不自动启动) | +| `task_timer_start(pt)` | 启动 | +| `task_timer_stop(pt)` | 停止 | +| `task_timer_restart(pt, timeout_ms)` | 重启(可改周期) | +| `task_timer_destroy(pt)` | 销毁 | +| `task_timer_is_active(pt)` | 查询运行状态 | + +### 事件 + +| 函数 | 说明 | +|------|------| +| `task_event_create(name)` | 创建事件对象 | +| `task_event_destroy(pe)` | 销毁 | +| `task_event_send(pe, bits)` | 发送(置位+广播) | +| `task_event_recv(pe, set, opt, timeout_ms, recved)` | 等待 | +| `task_event_clear(pe, bits)` | 清除位 | +| `task_event_query(pe)` | 查询当前位(非阻塞) | + +### 消息队列 + +| 函数 | 说明 | +|------|------| +| `task_msg_queue_create(name, msg_size, msg_num)` | 创建 | +| `task_msg_queue_destroy(pq)` | 销毁 | +| `task_msg_queue_send(pq, msg, size)` | 发送(阻塞) | +| `task_msg_queue_send_timeout(pq, msg, size, timeout_ms)` | 发送(超时) | +| `task_msg_queue_recv(pq, msg, size, timeout_ms)` | 接收(超时) | +| `task_msg_queue_try_recv(pq, msg, size)` | 非阻塞接收 | +| `task_msg_queue_get_count(pq)` | 获取消息数 | +| `task_msg_queue_space(pq)` | 获取剩余空间 | + +## 使用示例 + +### 定时器 +```c +#include "myTask.h" +#include + +static int tick_count = 0; + +void on_tick(void *arg) +{ + tick_count++; + printf("定时器触发: %d 次\n", tick_count); +} + +int main(void) +{ + // 创建周期定时器:每 100ms 触发一次 + stru_task_timer_t pt = task_timer_create( + "heartbeat", on_tick, NULL, 100, TASK_TIMER_FLAG_PERIODIC + ); + + task_timer_start(pt); + task_sleep_ms(500); // 等待 500ms(预计触发 5 次) + task_timer_destroy(pt); + + return 0; +} +``` + +### 事件 +```c +stru_task_event_t pe = task_event_create("ev1"); + +// 线程 A: 发送事件 +task_event_send(pe, 0x03); // 设置 bit0 和 bit1 + +// 线程 B: 等待事件(OR 模式 + 自动清除) +uint32_t recved = 0; +task_event_recv(pe, 0x03, + TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR, + TASK_EVENT_WAIT_FOREVER, &recved); +printf("收到事件: 0x%02X\n", recved); // 0x03 + +task_event_destroy(pe); +``` + +### 消息队列 +```c +// 创建队列:每条 64 字节,容量 10 条 +stru_task_msg_queue_t pq = task_msg_queue_create("q1", 64, 10); + +char tx[] = "Hello"; +char rx[64]; + +task_msg_queue_send(pq, tx, 6); // 发送 +task_msg_queue_recv(pq, rx, 64, 1000); // 接收(1 秒超时) + +printf("收到: %s, 队列中: %u 条\n", rx, task_msg_queue_get_count(pq)); +task_msg_queue_destroy(pq); +``` + +## 依赖关系 + +- **依赖**: liblog (错误日志) +- **系统依赖**: ``, ``, ``, `` +- **被依赖**: 所有需要定时/同步/通讯的模块