From e1736315e4d1d33d22eebe39bde22d1d2d789a4b Mon Sep 17 00:00:00 2001 From: ypc <15051963820@163.com> Date: Wed, 8 Jul 2026 16:23:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(RTU):=20=E4=B8=BB=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=20+=20=E6=A8=A1=E5=9D=97=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - src/system/inc/mySystem.h: app_init1/init2/run_fn 回调类型 + stru_app_module + 注册API - src/system/app_modules.c: 模块注册框架实现(register/init1/init2/start/stop/join) - src/system/RTU/src/main.c: 主程序入口(信号处理/模块生命周期/命令交互) - release/src/system/makefile: 构建 libsystem.a(app_modules.c) - release/src/system/RTU/makefile: 编译 RTU 可执行文件(链接全部 lib) - 构建验证: x86 + ARM RTU 可执行文件全通过 --- release/src/system/RTU/makefile | 45 +++++++++ release/src/system/makefile | 40 ++++++-- src/system/RTU/src/main.c | 163 ++++++++++++++++++++++++++++++++ src/system/app_modules.c | 133 ++++++++++++++++++++++++++ src/system/inc/mySystem.h | 54 +++++++++-- 5 files changed, 423 insertions(+), 12 deletions(-) create mode 100644 release/src/system/RTU/makefile create mode 100644 src/system/RTU/src/main.c create mode 100644 src/system/app_modules.c diff --git a/release/src/system/RTU/makefile b/release/src/system/RTU/makefile new file mode 100644 index 0000000..0af6e1f --- /dev/null +++ b/release/src/system/RTU/makefile @@ -0,0 +1,45 @@ +include ./../../../linux.mk + +ROOT := $(realpath $(CURDIR)/../../../..) + +INC_PATH := -I$(ROOT)/release/inc \ + -I$(ROOT)/src/system/inc \ + -I$(ROOT)/src/public/libdatacenter/inc \ + -I$(ROOT)/src/public/liblog/inc \ + -I$(ROOT)/src/public/libfunc/inc \ + -I$(ROOT)/src/public/libcmd/inc \ + -I$(ROOT)/src/public/libtask/inc \ + -I$(ROOT)/src/public/libmy_xxhash/inc \ + -I$(ROOT)/src/protocol/libmodbus/inc + +LIBS := -L$(ROOT)/release/$(BUILD_TYPE)/lib \ + -lsystem -lmodbus_m -lmodbus -l60870 \ + -ldatacenter -lxml -lcmd -ltask \ + -llog -lfunc -lmy_xxhash -lcJSON -lmd5 -lcomm \ + -lpthread -lstdc++ + +O := $(ROOT)/release/$(BUILD_TYPE)/exe/RTU +S := $(ROOT)/src/system/RTU/src +B := $(CURDIR)/RTU/obj +SRCS := $(wildcard $(S)/*.c) +OBJS := $(patsubst $(S)/%.c, $(B)/%.o, $(SRCS)) +F := $(C_FLAGS) $(INC_PATH) + +.PHONY: all +all: $(O) + @echo "[RTU] built -> $(O)" + +$(O): $(OBJS) + @mkdir -p $(dir $@) + $(CXX) $^ $(LIBS) -o $@ + +$(B)/%.o: $(S)/%.c + @mkdir -p $(dir $@) + $(CC) $(F) -c $< -o $@ + +.PHONY: clean +clean: + rm -rf $(B) $(O) + +.PHONY: rebuild +rebuild: clean all diff --git a/release/src/system/makefile b/release/src/system/makefile index 09452cf..01462b6 100644 --- a/release/src/system/makefile +++ b/release/src/system/makefile @@ -1,8 +1,36 @@ -SUBDIRS := ./libmodbus_m -define make_subdir - for d in $(SUBDIRS); do [ -f "$$d/makefile" ] && (cd "$$d" && make -f makefile $1) || true; done -endef +include ./../../linux.mk + +# 纠正 ROOT_DIR:release/src/system 只有三级深度,linux.mk 假设四级 +ORIG_ROOT := $(ROOT_DIR) +ROOT := $(realpath $(CURDIR)/../../..) +SYS_SRC := $(ROOT)/src/system +PUB_SRC := $(ROOT)/src/public + +LIB := $(ROOT)/release/$(BUILD_TYPE)/lib/libsystem.a +LIB_OBJ := $(CURDIR)/libsystem/obj/app_modules.o +LIB_FLAGS := $(C_FLAGS) -I$(SYS_SRC)/inc -I$(PUB_SRC)/liblog/inc -I$(PUB_SRC)/libtask/inc -I$(ROOT)/release/inc + +$(LIB): $(LIB_OBJ) + @mkdir -p $(dir $@) + $(AR) rcs $@ $^ + @echo "[libsystem] built" + +$(LIB_OBJ): $(SYS_SRC)/app_modules.c + @mkdir -p $(dir $@) + $(CC) $(LIB_FLAGS) -c $< -o $@ + +.PHONY: clean-sys +clean-sys: + rm -rf $(CURDIR)/libsystem/obj $(LIB) + +SUBDIRS := ./libmodbus_m ./RTU + .PHONY: all clean rebuild -all:; @$(call make_subdir,all) -clean:; @$(call make_subdir,clean) + +all: $(LIB) + @for d in $(SUBDIRS); do [ -f "$$d/makefile" ] && (cd "$$d" && $(MAKE) -f makefile all) || true; done + +clean: clean-sys + @for d in $(SUBDIRS); do [ -f "$$d/makefile" ] && (cd "$$d" && $(MAKE) -f makefile clean) || true; done + rebuild: clean all diff --git a/src/system/RTU/src/main.c b/src/system/RTU/src/main.c new file mode 100644 index 0000000..e6af2e3 --- /dev/null +++ b/src/system/RTU/src/main.c @@ -0,0 +1,163 @@ +/** + * @file main.c + * @brief RTU 主程序入口 + * @details 注册所有线程模块 → init1 → init2 → start → wait。 + * 每个模块在自己的独立线程中运行主循环。 + */ +#include "mySystem.h" +#include "myLog.h" +#include "myDatacenter.h" +#include "myModbus.h" +#include "myFunc.h" +#include "myCmd.h" + +#include +#include +#include +#include + +/* ================================================================ + * 外部模块声明(各模块在 system/ 子目录中实现,链接时解析) + * ================================================================ */ + +/* libmodbus_m — Modbus 主站管理 */ +extern int app_modbus_m_init1(void *arg); +extern int app_modbus_m_init2(void *arg); +extern void *app_modbus_m(void *arg); +extern void app_modbus_m_register(void); + +/* ================================================================ + * 信号处理 + * ================================================================ */ + +static volatile int g_running = 1; + +static void sig_handler(int sig) +{ + (void)sig; + g_running = 0; + LOG_I("signal received, shutting down..."); +} + +/* ================================================================ + * 内置命令 + * ================================================================ */ + +static void cmd_version(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + printf("RTU_ALL_AI v1.0\n"); + printf(" libmodbus v%d.%d.%d\n", + libmodbus_version_major, libmodbus_version_minor, + libmodbus_version_micro); +} + +static void cmd_uptime(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + printf("RTU uptime: (running)\n"); +} + +CMD_REGISTER("version", cmd_version, "show firmware version"); +CMD_REGISTER("uptime", cmd_uptime, "show uptime"); + +/* ================================================================ + * main + * ================================================================ */ + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + printf("\n=== RTU_ALL_AI Starting ===\n\n"); + + /* 信号处理 */ + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + + /* 初始化日志 */ + log_init(NULL); + + LOG_I("RTU booting..."); + + /* 注册所有线程模块 */ + app_modbus_m_register(); + + /* 阶段 1: 模块初始化(信号注册前) */ + if (app_modules_init1() != 0) + { + LOG_E("app_modules_init1 failed, aborting"); + + return 1; + } + + /* 数据中心初始化 */ + dc_init(NULL); + + /* 阶段 2: 模块初始化(信号注册后) */ + if (app_modules_init2() != 0) + { + LOG_E("app_modules_init2 failed, aborting"); + + return 1; + } + + /* 启动所有模块线程 */ + app_modules_start(); + + LOG_I("RTU running, %d worker threads", 1); + + /* 主循环: 处理命令输入 */ + while (g_running) + { + char *line = linenoise("RTU> "); + + if (!line) + { + break; /* Ctrl+D */ + } + + if (line[0] != '\0') + { + linenoiseHistoryAdd(line); + + /* 解析为 argc/argv */ + char *argv_buf[16]; + uint8_t argc = 0; + + if (func_str2argv(line, &argc, argv_buf, 16) == 0 && argc > 0) + { + stru_cmd *cmd = cmd_find(argv_buf[0]); + + if (cmd) + { + cmd->func((int)argc, argv_buf); + } + else + { + printf("unknown command: %s (type 'help')\n", argv_buf[0]); + } + } + } + + linenoiseFree(line); + } + + /* 停止所有模块 */ + LOG_I("stopping all modules..."); + app_modules_stop(); + app_modules_join(); + + /* 清理 */ + dc_cleanup(); + log_cleanup(); + + printf("=== RTU_ALL_AI Stopped ===\n"); + + return 0; +} diff --git a/src/system/app_modules.c b/src/system/app_modules.c new file mode 100644 index 0000000..d9ec96b --- /dev/null +++ b/src/system/app_modules.c @@ -0,0 +1,133 @@ +/** + * @file app_modules.c + * @brief 模块注册框架实现 + * @details 管理已注册线程模块的生命周期: register → init1 → init2 → start → stop。 + * 此文件编译进 libsystem.a,供 RTU 主程序使用。 + */ +#include "mySystem.h" +#include "myLog.h" + +#include +#include +#include + +/** 最大可注册模块数 */ +#define APP_MODULES_MAX 16 + +/** 已注册模块表 */ +static stru_app_module g_modules[APP_MODULES_MAX]; +static int g_module_count = 0; + +/** 线程句柄表 */ +static pthread_t g_threads[APP_MODULES_MAX]; + +void app_module_register(const char *name, + app_init1_fn init1, + app_init2_fn init2, + app_run_fn run, + stru_app *p_app) +{ + if (g_module_count >= APP_MODULES_MAX) + { + LOG_E("app_module_register: max modules reached"); + + return; + } + + if (!name || !run) + { + LOG_E("app_module_register: invalid args"); + + return; + } + + stru_app_module *m = &g_modules[g_module_count]; + + m->name = name; + m->init1 = init1; + m->init2 = init2; + m->run = run; + m->p_app = p_app; + + g_module_count++; + + LOG_I("app_module_register: [%s] registered", name); +} + +int app_modules_init1(void) +{ + for (int i = 0; i < g_module_count; i++) + { + if (g_modules[i].init1) + { + LOG_I("app_modules_init1: [%s]...", g_modules[i].name); + + if (g_modules[i].init1(g_modules[i].p_app) != 0) + { + LOG_E("app_modules_init1: [%s] failed", g_modules[i].name); + + return -1; + } + } + } + + return 0; +} + +int app_modules_init2(void) +{ + for (int i = 0; i < g_module_count; i++) + { + if (g_modules[i].init2) + { + LOG_I("app_modules_init2: [%s]...", g_modules[i].name); + + if (g_modules[i].init2(g_modules[i].p_app) != 0) + { + LOG_E("app_modules_init2: [%s] failed", g_modules[i].name); + + return -1; + } + } + } + + return 0; +} + +void app_modules_start(void) +{ + for (int i = 0; i < g_module_count; i++) + { + LOG_I("app_modules_start: [%s]...", g_modules[i].name); + + if (pthread_create(&g_threads[i], NULL, g_modules[i].run, + g_modules[i].p_app) != 0) + { + LOG_E("app_modules_start: [%s] thread create failed", + g_modules[i].name); + } + } +} + +void app_modules_stop(void) +{ + for (int i = 0; i < g_module_count; i++) + { + if (g_modules[i].p_app && g_modules[i].p_app->p_event) + { + task_event_send(g_modules[i].p_app->p_event, 0x80); /* 停止信号 */ + } + } +} + +void app_modules_join(void) +{ + for (int i = 0; i < g_module_count; i++) + { + if (g_threads[i]) + { + pthread_join(g_threads[i], NULL); + LOG_I("app_modules_join: [%s] exited", g_modules[i].name); + } + } +} diff --git a/src/system/inc/mySystem.h b/src/system/inc/mySystem.h index b0de486..08625ed 100644 --- a/src/system/inc/mySystem.h +++ b/src/system/inc/mySystem.h @@ -1,7 +1,8 @@ /** * @file mySystem.h * @brief 系统管理模块公共定义 - * @details 供 libmodbus_m/libiec/libcom_decode/RTU 等系统模块共用。 + * @details 定义任务上下文 stru_app 和模块注册框架。 + * 供 RTU 主程序及所有 system/ 线程模块共用。 */ #ifndef _MY_SYSTEM_H_ #define _MY_SYSTEM_H_ @@ -14,15 +15,56 @@ extern "C" { #endif -/** @brief 应用任务上下文(RTU 多任务运行时使用) */ +/** @brief 应用任务上下文(每个线程模块一个实例) */ typedef struct { - const char *name; /**< 任务名称 */ - stru_task_event_t p_event; /**< 事件句柄 */ - stru_task_msg_queue_t p_queue; /**< 消息队列句柄 */ - uint32_t run_cnt; /**< 运行计数 */ + const char *name; + stru_task_event_t p_event; + stru_task_msg_queue_t p_queue; + uint32_t run_cnt; } stru_app; +/** @brief 模块初始化阶段 1(datacenter 信号注册前) */ +typedef int (*app_init1_fn)(void *arg); + +/** @brief 模块初始化阶段 2(datacenter 信号注册后) */ +typedef int (*app_init2_fn)(void *arg); + +/** @brief 模块主循环(独立线程入口) */ +typedef void *(*app_run_fn)(void *arg); + +/** @brief 已注册的模块描述符 */ +typedef struct +{ + const char *name; + app_init1_fn init1; + app_init2_fn init2; + app_run_fn run; + stru_app *p_app; +} stru_app_module; + +/** @brief 注册一个线程模块 */ +void app_module_register(const char *name, + app_init1_fn init1, + app_init2_fn init2, + app_run_fn run, + stru_app *p_app); + +/** @brief 执行所有模块 init1 */ +int app_modules_init1(void); + +/** @brief 执行所有模块 init2 */ +int app_modules_init2(void); + +/** @brief 启动所有模块主循环(每模块一个独立线程) */ +void app_modules_start(void); + +/** @brief 停止所有模块 */ +void app_modules_stop(void); + +/** @brief 等待所有模块线程退出 */ +void app_modules_join(void); + #ifdef __cplusplus } #endif