RTU_ALL_AI/SPEC.md

224 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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(&not_full) 阻塞等待
→ 尾插队列
→ pthread_cond_signal(&not_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++