docs: 创建完整 API 参考文档(9 个文档, 1005 行)

目录结构: docs/public/ 镜像 src/public/, 每个模块一个 API-xxx.md
文档内容: 模块概述+数据结构+接口详细说明+使用示例+依赖关系

覆盖模块:
- docs/README.md (总索引, 依赖关系图)
- myBase.h (公共宏/字节序/数据类型常量)
- liblist (11 API, 侵入式链表, 含完整代码示例)
- liblog (17 API, 异步日志, 消息池+批量+文件轮转)
- libfunc (65 函数, 7 大分类, 分组文档)
- libmd5 (4 API, RFC 1321, 流式计算示例)
- libtask (21 API, 定时器+事件+消息队列, 三个独立示例)
- libcJSON (开源库, 解析/生成 全流程示例)
- libmy_xxhash (开源库, XXH32/XXH64 快速哈希)

文档规范已存入 /memories/doc-spec.md
This commit is contained in:
ypc 2026-07-07 15:16:17 +08:00
parent aa97f72500
commit 44419ec729
9 changed files with 1011 additions and 0 deletions

66
docs/README.md Normal file
View File

@ -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 中文

112
docs/public/API-myBase.md Normal file
View File

@ -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 头文件
- **被依赖**: 所有模块

View File

@ -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 <stdio.h>
#include <stdlib.h>
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 交互 等模块

View File

@ -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)` | 文件 CRC164K 缓冲区流式计算) |
| `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/文件/进程操作的模块

View File

@ -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;
}
```
## 依赖关系
- **依赖**: `<stddef.h>` (offsetof)
- **被依赖**: liblog, libdatacenter, 所有需要链表管理的模块

View File

@ -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 (进程路径获取)
- **被依赖**: 所有需要日志的模块

View File

@ -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 <stdio.h>
#include <string.h>
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;
}
```
## 依赖关系
- **依赖**: 无
- **被依赖**: 文件校验、协议认证 等模块

View File

@ -0,0 +1,40 @@
# libmy_xxhash — xxHash 快速哈希 API 参考
## 模块概述
xxHash 是极速非加密哈希算法BSD 2-Clause 许可证),直接使用原工程版本。
提供 XXH3232 位)和 XXH6464 位)两种哈希。用于数据中心信号点快速索引。
## 接口函数
### 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 <stdio.h>
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;
}
```

View File

@ -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 <stdio.h>
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 (错误日志)
- **系统依赖**: `<sys/timerfd.h>`, `<sys/epoll.h>`, `<sys/eventfd.h>`, `<pthread.h>`
- **被依赖**: 所有需要定时/同步/通讯的模块