refactor(RTU): 配置文件独立化 + app_sys_stop() + 代码风格统一

- config/SYSTEM/app_config.json: 配置文件从源码树迁出到独立 config/ 目录
- app_sys.cpp: 配置路径优先级 WORK_PATH 环境变量 > 可执行文件目录
- app_sys.cpp: 新增 app_sys_stop() 完整生命周期(EV_STOP + pthread_join)
- app_sys.cpp: 代码风格统一(空格/花括号/allman)
- main.c: 添加 SIGPIPE 处理 + app_sys_stop() 调用
- mySystem.h: 添加 EV_STOP 宏 + app_sys_stop() 声明
- RTU/makefile: 修复 .PHONY 重复定义 warning
This commit is contained in:
ypc 2026-07-08 17:35:26 +08:00
parent 3f6a3cfe91
commit 16b697f9c4
5 changed files with 137 additions and 24 deletions

View File

@ -25,7 +25,8 @@ S := $(ROOT)/src/system/RTU/src
C_OBJ := $(CURDIR)/RTU/obj/main.o
CXX_OBJ := $(CURDIR)/RTU/obj/app_sys.o
.PHONY: all; all: $(O)
.PHONY: all clean rebuild
all: $(O)
$(O): $(C_OBJ) $(CXX_OBJ)
@mkdir -p $(dir $@)
@ -40,5 +41,7 @@ $(CXX_OBJ): $(S)/app_sys.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXX_FLAGS) $(INC_PATH) -c $< -o $@
.PHONY: clean; clean:
clean:
rm -rf $(CURDIR)/RTU/obj $(O)
rebuild: clean all

View File

@ -1,9 +1,16 @@
/**
* @file app_sys.cpp
* @brief X-Macro + app_config.json
* @details config/SYSTEM/app_config.json
* @details <exe目录>/config/SYSTEM/app_config.json
* app_modules.h X-Macro g_vec_app
* + 3 + 线
*
* :
* WORK_PATH/ ()
* RTU
* config/
* SYSTEM/
* app_config.json
*/
#include "mySystem.h"
#include "myLog.h"
@ -19,6 +26,9 @@
/* ---- 启用的应用名集合(从 app_config.json 读取) ---- */
static std::set<std::string> g_enabled_apps;
/* ---- 线程句柄(用于 stop 时 join ---- */
static std::vector<pthread_t> g_threads;
/* ---- g_vec_app — 由 app_modules.h X-Macro 自动生成 ---- */
static std::vector<stru_app> g_vec_app =
{
@ -32,23 +42,37 @@ static std::vector<stru_app> g_vec_app =
/* ---- 三级定时器事件 ---- */
static uint32_t g_timer_event[TIMER_NUM] = {EV_TIMER1, EV_TIMER2, EV_TIMER3};
/* ---- 获取系统配置目录路径 ---- */
/* ---- 获取系统配置目录路径(优先级: WORK_PATH 环境变量 > 可执行文件所在目录) ---- */
static std::string get_system_config_path(void)
{
char proc_dir[512] = {0};
if (0 != func_proc_self_dir(proc_dir, sizeof(proc_dir)))
char buf[512] = {0};
/* 优先使用 WORK_PATH 环境变量RK3568 装置运行时设置) */
if (0 == func_get_work_path(buf, sizeof(buf)))
{
return std::string(buf) + "/config/SYSTEM/";
}
/* fallback: 从可执行文件路径推导(本地调试用) */
if (0 != func_proc_self_dir(buf, sizeof(buf)))
{
LOG_E("func_proc_self_dir failed");
return "";
}
return std::string(proc_dir) + "config/SYSTEM/";
return std::string(buf) + "/config/SYSTEM/";
}
/* ---- 解析 app_config.json ---- */
static int app_config_load(void)
{
std::string path = get_system_config_path();
if (path.empty()) { return -1; }
if (path.empty())
{
return -1;
}
std::string cfg_path = path + "app_config.json";
@ -60,9 +84,9 @@ static int app_config_load(void)
/* 配置文件不存在时不视为错误——默认启用所有模块 */
LOG_I("app_config.json not found, enabling all modules by default");
for (auto &app : g_vec_app)
for (size_t i = 0; i < g_vec_app.size(); i++)
{
g_enabled_apps.insert(app.name);
g_enabled_apps.insert(g_vec_app[i].name);
}
return 0;
@ -74,27 +98,38 @@ static int app_config_load(void)
if (!root)
{
LOG_E("cJSON_Parse failed for app_config.json");
return -1;
}
cJSON *apps = cJSON_GetObjectItem(root, "apps");
if (!apps || !cJSON_IsArray(apps))
{
LOG_E("app_config.json missing 'apps' array");
cJSON_Delete(root);
return -1;
}
int arr_size = cJSON_GetArraySize(apps);
for (int i = 0; i < arr_size; i++)
{
cJSON *item = cJSON_GetArrayItem(apps, i);
if (!item) { continue; }
if (!item)
{
continue;
}
cJSON *name = cJSON_GetObjectItem(item, "name");
cJSON *enable = cJSON_GetObjectItem(item, "enable");
if (!name || !cJSON_IsString(name)) { continue; }
if (!name || !cJSON_IsString(name))
{
continue;
}
if (enable && cJSON_IsTrue(enable))
{
@ -112,6 +147,7 @@ static int app_config_load(void)
if (g_enabled_apps.empty())
{
LOG_E("no apps enabled in config");
return -1;
}
@ -127,13 +163,19 @@ static bool is_app_enabled(const char *name)
/* ---- 定时器回调:发送对应的定时器事件给模块 ---- */
static void app_timer_expire(void *arg)
{
if (!arg) { return; }
if (!arg)
{
return;
}
uint32_t signal = *(uint32_t *)arg;
uint8_t thid = signal >> 8;
uint8_t tm_id = signal & 0xFF;
if (thid >= g_vec_app.size() || tm_id >= TIMER_NUM) { return; }
if (thid >= g_vec_app.size() || tm_id >= TIMER_NUM)
{
return;
}
task_event_send(g_vec_app[thid].p_event, g_timer_event[tm_id]);
}
@ -141,7 +183,10 @@ static void app_timer_expire(void *arg)
/* ---- 为一个模块创建 3 级定时器 ---- */
static int app_timer_create(stru_app *p_app)
{
if (!p_app) { return -1; }
if (!p_app)
{
return -1;
}
uint32_t delay_ms = 1;
@ -162,6 +207,7 @@ static int app_timer_create(stru_app *p_app)
if (!p_app->p_timer[i])
{
LOG_E("timer%d create failed for %s", i + 1, p_app->name);
return -1;
}
@ -174,24 +220,29 @@ static int app_timer_create(stru_app *p_app)
/* ---- 主初始化流程 ---- */
static int app_init(void)
{
uint32_t i;
size_t i;
/* init1: 信号注册前 */
for (i = 0; i < g_vec_app.size(); i++)
{
stru_app *p = &g_vec_app[i];
if (!p->app_init1) { continue; }
if (!p->app_init1)
{
continue;
}
if (!is_app_enabled(p->name))
{
LOG_I("app skipped (disabled): %s", p->name);
continue;
}
if (0 != p->app_init1((void *)p))
{
LOG_E("app_init1 failed: %s", p->name);
return -1;
}
}
@ -201,17 +252,22 @@ static int app_init(void)
{
stru_app *p = &g_vec_app[i];
if (!p->app_init2) { continue; }
if (!p->app_init2)
{
continue;
}
if (!is_app_enabled(p->name))
{
LOG_I("app skipped (disabled): %s", p->name);
continue;
}
if (0 != p->app_init2((void *)p))
{
LOG_E("app_init2 failed: %s", p->name);
return -1;
}
}
@ -224,10 +280,12 @@ static int app_init(void)
p->app_id = i;
std::string ev_name = "EV_" + std::string(p->name);
p->p_event = task_event_create(ev_name.c_str());
if (!p->p_event)
{
LOG_E("task_event_create failed: %s", ev_name.c_str());
return -1;
}
@ -236,12 +294,14 @@ static int app_init(void)
if (0 != app_timer_create(p))
{
LOG_E("app_timer_create failed: %s", p->name);
return -1;
}
if (!is_app_enabled(p->name))
{
LOG_I("app skipped (disabled): %s", p->name);
continue;
}
@ -250,10 +310,11 @@ static int app_init(void)
if (0 != pthread_create(&thread, NULL, p->fun_cb, p->arg))
{
LOG_E("pthread_create failed: %s", p->name);
return -1;
}
pthread_detach(thread);
g_threads.push_back(thread);
LOG_I("thread started: %s", p->name);
task_sleep_ms(10);
@ -269,30 +330,62 @@ int app_sys_init(void)
if (0 != app_config_load())
{
LOG_E("app_config_load failed");
return -1;
}
if (g_vec_app.size() != ENUM_APP_MAX)
if (g_vec_app.size() != (size_t)ENUM_APP_MAX)
{
LOG_E("g_vec_app size mismatch: %zu vs ENUM %d",
g_vec_app.size(), ENUM_APP_MAX);
return -1;
}
if (0 != app_init())
{
LOG_E("app_init failed");
return -1;
}
return 0;
}
/**
* @brief
* @details EV_STOP 退 join 线
*/
void app_sys_stop(void)
{
LOG_I("stopping all app modules...");
for (size_t i = 0; i < g_vec_app.size(); i++)
{
stru_app *p = &g_vec_app[i];
if (p->p_event)
{
task_event_send(p->p_event, EV_STOP);
}
}
/* 等待所有线程退出 */
for (size_t i = 0; i < g_threads.size(); i++)
{
pthread_join(g_threads[i], NULL);
LOG_I("module thread [%zu] exited", i);
}
LOG_I("all app modules stopped");
}
stru_app *app_get_ptr(uint32_t app_id)
{
if (app_id >= ENUM_APP_MAX)
{
LOG_E("app_id out of range: %u max %d", app_id, ENUM_APP_MAX);
return NULL;
}

View File

@ -3,6 +3,13 @@
* @brief RTU
* @details app_sys_init() X-Macro
* src/system/inc/app_modules.h
*
* :
* WORK_PATH/ ( WORK_PATH )
* RTU
* config/
* SYSTEM/
* app_config.json
*/
#include "mySystem.h"
#include "myLog.h"
@ -22,13 +29,14 @@ static void sig_handler(int sig)
{
(void)sig;
g_running = 0;
LOG_I("signal received, shutting down...");
LOG_I("signal %d received, shutting down...", sig);
}
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,
@ -39,6 +47,7 @@ static void cmd_uptime(int argc, char *argv[])
{
(void)argc;
(void)argv;
printf("RTU uptime: (running)\n");
}
@ -64,6 +73,7 @@ int main(int argc, char *argv[])
if (app_sys_init() != 0)
{
LOG_E("app_sys_init failed, aborting");
return 1;
}
@ -73,7 +83,10 @@ int main(int argc, char *argv[])
{
char *line = linenoise("RTU> ");
if (!line) { break; }
if (!line)
{
break;
}
if (line[0] != '\0')
{
@ -101,6 +114,8 @@ int main(int argc, char *argv[])
}
LOG_I("shutting down...");
app_sys_stop();
dc_cleanup();
log_cleanup();

View File

@ -24,6 +24,7 @@ extern "C"
#define EV_TIMER1 (0x01 << 0)
#define EV_TIMER2 (0x01 << 1)
#define EV_TIMER3 (0x01 << 2)
#define EV_STOP (0x80) /**< 模块停止信号 */
#define MSG_SIZE 2048
@ -76,8 +77,9 @@ stru_app *app_get_ptr(uint32_t app_id);
#include "app_modules.h"
#undef APP_MODULE
/* ---- 初始化 ---- */
/* ---- 初始化与停止 ---- */
int app_sys_init(void);
void app_sys_stop(void);
#ifdef __cplusplus
}