# 应用线程动态配置方案 ## 背景 原项目中 8 个应用线程(app_sys/app_cmd/app_com_decode/app_iec/app_self_ptl/app_web_server/app_iec61850m/app_iec61850s)的启动顺序和启用在 `app_sys.cpp` 中硬编码。修改线程启停需要重新编译。 ## 目标 通过 JSON 配置文件控制线程启停,运行时动态决定启动哪些线程。 ## 方案设计 ### 核心原则 - **保留完整 `g_vec_app` 向量和 `ENUM_APP_*` 枚举**:所有索引查找(`app_get_ptr(ENUM_APP_XXX)`)不受影响 - **仅 `pthread_create` 受配置控制**:init1/init2、事件对象、定时器为所有 app 创建(确保无空指针崩溃) - **禁用线程的事件/定时器照常创建**:事件发往无消费者的队列时无害累积 ### 配置文件 `test/config/SYSTEM/app_config.json` ```json { "apps": [ {"name": "app_sys", "enable": true}, {"name": "app_cmd", "enable": true}, ... ] } ``` - 格式:JSON 数组,使用 cJSON 库解析(项目中已有) - 路径:`/config/SYSTEM/app_config.json` ### 实现改动 | 文件 | 改动 | |------|------| | `src/system/RTU/src/app_sys.cpp` | 新增 `app_config_load()` 解析 JSON → `g_enabled_apps` set;`app_init()` 第三循环检查 set 再创建线程;`app_sys_init()` 首行调用配置加载 | | `test/config/SYSTEM/app_config.json` | 新建,含全部 8 个 app 及其 enable 标记 | ### 关键代码 ```cpp // 配置加载 — 读取 JSON → g_enabled_apps set LOCAL int app_config_load() { ... cJSON解析 ... } // app_init() 第三循环 — 仅启用的 app 创建线程 for(i = 0; i < g_vec_app.size(); i++) { // ... 创建事件、定时器(所有app)... if(g_enabled_apps.find(p->name) == g_enabled_apps.end()) { MY_LOG_I("app skipped (disabled by config): %s", p->name); continue; // 跳过 pthread_create } pthread_create(&p->thread, NULL, p->fun_cb, p->arg); } ``` ### 使用方式 1. 编辑 `test/config/SYSTEM/app_config.json` 2. 将目标 app 的 `enable` 设为 `false` 3. 重启 RTU 即可生效 ### 注意事项 - `app_sys` 是核心系统线程(数据中心),**不应禁用** - 禁用某个线程后,依赖它的模块发送的事件将无人处理(无害堆积) - 禁用 `app_web_server` 将无法通过浏览器访问 - 禁用 `app_cmd` 将无法通过 SSH 终端交互