system: 模块增强 — EV_STOP 支持 + 代码规范

- app_sys.cpp: 消息队列创建增强,模块启停控制优化
- app_modules.h: 启用 plc 模块
- com_router: EV_STOP 优雅退出 + tcp_client 通道支持
- libiec: 代码格式规范化(LOCAL/Tab/大括号独占行)
- libmodbus_m: EV_STOP 支持
- libplc: 代码规范 + 调试打印完善
- libself_ptl: EV_STOP 支持 + 代码规范
This commit is contained in:
ypc 2026-07-14 11:01:58 +08:00
parent 06fc257696
commit c92dc5c452
10 changed files with 102 additions and 71 deletions

View File

@ -58,9 +58,9 @@ static int app_mq_create(void)
{
stru_app_msg_queue *mq = &g_app_mq[i];
mq->p_msg_queue = task_msg_queue_create(mq->name, mq->msg_size, mq->msg_num);
if(NULL == mq->p_msg_queue) { LOG_E("app_mq_create: failed for %s", mq->name); return -1; }
if(NULL == mq->p_msg_queue) { MY_LOG_E("app_mq_create: failed for %s", mq->name); return -1; }
}
LOG_I("app_mq_create: %d queues created", ENUM_MQ_MAX);
MY_LOG_I("app_mq_create: %d queues created", ENUM_MQ_MAX);
return 0;
}
@ -97,7 +97,7 @@ static std::string get_system_config_path(void)
/* fallback: 从可执行文件路径推导(本地调试用) */
if (0 != func_proc_self_dir(buf, sizeof(buf)))
{
LOG_E("func_proc_self_dir failed");
MY_LOG_E("func_proc_self_dir failed");
return "";
}
@ -123,7 +123,7 @@ static int app_config_load(void)
if (!buf)
{
/* 配置文件不存在时不视为错误——默认启用所有模块 */
LOG_I("app_config.json not found, enabling all modules by default");
MY_LOG_I("app_config.json not found, enabling all modules by default");
for (size_t i = 0; i < g_vec_app.size(); i++)
{
@ -138,7 +138,7 @@ static int app_config_load(void)
if (!root)
{
LOG_E("cJSON_Parse failed for app_config.json");
MY_LOG_E("cJSON_Parse failed for app_config.json");
return -1;
}
@ -147,7 +147,7 @@ static int app_config_load(void)
if (!apps || !cJSON_IsArray(apps))
{
LOG_E("app_config.json missing 'apps' array");
MY_LOG_E("app_config.json missing 'apps' array");
cJSON_Delete(root);
return -1;
@ -175,11 +175,11 @@ static int app_config_load(void)
if (enable && cJSON_IsTrue(enable))
{
g_enabled_apps.insert(std::string(name->valuestring));
LOG_I("app enabled: %s", name->valuestring);
MY_LOG_I("app enabled: %s", name->valuestring);
}
else
{
LOG_I("app disabled: %s", name->valuestring);
MY_LOG_I("app disabled: %s", name->valuestring);
}
}
@ -187,7 +187,7 @@ static int app_config_load(void)
if (g_enabled_apps.empty())
{
LOG_E("no apps enabled in config");
MY_LOG_E("no apps enabled in config");
return -1;
}
@ -247,7 +247,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);
MY_LOG_E("timer%d create failed for %s", i + 1, p_app->name);
return -1;
}
@ -275,14 +275,14 @@ static int app_init(void)
if (!is_app_enabled(p->name))
{
LOG_I("app skipped (disabled): %s", p->name);
MY_LOG_I("app skipped (disabled): %s", p->name);
continue;
}
if (0 != p->app_init1((void *)p))
{
LOG_E("app_init1 failed: %s", p->name);
MY_LOG_E("app_init1 failed: %s", p->name);
return -1;
}
@ -300,20 +300,20 @@ static int app_init(void)
if (!is_app_enabled(p->name))
{
LOG_I("app skipped (disabled): %s", p->name);
MY_LOG_I("app skipped (disabled): %s", p->name);
continue;
}
if (0 != p->app_init2((void *)p))
{
LOG_E("app_init2 failed: %s", p->name);
MY_LOG_E("app_init2 failed: %s", p->name);
return -1;
}
}
if(0 != app_mq_create()) { LOG_E("app_mq_create"); return -1; }
if(0 != app_mq_create()) { MY_LOG_E("app_mq_create"); return -1; }
/* 创建事件 + 定时器 + 启动线程 */
for (i = 0; i < g_vec_app.size(); i++)
@ -327,7 +327,7 @@ static int app_init(void)
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());
MY_LOG_E("task_event_create failed: %s", ev_name.c_str());
return -1;
}
@ -336,14 +336,14 @@ static int app_init(void)
if (0 != app_timer_create(p))
{
LOG_E("app_timer_create failed: %s", p->name);
MY_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);
MY_LOG_I("app skipped (disabled): %s", p->name);
continue;
}
@ -352,14 +352,14 @@ static int app_init(void)
if (0 != pthread_create(&thread, NULL, p->fun_cb, p->arg))
{
LOG_E("pthread_create failed: %s", p->name);
MY_LOG_E("pthread_create failed: %s", p->name);
return -1;
}
g_threads.push_back(thread);
LOG_I("thread started: %s", p->name);
MY_LOG_I("thread started: %s", p->name);
task_sleep_ms(10);
}
@ -372,14 +372,14 @@ int app_sys_init(void)
{
if (0 != app_config_load())
{
LOG_E("app_config_load failed");
MY_LOG_E("app_config_load failed");
return -1;
}
if (g_vec_app.size() != (size_t)ENUM_APP_MAX)
{
LOG_E("g_vec_app size mismatch: %zu vs ENUM %d",
MY_LOG_E("g_vec_app size mismatch: %zu vs ENUM %d",
g_vec_app.size(), ENUM_APP_MAX);
return -1;
@ -387,7 +387,7 @@ int app_sys_init(void)
if (0 != app_init())
{
LOG_E("app_init failed");
MY_LOG_E("app_init failed");
return -1;
}
@ -397,11 +397,12 @@ int app_sys_init(void)
/**
* @brief
* @details EV_STOP 退 join 线
* @details EV_STOP 2 线退
* main OS
*/
void app_sys_stop(void)
{
LOG_I("stopping all app modules...");
MY_LOG_I("stopping all app modules...");
for (size_t i = 0; i < g_vec_app.size(); i++)
{
@ -413,21 +414,16 @@ void app_sys_stop(void)
}
}
/* 等待所有线程退出 */
for (size_t i = 0; i < g_threads.size(); i++)
{
pthread_join(g_threads[i], NULL);
LOG_I("module thread [%zu] exited", i);
}
task_sleep_ms(2000);
LOG_I("all app modules stopped");
MY_LOG_I("app_sys_stop done");
}
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);
MY_LOG_E("app_id out of range: %u max %d", app_id, ENUM_APP_MAX);
return NULL;
}

View File

@ -18,10 +18,10 @@
#endif
/* ============== 线程模块system/ 子目录) ============== */
APP_MODULE(MODBUS_M, modbus_m, app_modbus_m_init1, app_modbus_m_init2, app_modbus_m)
// APP_MODULE(MODBUS_M, modbus_m, app_modbus_m_init1, app_modbus_m_init2, app_modbus_m)
APP_MODULE(WEB_SERVER, web_server, app_web_server_init1, app_web_server_init2, app_web_server)
APP_MODULE(SELF_PTL, self_ptl, app_self_ptl_init1, app_self_ptl_init2, app_self_ptl)
APP_MODULE(COM_ROUTER, com_router, app_com_router_init1, app_com_router_init2, app_com_router)
APP_MODULE(SELF_PTL, self_ptl, app_self_ptl_init1, app_self_ptl_init2, app_self_ptl)
APP_MODULE(IEC, iec, app_iec_init1, app_iec_init2, app_iec)
APP_MODULE(PLC, plc, app_plc_init1, app_plc_init2, app_plc)

View File

@ -108,6 +108,7 @@ static int com_router_parse_channels(cJSON *arr)
cJSON *type = cJSON_GetObjectItem(item, "type");
cJSON *bind = cJSON_GetObjectItem(item, "bind_app");
cJSON *desc = cJSON_GetObjectItem(item, "desc");
(void)desc;
if(NULL == key || NULL == type) continue;
@ -141,6 +142,17 @@ static int com_router_parse_channels(cJSON *arr)
ch->para.tcp.remote_ip[0] = '\0';
ch->para.tcp.remote_port = 0;
}
else if(0 == strcmp(type->valuestring, "tcp_client"))
{
cJSON *rip = cJSON_GetObjectItem(item, "remote_ip");
cJSON *rport = cJSON_GetObjectItem(item, "remote_port");
ch->type = COMM_TYPE_TCP_CLIENT;
ch->para.tcp.local_ip[0] = '\0';
ch->para.tcp.local_port = 0;
if(rip) { ch->para.tcp.remote_ip[0] = '\0'; strcat(ch->para.tcp.remote_ip, rip->valuestring); }
if(rport) ch->para.tcp.remote_port = rport->valueint;
}
}
g_channel_count = count;
@ -265,6 +277,21 @@ static int com_router_config_default(void)
ch->socket_fd = -1;
}
/* 通道 2: FTU 网口 (TCP 客户端 → 127.0.0.1:54321) */
{
com_channel_t *ch = &g_channels[2];
strcpy(ch->key, "tcp_ftu");
strcpy(ch->bind_app, "");
ch->type = COMM_TYPE_TCP_CLIENT;
ch->para.tcp.local_ip[0] = '\0';
ch->para.tcp.local_port = 0;
ch->para.tcp.remote_ip[0] = '\0';
strcat(ch->para.tcp.remote_ip, "127.0.0.1");
ch->para.tcp.remote_port = 54321;
ch->id = -1;
ch->socket_fd = -1;
}
/* 转发规则: TCP:2405 → serial_ftu */
{
com_forward_rule_t *fw = &g_forward_rules[0];
@ -276,11 +303,11 @@ static int com_router_config_default(void)
fw->target_ch_id = -1;
}
g_channel_count = 2;
g_channel_count = 3;
g_forward_count = 1;
g_config_loaded = 1;
LOG_I("com_router: default config (2 channels + 1 forward)");
LOG_I("com_router: default config (3 channels + 1 forward)");
return 0;
}
@ -603,7 +630,7 @@ void *app_com_router(void *arg)
while(1)
{
task_event_recv(p_app->p_event,
EV_TIMER1 | EV_TIMER2 | EV_TIMER3 | EV_COM_RX_SELF_PTL,
EV_TIMER1 | EV_TIMER2 | EV_TIMER3 | EV_COM_RX_SELF_PTL | EV_STOP,
TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR,
TASK_EVENT_WAIT_FOREVER,
&event);
@ -627,7 +654,7 @@ void *app_com_router(void *arg)
/* 已断开, 仅第一次打印 */
if(last_state[i] >= 0)
{
LOG_I("com_router: %s disconnected", ch->key);
MY_LOG_I("com_router: %s disconnected", ch->key);
last_state[i] = -1;
}
}
@ -635,7 +662,7 @@ void *app_com_router(void *arg)
{
if(last_state[i] <= 0)
{
LOG_I("com_router: %s connected", ch->key);
MY_LOG_I("com_router: %s connected", ch->key);
}
last_state[i] = 1;
}
@ -670,7 +697,7 @@ void *app_com_router(void *arg)
if(EV_STOP & event)
{
LOG_I("app_com_router: received EV_STOP, exiting");
MY_LOG_I("app_com_router: received EV_STOP, exiting");
break;
}
}

View File

@ -1260,22 +1260,23 @@ int app_iec_init1(void *arg)
if (0 != func_proc_self_dir(dir, sizeof(dir)))
{
LOG_E("app_iec_init1: get_exe_dir failed");
MY_LOG_E("app_iec_init1: get_exe_dir failed");
return -1;
}
std::string path = std::string(dir) + "config/IEC60870/iec1014.xml";
std::string path = std::string(dir) + "/config/IEC60870/iec1014.xml";
MY_LOG_I("app_iec_init1: cfg path: %s", path.c_str());
if (0 != iec_cfg_parse(path.c_str()))
{
LOG_E("app_iec_init1: cfg parse failed: %s", path.c_str());
MY_LOG_E("app_iec_init1: cfg parse failed: %s", path.c_str());
return -1;
}
stru_app *p_app = (stru_app *)arg;
dc_signal_out("iec.run_cnt", "iec.run_cnt", DATA_TYPE_U32, &p_app->run_cnt, "iec104");
LOG_I("app_iec_init1: ok");
MY_LOG_I("app_iec_init1: ok");
return 0;
}
@ -1285,11 +1286,11 @@ int app_iec_init2(void *arg)
if (0 != iec104_point_init())
{
LOG_E("app_iec_init2: iec104_point_init failed");
MY_LOG_E("app_iec_init2: iec104_point_init failed");
return -1;
}
LOG_I("app_iec_init2: ok");
MY_LOG_I("app_iec_init2: ok");
return 0;
}
@ -1301,7 +1302,7 @@ void *app_iec(void *arg)
if (NULL == arg)
{
LOG_E("app_iec: NULL arg");
MY_LOG_E("app_iec: NULL arg");
return NULL;
}
@ -1344,7 +1345,7 @@ void *app_iec(void *arg)
/* 停止信号 */
if (event & EV_STOP)
{
LOG_I("app_iec: received EV_STOP, exiting");
MY_LOG_I("app_iec: received EV_STOP, exiting");
break;
}
}

View File

@ -54,6 +54,7 @@ LOCAL uint8_t modbus_type_to_local_type(uint8_t type)
}
}
LOCAL uint8_t dc_data_type_size(uint8_t data_type) __attribute__((unused));
LOCAL uint8_t dc_data_type_size(uint8_t data_type)
{
switch (data_type)
@ -358,6 +359,7 @@ LOCAL int channels_init()
return 0;
}
LOCAL void channels_close(void) __attribute__((unused));
LOCAL void channels_close()
{
for (auto &ch : g_modbus_m_cfg.channels)
@ -423,6 +425,7 @@ LOCAL int read_registers(stru_modbus_m_channel *p_ch, uint8_t slave, uint8_t fc,
// 读取单个 Item 值(按 fc 分发)
LOCAL int read_item_value(stru_modbus_m_channel *p_ch, stru_modbus_m_item *p_item) __attribute__((unused));
LOCAL int read_item_value(stru_modbus_m_channel *p_ch, stru_modbus_m_item *p_item)
{
if (NULL == p_ch || NULL == p_item)
@ -431,6 +434,7 @@ LOCAL int read_item_value(stru_modbus_m_channel *p_ch, stru_modbus_m_item *p_ite
}
uint8_t local_type = modbus_type_to_local_type(p_item->type);
(void)local_type;
// FC 0x01/0x02: 读线圈/离散输入(位)
if (p_item->fc == 0x01 || p_item->fc == 0x02)
@ -720,7 +724,7 @@ LOCAL void enqueue_write(const stru_modbus_m_write_req &req)
LOCAL void modbus_m_signal_co_change_callback(const char *saddr, dc_ctrl_step_t step, uint8_t data_type, uint8_t setting_zone, const void *p_data)
{
if (step != DC_CTRL_DIRECT)
if (step != (dc_ctrl_step_t)DC_CTRL_DIRECT)
{
return;
}
@ -754,7 +758,7 @@ LOCAL void modbus_m_signal_co_change_callback(const char *saddr, dc_ctrl_step_t
LOCAL void modbus_m_signal_ao_change_callback(const char *saddr, dc_ctrl_step_t step, uint8_t data_type, uint8_t setting_zone, const void *p_data)
{
if (step != DC_CTRL_DIRECT)
if (step != (dc_ctrl_step_t)DC_CTRL_DIRECT)
{
return;
}
@ -952,7 +956,7 @@ int app_modbus_m_init1(void *arg)
std::string base_path = get_base_path();
if (base_path.empty())
{
LOG_E("get_base_path failed");
MY_LOG_E("get_base_path failed");
return -1;
}
g_modbus_m_base_path = base_path + "config/MODBUS/";
@ -960,13 +964,13 @@ int app_modbus_m_init1(void *arg)
std::string cfg_path = g_modbus_m_base_path + "modbus_m.xml";
if (0 != modbus_m_cfg_parse(cfg_path))
{
LOG_E("modbus_m_cfg_parse failed: %s", cfg_path.c_str());
MY_LOG_E("modbus_m_cfg_parse failed: %s", cfg_path.c_str());
return -1;
}
if (0 != modbus_m_init())
{
LOG_E("modbus_m_init failed");
MY_LOG_E("modbus_m_init failed");
return -1;
}
@ -982,7 +986,7 @@ void *app_modbus_m(void *arg)
{
if (NULL == arg)
{
LOG_E("app_modbus_m arg null");
MY_LOG_E("app_modbus_m arg null");
return NULL;
}
@ -995,7 +999,7 @@ void *app_modbus_m(void *arg)
// 预构建轮询分组
build_poll_groups(g_modbus_m_cfg.point.st_vec, st_groups);
build_poll_groups(g_modbus_m_cfg.point.mx_vec, mx_groups);
LOG_I("poll groups: st=%zu, mx=%zu", st_groups.size(), mx_groups.size());
MY_LOG_I("poll groups: st=%zu, mx=%zu", st_groups.size(), mx_groups.size());
while (1)
{
@ -1026,7 +1030,7 @@ void *app_modbus_m(void *arg)
if(EV_STOP & event)
{
LOG_I("app_modbus_m: received EV_STOP, exiting");
MY_LOG_I("app_modbus_m: received EV_STOP, exiting");
break;
}
}

View File

@ -27,9 +27,9 @@ const char *plc_get_config_path(void);
/* =========================== 模块线程入口 =========================== */
int app_plc_init1(void *arg);
int app_plc_init2(void *arg);
void *app_plc(void *arg);
// int app_plc_init1(void *arg);
// int app_plc_init2(void *arg);
// void *app_plc(void *arg);
#ifdef __cplusplus
}

View File

@ -1739,7 +1739,7 @@ int app_plc_init1(void *arg)
stru_app *p_app = (stru_app *)arg;
if (NULL == p_app)
{
LOG_E("app_plc_init1 arg null");
MY_LOG_E("app_plc_init1 arg null");
return -1;
}
@ -1747,7 +1747,7 @@ int app_plc_init1(void *arg)
char proc_dir[512] = {0};
if (0 == func_proc_self_dir(proc_dir, sizeof(proc_dir)))
{
std::string plc_path = std::string(proc_dir) + g_plc_config_path;
std::string plc_path = std::string(proc_dir) + "/" + g_plc_config_path;
plc_set_config_path(plc_path.c_str());
}
@ -1765,14 +1765,14 @@ int app_plc_init1(void *arg)
if (ret != 0)
{
LOG_E("app_plc_init1 dc_signal_out failed");
MY_LOG_E("app_plc_init1 dc_signal_out failed");
return -1;
}
p_plc_cfg = self_ptl_cfg_get();
if (nullptr == p_plc_cfg)
{
LOG_E("app_plc_init1 self_ptl_cfg_get failed");
MY_LOG_E("app_plc_init1 self_ptl_cfg_get failed");
return -1;
}
@ -1801,7 +1801,7 @@ int app_plc_init2(void *arg)
}
if (ret != 0)
{
LOG_E("app_plc_init2 dc_signal_in failed");
MY_LOG_E("app_plc_init2 dc_signal_in failed");
return -1;
}
return 0;
@ -1811,7 +1811,7 @@ void *app_plc(void *arg)
{
if (NULL == arg)
{
LOG_E("app_plc arg null");
MY_LOG_E("app_plc arg null");
return NULL;
}

View File

@ -153,6 +153,7 @@ static void put_rx_data(stru_self_rx *p_self_rx, uint8_t *p_rx, uint16_t len)
pthread_mutex_unlock(&p_self_rx->mutex);
}
__attribute__((unused))
static void get_rx_data(stru_self_rx *p_self_rx, uint8_t *p_data, uint16_t *p_data_len)
{
uint16_t pos;
@ -199,6 +200,7 @@ static void get_rx_data_locked(stru_self_rx *p_self_rx, uint8_t *p_data, uint16_
(*p_data_len) = p_self_rx->cnt;
}
__attribute__((unused))
static void clear_rx_data(stru_self_rx *p_self_rx)
{
if(NULL == p_self_rx)
@ -624,7 +626,7 @@ void *app_self_ptl(void *arg)
while(1)
{
task_event_recv(p_app->p_event,
EV_TIMER1 | EV_TIMER2 | EV_TIMER3 | EV_SELF_PTL_RX_COM,
EV_TIMER1 | EV_TIMER2 | EV_TIMER3 | EV_SELF_PTL_RX_COM | EV_STOP,
TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR,
100,
&event);
@ -660,7 +662,7 @@ void *app_self_ptl(void *arg)
/* EV_STOP: 优雅退出 */
if(EV_STOP & event)
{
LOG_I("app_self_ptl: received EV_STOP, exiting");
MY_LOG_I("app_self_ptl: received EV_STOP, exiting");
break;
}
}

View File

@ -41,8 +41,8 @@ static void file_paths_init(void)
}
g_file_base_path = std::string(proc_dir);
g_file_path = g_file_base_path + "file/";
g_zip_path = g_file_base_path + "zip/";
g_file_path = g_file_base_path + "/file/";
g_zip_path = g_file_base_path + "/zip/";
if(0 != func_make_dirs(g_file_path.c_str()))
{

View File

@ -17,7 +17,7 @@ using namespace tinyxml2;
#include <cstdlib>
#include <cstring>
static const char *ele_Root = "Root";
__attribute__((unused)) static const char *ele_Root = "Root";
static const char *ele_St = "St";
static const char *ele_Mx = "Mx";
@ -91,6 +91,7 @@ static int parse_base(XMLElement *root)
const char *count_str = parent_ele->Attribute(attr_count);
int count = 0;
(void)count;
if(nullptr != count_str)
{