From a353f8339333ddbf9aa6c4099347ec03d275fea5 Mon Sep 17 00:00:00 2001 From: ypc <15051963820@163.com> Date: Tue, 7 Jul 2026 12:20:03 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=A7=84=E8=8C=83=20SPEC.md=EF=BC=88?= =?UTF-8?q?=E5=9F=BA=E4=BA=8E=20RTU=20=E5=8E=9F=E5=B7=A5=E7=A8=8B=2065+=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=82=B9=E5=88=86=E6=9E=90=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SPEC.md | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 SPEC.md diff --git a/SPEC.md b/SPEC.md new file mode 100644 index 0000000..405a7f9 --- /dev/null +++ b/SPEC.md @@ -0,0 +1,223 @@ +# RTU_ALL_AI 模块功能规范(基于 RTU 原工程分析) + +> 生成时间: 2026-07-07 +> 原则: 每条功能点均来自 RTU 原工程对应模块的完整分析,不遗漏不编造 + +--- + +## 1. myBase.h + +### 功能点 +| 序号 | 功能 | 说明 | +|------|------|------| +| B01 | 颜色宏 | COLOR_RESET/RED/GREEN/YELLOW/BLUE/MAGENTA/CYAN/WHITE | +| B02 | 文件名缩写宏 | `__SHORT_FILE__` 去除路径前缀 | +| B03 | 基础日志宏 | `MY_LOG(color,level,fmt,...)` / `MY_LOG_I` / `MY_LOG_E` | +| B04 | LOCAL 宏 | `#define LOCAL static` | +| B05 | 字符串类型 | `S_STR[64]` / `L_STR[128]` | +| B06 | uint16 大小端转换 | `MY_GET/SET_SHORT_BIGEND/LITTLEEND` | +| B07 | int32 大小端转换 | `MY_GET/SET_INT_BIGEND/LITTLEEND` | +| B08 | uint64 大小端转换 | `MY_GET/SET_LONG_BIGEND/LITTLEEND` | +| B09 | 类型级存/取宏 | `MY_GET/SET_DATA_WITH_TYPE` | +| B10 | 数据类型常量 | DATA_TYPE_B/S8/U8/.../STR (22种) | + +--- + +## 2. liblist 侵入式链表 + +### 功能点(Linux 内核标准 list.h 精简版) +| 序号 | 功能 | API | +|------|------|------| +| L01 | 链表初始化 | `LIST_HEAD` / `INIT_LIST_HEAD` | +| L02 | 头插 | `list_add` | +| L03 | 尾插 | `list_add_tail` | +| L04 | 删除 | `list_del` / `list_del_init` | +| L05 | 移动 | `list_move` / `list_move_tail` | +| L06 | 替换 | `list_replace` / `list_replace_init` | +| L07 | 判空 | `list_empty` / `list_is_linked` | +| L08 | 节点→宿主转换 | `list_entry` | +| L09 | 取首/尾元素 | `list_first_entry` / `list_last_entry` / `list_first_entry_or_null` | +| L10 | 遍历(安全) | `list_for_each` / `list_for_each_entry` / `*_safe` | +| L11 | 拼接 | `list_splice_init` | + +### 关键约束 +- 纯头文件,无运行时依赖 +- 所有 API 必须兼容 C 和 C++(变量名不用 `new`/`class`;`typeof`→`__typeof__`) + +--- + +## 3. liblog 异步日志系统 + +### 功能点(636 行,完整复刻 RTU 原实现) +| 序号 | 功能 | 说明 | +|------|------|------| +| G01 | 异步日志线程 | `log_worker_thread` 独立线程处理日志写入 | +| G02 | 懒初始化 | `pthread_once` 实现首次调用自动初始化 | +| G03 | 消息池预分配 | `calloc(LOG_QUEUE_SIZE)` 预分配消息池,避免频繁 malloc/free | +| G04 | 消息池取还 | `get_message_from_pool` / `return_message_to_pool` | +| G05 | 队列满阻塞 | `pthread_cond_wait` 等待 not_full,不丢弃日志 | +| G06 | 批量消费 | 一次最多取 `LOG_BATCH_SIZE`=100 条,批量写入 | +| G07 | 控制台输出 | 带颜色 ANSI 码输出 | +| G08 | 文件输出 | 带时间戳写入日志文件 | +| G09 | 文件自动创建 | `init_log_directory` 自动创建 logs/ 目录 | +| G10 | 文件按大小轮转 | 超过 10MB 自动轮转,保留 5 个历史文件 | +| G11 | 文件 setlinebuf | 行缓冲模式 | +| G12 | 时间戳格式化 | 精确到毫秒 `YYYY-MM-DD HH:MM:SS.mmm` | +| G13 | 文件信息格式化 | `文件名/函数名:行号` 格式 | +| G14 | LOG_I/LOG_E 宏 | 便捷宏 | +| G15 | 开关控制 | `log_set_file_enabled` / `log_set_console_enabled` | +| G16 | flush | 等待队列清空 | +| G17 | cleanup | 停止线程、关闭文件、释放消息池 | + +### 程序运行流程 +``` +首次 log_prt() 调用 + → pthread_once → log_global_init + → init_message_pool (预分配 LOG_QUEUE_SIZE 个消息结构) + → logger.running = 1 + → pthread_create(&log_worker_thread) + +每次 log_prt() + → get_message_from_pool() + → 填充 level/timestamp/file_info/content + → enqueue_log() + → 队列满则 pthread_cond_wait(¬_full) 阻塞等待 + → 尾插队列 + → pthread_cond_signal(¬_empty) + +log_worker_thread 主循环 + → 批量取消息 (最多 LOG_BATCH_SIZE) + → write_log_batch_array() + → 控制台: printf 带颜色 + → 文件: fopen/fprintf, 超过 10MB 触发 rotate_log_files + → return_message_to_pool() 归还每个消息 +``` + +--- + +## 4. libfunc 基础工具函数 + +### 功能点(1783 行,完整复刻 RTU 原实现) + +#### 4.1 校验计算 (6 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F01 | `func_cal_sum_byte` | 8位校验和 | +| F02 | `func_cal_sum_word` | 16位校验和 | +| F03 | `func_cal_crc16` | CRC16(Modbus 多项式) | +| F04 | `func_cal_crc32` | CRC32(标准多项式) | +| F05 | `func_cal_file_crc16` | 文件 CRC16 (4K 缓冲区) | +| F06 | `func_cal_file_crc32` | 文件 CRC32 (4K 缓冲区) | + +#### 4.2 字符串转换 (10 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F07 | `func_get_hex_from_ASCLL` | 单字符hex→数值 | +| F08 | `func_get_dec_from_ASCLL` | 单字符dec→数值 | +| F09 | `func_string_hex_to_dec` | hex字符串→int | +| F10 | `func_string_dec_to_dec` | dec字符串→int | +| F11 | `func_string_hex_to_buf` | hex字符串→字节缓冲 | +| F12 | `func_dec_to_string` | int→dec字符串(支持宽度填充) | +| F13 | `func_hex_to_string` | int→hex字符串(支持宽度填充) | +| F14 | `func_float_to_string` | float→字符串(支持宽度) | +| F15 | `func_buf_to_string` | 字节缓冲→hex字符串 | +| F16 | `func_string_to_argv` | 字符串→argc/argv分割 | + +#### 4.3 时间处理 (6 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F17 | `func_sys_time_to_string` | 系统时间结构体→字符串 | +| F18 | `func_string_to_sys_time` | 字符串→系统时间结构体 | +| F19 | `func_get_time` | 获取系统时间(支持 sys/cal 两种) | +| F20 | `func_set_time` | 设置系统时间 | +| F21 | `func_time_sys_to_cal` | 系统时间→日历时间 | +| F22 | `func_time_cal_to_sys` | 日历时间→系统时间 | + +#### 4.4 文件目录操作 (11 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F23 | `func_dir_exist` | 目录是否存在 | +| F24 | `func_make_dirs` | 创建目录(递归) | +| F25 | `func_del_dirs` | 删除目录(递归) | +| F26 | `func_del_dirs_by_cmd` | 删除目录(系统命令) | +| F27 | `func_file_exist` | 文件是否存在 | +| F28 | `func_get_file_size` | 获取文件大小 | +| F29 | `func_read_file_to_buf` | 读文件到预分配buf | +| F30 | `func_read_file_alloc_buf` | 读文件到动态分配buf | +| F31 | `func_write_buf_to_file` | 写buf到文件 | +| F32 | `func_read_file_tip_info` | 读结构体格式文件信息(含CRC校验) | +| F33 | `func_make_dir`(内部) | 内部单级目录创建 | + +#### 4.5 进程管理 (9 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F34 | `func_get_process_self_name` | 获取本进程名 | +| F35 | `func_get_process_name_by_pid` | PID→进程名 | +| F36 | `func_get_process_pid` | 获取本进程PID | +| F37 | `func_get_process_pid_by_name` | 进程名→PID | +| F38 | `func_process_exist_by_name` | 按名判断进程存在 | +| F39 | `func_process_exist_by_pid` | 按PID判断进程存在 | +| F40 | `func_get_process_path_by_pid` | PID→进程路径 | +| F41 | `func_get_process_self_path` | 本进程路径 | +| F42 | `func_get_process_self_dir` | 本进程目录 | + +#### 4.6 环境变量路径 (12 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F43 | `func_get_env_value`(内部) | 读环境变量 | +| F44 | `func_get_env_path`(内部) | 读环境变量路径 | +| F45 | `func_get_work_path` | WORK_PATH | +| F46 | `func_get_sys_cfg_path` | SYS_CFG_PATH | +| F47 | `func_get_app_root_path` | APP_ROOT_PATH | +| F48 | `func_get_his_root_path` | HIS_ROOT_PATH | +| F49 | `func_get_log_root_path` | LOG_ROOT_PATH | +| F50 | `func_get_dbc_root_path` | DBC_ROOT_PATH | +| F51 | `func_get_shell_path` | SHELL_PATH | +| F52 | `func_get_update_path` | UPDATE_PATH | +| F53 | `func_get_app_path` | 应用路径(拼接后) | +| F54 | `func_get_app_cfg_path` | 应用配置路径 | +| F55 | `func_get_app_his_path` | 应用历史路径 | +| F56 | `func_get_app_log_path` | 应用日志路径 | + +#### 4.7 IPC 消息队列 (9 个函数) +| 序号 | 函数 | 说明 | +|------|------|------| +| F57 | `func_create_ipc_msg_queue_by_name` | 按名称创建 | +| F58 | `func_create_ipc_msg_queue_by_pid` | 按PID创建 | +| F59 | `func_get_ipc_msg_queue_by_name` | 按名称获取 | +| F60 | `func_get_ipc_msg_queue_by_pid` | 按PID获取 | +| F61 | `func_ipc_msg_send_buf` | 发送原始buf | +| F62 | `func_ipc_msg_recv_buf` | 接收原始buf | +| F63 | `func_ipc_msg_send_struct` | 发送结构体 | +| F64 | `func_ipc_msg_recv_struct` | 接收结构体 | +| F65 | `func_delete_ipc_msg_queue` | 删除队列 | +| — | `func_process_exist_by_name` | (见4.5) | + +--- + +## 5. 构建系统 + +### 层次结构 (与 RTU 完全一致) +``` +release/ + makefile ← 顶层入口 (SUBDIRS=./src) + linux.mk ← 公共编译选项 (CC/CXX/AR, x86/arm切换) + build.sh ← 一键编译脚本 + src/ + makefile ← 第二层 (SUBDIRS=public protocol system) + public/ + makefile ← 第三层 (SUBDIRS=liblist libfunc liblog ...) + liblist/makefile + libfunc/makefile + ... + protocol/ + makefile + system/ + makefile +``` + +### linux.mk 关键变量 +- `CC`/`CXX`/`LD`/`AR` — 工具链 +- `CROSS=arm` 切换 ARM 交叉编译 +- `ROOT_DIR`/`SRC_ROOT_DIR`/`REL_INC`/`LIB_REL`/`EXE_REL` — 路径 +- `C_FLAGS`/`CXX_FLAGS` — 编译选项(.c 用 gcc,.cpp 用 g++)