refactor(system): 迁移至 X-Macro 框架 + app_config.json 启停控制

- 新增 app_modules.h: X-Macro 模块中心化列表(当前仅 modbus_m)
- 重写 mySystem.h: 移除旧 app_module_register API,新增:
  * enum_app: 通过 app_modules.h X-Macro 自动生成
  * extern 声明: 通过 app_modules.h 自动生成全部 init1/init2/run
  * stru_app: 增加 p_event/timer[3]/rtx/run_cnt(对齐原工程)
- 新增 app_sys.cpp (替换 app_modules.c):
  * 读取 app_config.json → 按 enable:true/false 启停模块
  * 自动为每个模块创建 3 级定时器 (10ms/100ms/1000ms) + 事件
  * X-Macro 展开 g_vec_app 初始化列表
- 新增 app_config.json: {"apps":[{"name":"app_modbus_m","enable":true}]}
- 删除 app_modules.c: 旧的动态注册框架
This commit is contained in:
ypc 2026-07-08 16:38:10 +08:00
parent aed907a977
commit 447443a6e5
5 changed files with 390 additions and 178 deletions

View File

@ -0,0 +1,5 @@
{
"apps": [
{"name": "app_modbus_m", "enable": true}
]
}

View File

@ -0,0 +1,300 @@
/**
* @file app_sys.cpp
* @brief X-Macro + app_config.json
* @details config/SYSTEM/app_config.json
* app_modules.h X-Macro g_vec_app
* + 3 + 线
*/
#include "mySystem.h"
#include "myLog.h"
#include "myFunc.h"
#include "myDatacenter.h"
#include "cJSON.h"
#include <string>
#include <vector>
#include <set>
#include <pthread.h>
/* ---- 启用的应用名集合(从 app_config.json 读取) ---- */
static std::set<std::string> g_enabled_apps;
/* ---- g_vec_app — 由 app_modules.h X-Macro 自动生成 ---- */
static std::vector<stru_app> g_vec_app =
{
#define APP_MODULE(name, cfg_name, init1, init2, func) \
{"app_" #cfg_name, 0, init1, init2, (app_func_fn)func, NULL, 0, {}, {}, {}, 0},
#include "app_modules.h"
#undef APP_MODULE
};
/* ---- 三级定时器事件 ---- */
static uint32_t g_timer_event[TIMER_NUM] = {EV_TIMER1, EV_TIMER2, EV_TIMER3};
/* ---- 获取系统配置目录路径 ---- */
static std::string get_system_config_path(void)
{
char proc_dir[512] = {0};
if (0 != func_proc_self_dir(proc_dir, sizeof(proc_dir)))
{
LOG_E("func_proc_self_dir failed");
return "";
}
return std::string(proc_dir) + "config/SYSTEM/";
}
/* ---- 解析 app_config.json ---- */
static int app_config_load(void)
{
std::string path = get_system_config_path();
if (path.empty()) { return -1; }
std::string cfg_path = path + "app_config.json";
uint32_t fsize = 0;
uint8_t *buf = func_read_file_alloc(cfg_path.c_str(), &fsize);
if (!buf)
{
/* 配置文件不存在时不视为错误——默认启用所有模块 */
LOG_I("app_config.json not found, enabling all modules by default");
for (auto &app : g_vec_app)
{
g_enabled_apps.insert(app.name);
}
return 0;
}
cJSON *root = cJSON_Parse((const char *)buf);
free(buf);
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; }
cJSON *name = cJSON_GetObjectItem(item, "name");
cJSON *enable = cJSON_GetObjectItem(item, "enable");
if (!name || !cJSON_IsString(name)) { continue; }
if (enable && cJSON_IsTrue(enable))
{
g_enabled_apps.insert(std::string(name->valuestring));
LOG_I("app enabled: %s", name->valuestring);
}
else
{
LOG_I("app disabled: %s", name->valuestring);
}
}
cJSON_Delete(root);
if (g_enabled_apps.empty())
{
LOG_E("no apps enabled in config");
return -1;
}
return 0;
}
/* ---- 判断模块是否启用 ---- */
static bool is_app_enabled(const char *name)
{
return g_enabled_apps.find(name) != g_enabled_apps.end();
}
/* ---- 定时器回调:发送对应的定时器事件给模块 ---- */
static void app_timer_expire(void *arg)
{
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; }
task_event_send(g_vec_app[thid].p_event, g_timer_event[tm_id]);
}
/* ---- 为一个模块创建 3 级定时器 ---- */
static int app_timer_create(stru_app *p_app)
{
if (!p_app) { return -1; }
uint32_t delay_ms = 1;
for (int i = 0; i < TIMER_NUM; i++)
{
std::string tm_name = std::string(p_app->name) + "_tm" + std::to_string(i + 1);
p_app->timer_arg[i] = ((p_app->app_id << 8) | i) & 0xFFFF;
delay_ms *= 10;
p_app->p_timer[i] = task_timer_create(
tm_name.c_str(),
app_timer_expire,
(void *)&p_app->timer_arg[i],
delay_ms,
TASK_TIMER_FLAG_PERIODIC);
if (!p_app->p_timer[i])
{
LOG_E("timer%d create failed for %s", i + 1, p_app->name);
return -1;
}
task_timer_start(p_app->p_timer[i]);
}
return 0;
}
/* ---- 主初始化流程 ---- */
static int app_init(void)
{
uint32_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 (!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;
}
}
/* init2: 信号注册后 */
for (i = 0; i < g_vec_app.size(); i++)
{
stru_app *p = &g_vec_app[i];
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;
}
}
/* 创建事件 + 定时器 + 启动线程 */
for (i = 0; i < g_vec_app.size(); i++)
{
stru_app *p = &g_vec_app[i];
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;
}
p->arg = (void *)p;
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;
}
pthread_t thread;
if (0 != pthread_create(&thread, NULL, p->fun_cb, p->arg))
{
LOG_E("pthread_create failed: %s", p->name);
return -1;
}
pthread_detach(thread);
LOG_I("thread started: %s", p->name);
task_sleep_ms(10);
}
return 0;
}
/* ---- 公共 API ---- */
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)
{
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;
}
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;
}
return &g_vec_app[app_id];
}

View File

@ -1,133 +0,0 @@
/**
* @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

@ -0,0 +1,26 @@
/**
* @file app_modules.h
* @brief X-Macro
* @details include guard
* APP_MODULE
*
*
* : APP_MODULE(, , init1, init2, 线)
* - : ENUM_APP_<>
* - : "app_<配置名>"
* - init1: 1
* - init2: 2 NULL
* - 线: 线
*/
#ifndef APP_MODULE
#error "APP_MODULE macro must be defined before including app_modules.h"
#endif
/* ============== 线程模块system/ 子目录) ============== */
APP_MODULE(MODBUS_M, modbus_m, app_modbus_m_init1, app_modbus_m_init2, app_modbus_m)
/* ============== 预留模块(阶段 2-3 实现后取消注释) ============== */
// APP_MODULE(COM_DECODE, com_decode, app_com_decode_init1, app_com_decode_init2, app_com_decode)
// APP_MODULE(IEC, iec, app_iec_init1, app_iec_init2, app_iec)
// APP_MODULE(WEB_SERVER, web_server, app_web_server_init1, app_web_server_init2, app_web_server)

View File

@ -1,8 +1,11 @@
/** /**
* @file mySystem.h * @file mySystem.h
* @brief * @brief X-Macro
* @details stru_app * @details app_modules.h X-Macro :
* RTU system/ 线 * 1) enum_app ID
* 2) extern init1/init2/thread
* 3) g_vec_app app_sys.cpp 使
* app_modules.h
*/ */
#ifndef _MY_SYSTEM_H_ #ifndef _MY_SYSTEM_H_
#define _MY_SYSTEM_H_ #define _MY_SYSTEM_H_
@ -15,55 +18,66 @@ extern "C"
{ {
#endif #endif
/** @brief 应用任务上下文(每个线程模块一个实例) */ /** 每个模块的定时器数量10ms / 100ms / 1000ms 三级) */
#define TIMER_NUM 3
#define EV_TIMER1 (0x01 << 0)
#define EV_TIMER2 (0x01 << 1)
#define EV_TIMER3 (0x01 << 2)
#define MSG_SIZE 2048
/* ---- 应用枚举,由 app_modules.h 生成 ---- */
#define APP_MODULE(name, cfg_name, init1, init2, func) ENUM_APP_##name,
typedef enum
{
#include "app_modules.h"
ENUM_APP_MAX
} enum_app;
#undef APP_MODULE
/* ---- 应用数据收发结构体 ---- */
typedef struct typedef struct
{ {
const char *name; uint16_t rx_len;
stru_task_event_t p_event; uint16_t tx_len;
stru_task_msg_queue_t p_queue; uint8_t rx[MSG_SIZE];
uint32_t run_cnt; uint8_t tx[MSG_SIZE];
} stru_rtx_data;
/* ---- 应用上下文(每个线程模块一个实例) ---- */
typedef int (*app_init_fn)(void *arg);
typedef void *(*app_func_fn)(void *arg);
typedef struct
{
const char *name;
uint32_t app_id;
app_init_fn app_init1;
app_init_fn app_init2;
app_func_fn fun_cb;
void *arg;
stru_task_event_t p_event;
stru_rtx_data rtx;
uint32_t timer_arg[TIMER_NUM];
stru_task_timer_t p_timer[TIMER_NUM];
uint32_t run_cnt;
} stru_app; } stru_app;
/** @brief 模块初始化阶段 1datacenter 信号注册前) */ /* ---- 获取模块指针 ---- */
typedef int (*app_init1_fn)(void *arg); stru_app *app_get_ptr(uint32_t app_id);
/** @brief 模块初始化阶段 2datacenter 信号注册后) */ /* ---- extern 函数声明,由 app_modules.h 生成 ---- */
typedef int (*app_init2_fn)(void *arg); #define APP_MODULE(name, cfg_name, init1, init2, func) \
extern int init1(void *arg); \
extern int init2(void *arg); \
extern void *func(void *arg);
/** @brief 模块主循环(独立线程入口) */ #include "app_modules.h"
typedef void *(*app_run_fn)(void *arg); #undef APP_MODULE
/** @brief 已注册的模块描述符 */ /* ---- 初始化 ---- */
typedef struct int app_sys_init(void);
{
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 #ifdef __cplusplus
} }