feat(RTU): 主程序入口 + 模块注册框架

- 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 可执行文件全通过
This commit is contained in:
ypc 2026-07-08 16:23:39 +08:00
parent 854319a500
commit e1736315e4
5 changed files with 423 additions and 12 deletions

View File

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

View File

@ -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_DIRrelease/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

163
src/system/RTU/src/main.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
/* ================================================================
* 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;
}

133
src/system/app_modules.c Normal file
View File

@ -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 <string.h>
#include <stdlib.h>
#include <pthread.h>
/** 最大可注册模块数 */
#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);
}
}
}

View File

@ -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 模块初始化阶段 1datacenter 信号注册前) */
typedef int (*app_init1_fn)(void *arg);
/** @brief 模块初始化阶段 2datacenter 信号注册后) */
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