<修改> 1、将应用线程模块调用方式改为动态的,通过头文件中进行绑定,通过配置文件进行选择是否运行;2、消息队列初始化也同样修改
This commit is contained in:
parent
3c19148b97
commit
8de2441a79
|
|
@ -69,7 +69,21 @@ _Hard constraints from user that every session must respect._
|
|||
## Architecture decisions
|
||||
_Major design choices with rationale. The "why" matters more than the "what" for future sessions._
|
||||
|
||||
### 1. 数据中心信号管理
|
||||
### 1. 应用模块注册表 — X-Macro 架构(2026-06-18)
|
||||
`release/inc/app_modules.h` 作为应用模块的**单一事实来源**,使用 X-Macro 模式自动生成枚举值、extern 声明、模块注册表。
|
||||
|
||||
**设计**:
|
||||
- `APP_MODULE(ENUM后缀, 配置名, init1, init2, thread入口)` 格式
|
||||
- 第一个参数生成 `ENUM_APP_<后缀>` 枚举值(大写)
|
||||
- 第二个参数生成 `"app_<配置名>"` 匹配配置文件 JSON 中的小写名称
|
||||
- `#include "app_modules.h"` 在三个不同位置展开,每次定义不同的 `APP_MODULE` 宏
|
||||
|
||||
**效果**:
|
||||
- 新增模块 = 在 `app_modules.h` 加一行 + 配置文件加一行,无需改任何其他代码
|
||||
- 消除了 `mySystem.h` 中手写的 extern 声明(原 24 行 → 自动生成)
|
||||
- 消除了 `app_sys.cpp` 中手写的 g_vec_app(原 8 组结构体 → 自动生成)
|
||||
|
||||
### 2. 数据中心信号管理
|
||||
`dc_signal.cpp` 使用 XXH128 哈希对信号快速索引(`signal_out`, `signal_in`, `signal_yk`, `signal_ao`, `signal_param` 五张表,每表独立互斥锁)。输出信号变更通过脏队列 + 去重 + 比对 + 回调实现增量推送(仅变更时发送),`last_caller_module` 防止同模块回调自循环。SBO(Select Before Operate)控制流程:SELECT 暂存值 → DIRECT 校验与 SELECT 值一致 → 写入信号。事件队列(扰动/SOE/故障)使用 swap 模式低锁竞争 pop。
|
||||
|
||||
### 2. 参数配置双文件机制
|
||||
|
|
@ -98,6 +112,16 @@ _Cross-task facts that survive across sessions. Promoted from session checkpoint
|
|||
#### #1 RCB 订阅编号可配置化(2026-06-10)
|
||||
- **问题**: `mms_m_icd_report_init()` 硬编码只订阅编号 `"01"` 的 RCB
|
||||
- **修复**: 新增 `mms_m_out_set_rcb_numbers()` API,支持逗号分隔的多编号和通配符 `"*"`
|
||||
|
||||
### #2 X-Macro 应用模块注册表(2026-06-18)
|
||||
- **问题**: 新增线程模块需要改 3 处(mySystem.h 枚举+extern、app_sys.cpp g_vec_app),且名称大小写不一致
|
||||
- **方案**: 创建 `app_modules.h` 作为单一事实来源,X-Macro 自动展开
|
||||
- **关键约束**: `app_modules.h` **不能有 `#pragma once` 或 include guard**,需被多次包含
|
||||
- **cfg_name 参数**: 枚举后缀(大写)用 `ENUM_APP_##name`,配置名(小写)用 `"app_" #cfg_name`,通过两参数分离解决大小写匹配问题
|
||||
- **文件**:
|
||||
- `release/inc/app_modules.h` — 模块注册表(8 个 APP_MODULE 条目)
|
||||
- `release/inc/mySystem.h` — 枚举 + extern 自动生成
|
||||
- `src/system/RTU/src/app_sys.cpp` — g_vec_app 自动生成
|
||||
- **文件**: `myMms_m.h`, `mms_m.h`, `mms_m.cpp`, `iec61850m.cpp`
|
||||
|
||||
#### #2 libweb_server 多连接支持(2026-06-10)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
# 应用线程动态配置方案
|
||||
|
||||
## 背景
|
||||
|
||||
原项目中 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 库解析(项目中已有)
|
||||
- 路径:`<exe_dir>/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 终端交互
|
||||
|
|
@ -2,6 +2,27 @@
|
|||
|
||||
---
|
||||
|
||||
## 2026-06-18: X-Macro 应用模块注册表 — 名称大小写匹配修复
|
||||
|
||||
**问题**:X-Macro 生成 g_vec_app 名称时使用 `"app_" #name`(如 `app_SYS`),但配置文件 `app_config.json` 使用小写 `app_sys`,导致名称不匹配,所有线程被 "skipped (disabled by config)"。
|
||||
|
||||
**根因**:C 预处理器 `#name` 运算符产生宏参数的原始文本,`APP_MODULE(SYS, ...)` → `"app_SYS"`,无法自动转小写。
|
||||
|
||||
**修复**:增加第二个参数 `cfg_name`(小写),与 `name`(大写,枚举后缀)分离:
|
||||
```c
|
||||
// 修改前: APP_MODULE(SYS, init1, init2, func)
|
||||
// 修改后: APP_MODULE(SYS, sys, init1, init2, func)
|
||||
```
|
||||
- `#cfg_name` → `"app_sys"`(匹配配置文件)
|
||||
|
||||
**涉及文件**:`app_modules.h`、`mySystem.h`(两处)、`app_sys.cpp`(一处)
|
||||
|
||||
**注意事项**:旧进程残留占端口会导致 `mms_s_init` 绑定失败。app_modules.h 禁止加 `#pragma once`。
|
||||
|
||||
**验证**:编译通过,8 个线程全部 `pthread_create success`。
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-16: ICP67 模块多实例重构
|
||||
|
||||
**来源**:[libicp67模块分析](./工程/libicp67模块分析.md)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
// ============================================================
|
||||
// 应用模块注册表 — X-Macro 中心化列表
|
||||
//
|
||||
// 注意:此文件故意不设 #pragma once 或 include guard,
|
||||
// 因为需要被多次包含(每次在不同的 APP_MODULE 宏定义下展开)
|
||||
// ============================================================
|
||||
|
||||
#ifndef APP_MODULE
|
||||
#error "APP_MODULE macro must be defined before including app_modules.h"
|
||||
#endif
|
||||
|
||||
// 格式: APP_MODULE(ENUM后缀, 配置名, init1, init2, thread入口)
|
||||
// - ENUM后缀: 用于生成 ENUM_APP_<后缀> 枚举值(大写)
|
||||
// - 配置名: 用于生成 "app_<配置名>" 匹配配置文件(小写)
|
||||
// - init1/init2/thread: 模块初始化函数和线程入口
|
||||
APP_MODULE(SYS, sys, app_sys_init1, app_sys_init2, app_sys )
|
||||
APP_MODULE(CMD, cmd, app_cmd_init1, app_cmd_init2, app_cmd )
|
||||
APP_MODULE(WEB_SERVER, web_server, app_web_server_init1, app_web_server_init2, app_web_server)
|
||||
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(SELF_PTL, self_ptl, app_self_ptl_init1, app_self_ptl_init2, app_self_ptl )
|
||||
APP_MODULE(IEC61850M, iec61850m, app_iec61850m_init1, app_iec61850m_init2, app_iec61850m )
|
||||
APP_MODULE(IEC61850S, iec61850s, app_iec61850s_init1, app_iec61850s_init2, app_iec61850s )
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// ============================================================
|
||||
// 消息队列注册表 — X-Macro 中心化列表
|
||||
//
|
||||
// 注意:此文件故意不设 #pragma once 或 include guard,
|
||||
// 因为需要被多次包含(每次在不同的 APP_MQ 宏定义下展开)
|
||||
// ============================================================
|
||||
|
||||
#ifndef APP_MQ
|
||||
#error "APP_MQ macro must be defined before including app_msg_queue.h"
|
||||
#endif
|
||||
|
||||
// 格式: APP_MQ(ENUM后缀, 配置名, msg_size, msg_num)
|
||||
// - ENUM后缀: 用于生成 ENUM_MQ_<后缀> 枚举值(大写)
|
||||
// - 配置名: 用于生成 "mq_<配置名>" 名称字符串(小写)
|
||||
// - msg_size: 消息大小(字节),应与 RTX_BUF_SIZE 匹配
|
||||
// - msg_num: 队列深度(消息个数)
|
||||
APP_MQ(COM_TO_IEC, com_to_iec, 2048, 8)
|
||||
APP_MQ(IEC_TO_COM, iec_to_com, 2048, 8)
|
||||
APP_MQ(COM_TO_SELF_PTL, com_to_self_ptl, 2048, 8)
|
||||
APP_MQ(SELF_PTL_TO_COM, self_ptl_to_com, 2048, 8)
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
|
||||
#define MSG_SIZE 2048 // 消息队列消息大小
|
||||
#define MSG_NUM 8 // 消息队列消息个数
|
||||
|
||||
|
||||
#define TIMER_NUM 3 // 定时器个数
|
||||
|
|
@ -38,32 +37,24 @@
|
|||
|
||||
// datacenter线程事件
|
||||
|
||||
// 消息队列枚举
|
||||
// 消息队列枚举 — 由 app_msg_queue.h X-macro 自动生成
|
||||
#define APP_MQ(name, cfg_name, msg_size, msg_num) ENUM_MQ_##name,
|
||||
typedef enum
|
||||
{
|
||||
ENUM_MQ_COM_TO_IEC, // 通讯线程到iec线程消息队列
|
||||
ENUM_MQ_IEC_TO_COM, // iec线程到通讯线程消息队列
|
||||
ENUM_MQ_COM_TO_SELF_PTL, // 通讯线程到icp67线程消息队列
|
||||
ENUM_MQ_SELF_PTL_TO_COM, // icp67线程到通讯线程消息队列
|
||||
|
||||
#include "app_msg_queue.h"
|
||||
ENUM_MQ_MAX
|
||||
}enun_msg_queue;
|
||||
#undef APP_MQ
|
||||
|
||||
|
||||
// 应用枚举
|
||||
// 应用枚举 — 由 app_modules.h X-macro 自动生成
|
||||
#define APP_MODULE(name, cfg_name, init1, init2, func) ENUM_APP_##name,
|
||||
typedef enum
|
||||
{
|
||||
ENUM_APP_SYS, // 系统应用
|
||||
ENUM_APP_CMD, // 命令行应用
|
||||
ENUM_APP_COM_DECODE, // 通讯编解码应用
|
||||
ENUM_APP_IEC, // iec101104应用
|
||||
ENUM_APP_SELF_PTL, // icp67应用
|
||||
ENUM_APP_WEB_SERVER, // web服务器应用
|
||||
ENUM_APP_IEC61850M, // iec61850m应用
|
||||
ENUM_APP_IEC61850S, // iec61850s应用
|
||||
|
||||
#include "app_modules.h"
|
||||
ENUM_APP_MAX
|
||||
}enum_app;
|
||||
#undef APP_MODULE
|
||||
|
||||
|
||||
// 通讯枚举
|
||||
|
|
@ -185,40 +176,14 @@ stru_app_msg_queue *app_get_msg_queue_ptr(uint32_t mq_id);
|
|||
// 应用指针获取函数,根据应用ID获取应用指针
|
||||
stru_app *app_get_ptr(uint32_t app_id);
|
||||
|
||||
// 命令行应用初始化与线程函数声明
|
||||
extern int app_cmd_init1(void *arg);
|
||||
extern int app_cmd_init2(void *arg);
|
||||
extern void *app_cmd(void *arg);
|
||||
// 应用初始化与线程函数声明 — 由 app_modules.h X-macro 自动生成
|
||||
#define APP_MODULE(name, cfg_name, init1, init2, func) \
|
||||
extern int init1(void *arg); \
|
||||
extern int init2(void *arg); \
|
||||
extern void *func(void *arg);
|
||||
|
||||
// 通讯编解码应用初始化与线程函数声明
|
||||
extern int app_com_decode_init1(void *arg);
|
||||
extern int app_com_decode_init2(void *arg);
|
||||
extern void *app_com_decode(void *arg);
|
||||
|
||||
// iec101104应用初始化与线程函数声明
|
||||
extern int app_iec_init1(void *arg);
|
||||
extern int app_iec_init2(void *arg);
|
||||
extern void *app_iec(void *arg);
|
||||
|
||||
// icp67应用初始化与线程函数声明
|
||||
extern int app_self_ptl_init1(void *arg);
|
||||
extern int app_self_ptl_init2(void *arg);
|
||||
extern void *app_self_ptl(void *arg);
|
||||
|
||||
// web服务器应用初始化与线程函数声明
|
||||
extern int app_web_server_init1(void *arg);
|
||||
extern int app_web_server_init2(void *arg);
|
||||
extern void *app_web_server(void *arg);
|
||||
|
||||
// iec61850m应用初始化与线程函数声明
|
||||
extern int app_iec61850m_init1(void *arg);
|
||||
extern int app_iec61850m_init2(void *arg);
|
||||
extern void *app_iec61850m(void *arg);
|
||||
|
||||
// iec61850s应用初始化与线程函数声明
|
||||
extern int app_iec61850s_init1(void *arg);
|
||||
extern int app_iec61850s_init2(void *arg);
|
||||
extern void *app_iec61850s(void *arg);
|
||||
#include "app_modules.h"
|
||||
#undef APP_MODULE
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,38 +1,140 @@
|
|||
#include "app_sys.h"
|
||||
#include "mySystem.h"
|
||||
#include "myFunc.h"
|
||||
#include "myLog.h"
|
||||
#include "myDatacenter.h"
|
||||
|
||||
#include "cJSON.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
|
||||
LOCAL int app_sys_init1(void *arg);
|
||||
LOCAL int app_sys_init2(void *arg);
|
||||
LOCAL void *app_sys(void *arg);
|
||||
|
||||
LOCAL std::set<std::string> g_enabled_apps; // 配置中启用的应用名集合
|
||||
|
||||
LOCAL std::string get_system_config_path()
|
||||
{
|
||||
char proc_dir[512] = {0};
|
||||
if(0 != func_get_process_self_dir(proc_dir, sizeof(proc_dir)))
|
||||
{
|
||||
MY_LOG_E("func_get_process_self_dir failed");
|
||||
return "";
|
||||
}
|
||||
return std::string(proc_dir) + "config/SYSTEM/";
|
||||
}
|
||||
|
||||
LOCAL int app_config_load()
|
||||
{
|
||||
std::string path = get_system_config_path();
|
||||
if(path.empty())
|
||||
{
|
||||
MY_LOG_E("get_system_config_path failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string cfg_path = path + "app_config.json";
|
||||
FILE *fp = fopen(cfg_path.c_str(), "rb");
|
||||
if(NULL == fp)
|
||||
{
|
||||
MY_LOG_E("cannot open app config: %s", cfg_path.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if(fsize <= 0)
|
||||
{
|
||||
fclose(fp);
|
||||
MY_LOG_E("app config file empty: %s", cfg_path.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = (char *)malloc((size_t)fsize + 1);
|
||||
if(NULL == buf)
|
||||
{
|
||||
fclose(fp);
|
||||
MY_LOG_E("malloc failed for app config");
|
||||
return -1;
|
||||
}
|
||||
size_t nread = fread(buf, 1, (size_t)fsize, fp);
|
||||
buf[nread] = '\0';
|
||||
fclose(fp);
|
||||
|
||||
cJSON *root = cJSON_Parse(buf);
|
||||
free(buf);
|
||||
if(NULL == root)
|
||||
{
|
||||
MY_LOG_E("cJSON_Parse failed for app config");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON *apps = cJSON_GetObjectItem(root, "apps");
|
||||
if(NULL == apps || !cJSON_IsArray(apps))
|
||||
{
|
||||
MY_LOG_E("app config 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(NULL == item) continue;
|
||||
|
||||
cJSON *name = cJSON_GetObjectItem(item, "name");
|
||||
cJSON *enable = cJSON_GetObjectItem(item, "enable");
|
||||
if(NULL == name || !cJSON_IsString(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(NULL != enable && cJSON_IsTrue(enable))
|
||||
{
|
||||
g_enabled_apps.insert(std::string(name->valuestring));
|
||||
MY_LOG_I("app enabled: %s", name->valuestring);
|
||||
}
|
||||
else
|
||||
{
|
||||
MY_LOG_I("app disabled: %s", name->valuestring);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
||||
if(g_enabled_apps.empty())
|
||||
{
|
||||
MY_LOG_E("no apps enabled in config, at least app_sys must be enabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int app_sys_init1(void *arg);
|
||||
int app_sys_init2(void *arg);
|
||||
void *app_sys(void *arg);
|
||||
LOCAL std::vector<stru_app_msg_queue> g_vec_app_msg_queue =
|
||||
{
|
||||
{"mq_com_to_iec", MSG_SIZE, MSG_NUM, NULL},
|
||||
{"mq_iec_to_com", MSG_SIZE, MSG_NUM, NULL},
|
||||
{"mq_com_to_self_ptl", MSG_SIZE, MSG_NUM, NULL},
|
||||
{"mq_self_ptl_to_com", MSG_SIZE, MSG_NUM, NULL},
|
||||
// 消息队列注册表 — 由 app_msg_queue.h X-macro 自动生成
|
||||
#define APP_MQ(name, cfg_name, msg_size, msg_num) \
|
||||
{"mq_" #cfg_name, msg_size, msg_num, NULL},
|
||||
|
||||
#include "app_msg_queue.h"
|
||||
#undef APP_MQ
|
||||
};
|
||||
|
||||
|
||||
LOCAL std::vector<stru_app> g_vec_app =
|
||||
{
|
||||
{"app_sys", 0, app_sys_init1, app_sys_init2, (app_func_cb)app_sys, NULL, 0, NULL},
|
||||
{"app_cmd", 0, app_cmd_init1, app_cmd_init2, (app_func_cb)app_cmd, NULL, 0, NULL},
|
||||
{"app_com_decode", 0, app_com_decode_init1, app_com_decode_init2, (app_func_cb)app_com_decode, NULL, 0, NULL},
|
||||
{"app_iec", 0, app_iec_init1, app_iec_init2, (app_func_cb)app_iec, NULL, 0, NULL},
|
||||
{"app_self_ptl", 0, app_self_ptl_init1, app_self_ptl_init2, (app_func_cb)app_self_ptl, NULL, 0, NULL},
|
||||
{"app_web_server", 0, app_web_server_init1, app_web_server_init2, (app_func_cb)app_web_server, NULL, 0, NULL},
|
||||
{"app_iec61850m", 0, app_iec61850m_init1, app_iec61850m_init2, (app_func_cb)app_iec61850m, NULL, 0, NULL},
|
||||
{"app_iec61850s", 0, app_iec61850s_init1, app_iec61850s_init2, (app_func_cb)app_iec61850s, NULL, 0, NULL},
|
||||
// 应用模块注册表 — 由 app_modules.h X-macro 自动生成
|
||||
#define APP_MODULE(name, cfg_name, init1, init2, func) \
|
||||
{"app_" #cfg_name, 0, init1, init2, (app_func_cb)func, NULL, 0, NULL},
|
||||
|
||||
#include "app_modules.h"
|
||||
#undef APP_MODULE
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -161,7 +263,13 @@ LOCAL int app_init()
|
|||
MY_LOG_E("app_timer_create failed, name:%s", p->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(g_enabled_apps.find(p->name) == g_enabled_apps.end())
|
||||
{
|
||||
MY_LOG_I("app skipped (disabled by config): %s", p->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(0 != pthread_create(&p->thread, NULL, p->fun_cb, p->arg))
|
||||
{
|
||||
MY_LOG_E("pthread_create failed, name:%s", p->name);
|
||||
|
|
@ -182,6 +290,13 @@ LOCAL int app_init()
|
|||
int app_sys_init(void)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
if(0 != app_config_load())
|
||||
{
|
||||
MY_LOG_E("app_config_load failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((size = g_vec_app_msg_queue.size()) != ENUM_MQ_MAX)
|
||||
{
|
||||
MY_LOG_E("g_vec_app_msg_queue size error, size = %d, ENUM num %d", size, ENUM_MQ_MAX);
|
||||
|
|
@ -235,7 +350,7 @@ stru_app *app_get_ptr(uint32_t app_id)
|
|||
|
||||
|
||||
|
||||
LOCAL int app_sys_init1(void *arg)
|
||||
int app_sys_init1(void *arg)
|
||||
{
|
||||
if(0 != datacenter_init())
|
||||
{
|
||||
|
|
@ -245,12 +360,12 @@ LOCAL int app_sys_init1(void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
LOCAL int app_sys_init2(void *arg)
|
||||
int app_sys_init2(void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOCAL void *app_sys(void *arg)
|
||||
void *app_sys(void *arg)
|
||||
{
|
||||
if(NULL == arg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"comment": "应用线程启动配置 — 修改 enable 字段控制线程是否启动",
|
||||
"apps": [
|
||||
{"name": "app_sys", "enable": true, "comment": "系统应用(数据中心,必须启用)"},
|
||||
{"name": "app_cmd", "enable": true, "comment": "命令行应用(SSH终端交互)"},
|
||||
{"name": "app_web_server", "enable": true, "comment": "Web 服务器(HTTP/WS,端口8000)"},
|
||||
{"name": "app_com_decode", "enable": true, "comment": "通讯编解码应用(串口/TCP收发)"},
|
||||
{"name": "app_iec", "enable": true, "comment": "IEC 101/104 协议应用"},
|
||||
{"name": "app_self_ptl", "enable": true, "comment": "ICP67 私有规约应用"},
|
||||
{"name": "app_iec61850m", "enable": true, "comment": "IEC 61850 MMS 客户端"},
|
||||
{"name": "app_iec61850s", "enable": true, "comment": "IEC 61850 MMS 服务端"}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue