RTU/mimo/plan/app_thread_dynamic_config.md

2.4 KiB
Raw Blame History

应用线程动态配置方案

背景

原项目中 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

{
    "apps": [
        {"name": "app_sys",        "enable": true},
        {"name": "app_cmd",        "enable": true},
        ...
    ]
}
  • 格式JSON 数组,使用 cJSON 库解析(项目中已有)
  • 路径:<exe_dir>/config/SYSTEM/app_config.json

实现改动

文件 改动
src/system/RTU/src/app_sys.cpp 新增 app_config_load() 解析 JSON → g_enabled_apps setapp_init() 第三循环检查 set 再创建线程;app_sys_init() 首行调用配置加载
test/config/SYSTEM/app_config.json 新建,含全部 8 个 app 及其 enable 标记

关键代码

// 配置加载 — 读取 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 终端交互