diff --git a/release/inc/myDatacenter.h b/release/inc/myDatacenter.h new file mode 100644 index 0000000..4b33056 --- /dev/null +++ b/release/inc/myDatacenter.h @@ -0,0 +1,175 @@ +#pragma once + + +#include "myBase.h" +#include +#include +#include + + + + +// 信号控制枚举 +enum SIGNAL_CTRL_TYPE +{ + NONE, // 无 + DIRECT_NORMAL, // 直控 + SBO_NORMAL, // 选控 +}; + +// 信号控制步骤枚举 +enum SIGNAL_CTRL_STEP +{ + READY, // 准备 + SELECT, // 选择 + DIRECT, // 执行 + CANCEL, // 取消 +}; + +// 数据中心信号控制结构体 +typedef struct +{ + uint8_t step:2; // 控制步骤 + uint8_t type:2; // 控制类型 + uint8_t backup:4; // 备用字节 + uint8_t data_type; // 数据类型 + void *p_data; // 数据指针 +}stru_signal_ctrl; + +typedef struct +{ + float min; // 最小值 + float max; // 最大值 + float step; // 步长 + std::string unit; // 单位 + // std::string default_value; // 默认值字符串 + // void *p_default; // 默认值 +}stru_signal_param; + + +typedef void (*out_signal_change_cb)(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data); +typedef void (*signal_change_cb)(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data); + + +int datacenter_init(); +void datacenter_run_100ms(); +void datacenter_run_1000ms(); + + +// 数据中心out信号注册接口 +int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data); + +int dc_signal_out_with_callback(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data, out_signal_change_cb cb); + +int dc_signal_out_link_with_callback(const std::string &saddr, void **p_data, out_signal_change_cb cb); + +// 数据中心in信号注册并链接out信号接口 +int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data); + +int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data, out_signal_change_cb cb); + +int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, void *p_default_data, signal_change_cb cb); + +int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb); + +int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); + +int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data); + +// 数据中心参数信号注册接口 +int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data, signal_change_cb cb); + +// 数据中心参数链接信号接口 +int dc_signal_param_link_with_callback(const std::string &saddr, std::vector &vec_p_data, signal_change_cb cb); + +// 数据中心参数设置接口 +int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, uint8_t setting_zone, void *p_data); + +int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, uint8_t setting_zone, void *p_data); + +// 数据中心遥控信号注册接口 +int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb); + +// 数据中心遥控信号链接接口 +int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb); + +// 数据中心遥控控制接口(校验前置,调用前需先调 dc_yk_ctrl_valid) +int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); + +// 数据中心获取out信号信息接口 +int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); + +// 数据中心获取in信号信息接口 +int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); + +int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, void **p_data, void **p_default_data); + +// 数据中心获取参数信号信息接口 +int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, std::vector *p_vec_p_data, std::vector *p_vec_p_default_data); + +// 数据中心获取遥控信号信息接口 +int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, void **p_data); + +// 数据中心获取信号值字符串接口 +std::string dc_get_signal_val(void *p_data, uint8_t data_type); + +// 数据中心设置信号值字符串接口 +int dc_set_out_signal_val(const std::string &saddr, void *set_data); + +// 数据中心根据数据类型创建数据指针接口 +void *dc_create_data_ptr_by_type(uint8_t data_type); + +void dc_delete_signal_data(void *p_data, uint8_t data_type); + +// 数据中心根据数据类型ID获取数据类型字符串接口 +std::string dc_get_data_type_str_by_id(uint8_t data_type); + +// 数据中心根据数据类型字符串获取数据类型ID接口 +uint8_t dc_get_data_type_id_by_str(const std::string &data_type_str); + +uint8_t dc_get_data_type_len(uint8_t data_type); + +void dc_set_signal_val_from_str(void *p_data, uint8_t data_type, const std::string &str); + + + +typedef struct +{ + std::string saddr; + float fVal; + uint32_t sec; + uint16_t ms; +}stru_disturb_dd; + +typedef struct +{ + std::string saddr; + uint8_t status; + uint32_t sec; + uint16_t ums; +}stru_dc_soe; + +typedef struct +{ + std::string saddr; + float fVal; +}stru_dc_disturb_yc; + +typedef struct +{ + std::vector vec_soe; + std::vector vec_disturb_yc; +}stru_dc_fault; + + +typedef void (*dc_queue_pop_cb)(void *p_data); + + +int dc_disturb_dd_queue_push(const stru_disturb_dd &dd); +int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb cb); + +int dc_event_queue_push(const stru_dc_soe &soe); +int dc_event_register_queue_pop(dc_queue_pop_cb cb); + +int dc_fault_queue_push(const stru_dc_fault &fault); +int dc_fault_register_queue_pop(dc_queue_pop_cb cb); diff --git a/release/inc/mySystem.h b/release/inc/mySystem.h index b2d1b62..71e1000 100644 --- a/release/inc/mySystem.h +++ b/release/inc/mySystem.h @@ -53,8 +53,8 @@ typedef enum // 应用枚举 typedef enum { + ENUM_APP_SYS, // 系统应用 ENUM_APP_CMD, // 命令行应用 - ENUM_APP_DATACENTER, // 数据中心应用 ENUM_APP_COMM, // 通讯通道应用 ENUM_APP_COM_SCAN, // 通讯扫描应用 ENUM_APP_IEC, // iec101104应用 @@ -191,11 +191,6 @@ extern int app_cmd_init1(void *arg); extern int app_cmd_init2(void *arg); extern void *app_cmd(void *arg); -// 数据中心应用初始化与线程函数声明 -extern int app_datacenter_init1(void *arg); -extern int app_datacenter_init2(void *arg); -extern void *app_datacenter(void *arg); - // 通讯转发应用初始化与线程函数声明 extern int app_com_scan_init1(void *arg); extern int app_com_scan_init2(void *arg); @@ -301,119 +296,3 @@ stru_self_ptl_cfg* self_ptl_cfg_get(); - -// 信号控制枚举 -enum SIGNAL_CTRL_TYPE -{ - NONE, // 无 - DIRECT_NORMAL, // 直控 - SBO_NORMAL, // 选控 -}; - -// 信号控制步骤枚举 -enum SIGNAL_CTRL_STEP -{ - READY, // 准备 - SELECT, // 选择 - DIRECT, // 执行 - CANCEL, // 取消 -}; - -// 数据中心信号控制结构体 -typedef struct -{ - uint8_t step:2; // 控制步骤 - uint8_t type:2; // 控制类型 - uint8_t backup:4; // 备用字节 - uint8_t data_type; // 数据类型 - void *p_data; // 数据指针 -}stru_signal_ctrl; - -typedef struct -{ - float min; // 最小值 - float max; // 最大值 - float step; // 步长 - std::string unit; // 单位 - // std::string default_value; // 默认值字符串 - // void *p_default; // 默认值 -}stru_signal_param; - - -typedef void (*out_signal_change_cb)(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data); -typedef void (*signal_change_cb)(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data); - - - -// 数据中心out信号注册接口 -int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data); - -int dc_signal_out_with_callback(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data, out_signal_change_cb cb); - -// 数据中心in信号注册并链接out信号接口 -int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data); - -int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data, out_signal_change_cb cb); - -int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, void *p_default_data, signal_change_cb cb); - -int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb); - -int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); - -int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data); - -// 数据中心参数信号注册接口 -int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data, signal_change_cb cb); - -// 数据中心参数链接信号接口 -int dc_signal_param_link_with_callback(const std::string &saddr, std::vector &vec_p_data, signal_change_cb cb); - -// 数据中心参数设置接口 -int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, uint8_t setting_zone, void *p_data); - -int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, uint8_t setting_zone, void *p_data); - -// 数据中心遥控信号注册接口 -int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb); - -// 数据中心遥控信号链接接口 -int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb); - -// 数据中心遥控控制接口(校验前置,调用前需先调 dc_yk_ctrl_valid) -int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); - -// 数据中心获取out信号信息接口 -int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); - -// 数据中心获取in信号信息接口 -int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); - -int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, void **p_data, void **p_default_data); - -// 数据中心获取参数信号信息接口 -int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, std::vector *p_vec_p_data, std::vector *p_vec_p_default_data); - -// 数据中心获取遥控信号信息接口 -int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, void **p_data); - -// 数据中心获取信号值字符串接口 -std::string dc_get_signal_val(void *p_data, uint8_t data_type); - -// 数据中心设置信号值字符串接口 -int dc_set_out_signal_val(const std::string &saddr, void *set_data); - -// 数据中心根据数据类型创建数据指针接口 -void *dc_create_data_ptr_by_type(uint8_t data_type); - -void dc_delete_signal_data(void *p_data, uint8_t data_type); - -// 数据中心根据数据类型ID获取数据类型字符串接口 -std::string dc_get_data_type_str_by_id(uint8_t data_type); - -// 数据中心根据数据类型字符串获取数据类型ID接口 -uint8_t dc_get_data_type_id_by_str(const std::string &data_type_str); - -uint8_t dc_get_data_type_len(uint8_t data_type); - -void dc_set_signal_val_from_str(void *p_data, uint8_t data_type, const std::string &str); \ No newline at end of file diff --git a/src/system/RTU/src/app_sys.cpp b/src/system/RTU/src/app_sys.cpp index 1866da4..caf5940 100644 --- a/src/system/RTU/src/app_sys.cpp +++ b/src/system/RTU/src/app_sys.cpp @@ -1,13 +1,17 @@ #include "app_sys.h" #include "mySystem.h" #include "myLog.h" - +#include "myDatacenter.h" #include #include +LOCAL int app_sys_init1(void *arg); +LOCAL int app_sys_init2(void *arg); +LOCAL void *app_sys(void *arg); + LOCAL std::vector g_vec_app_msg_queue = @@ -21,8 +25,8 @@ LOCAL std::vector g_vec_app_msg_queue = LOCAL std::vector 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_datacenter", 0, app_datacenter_init1, app_datacenter_init2, (app_func_cb)app_datacenter, NULL, 0, NULL}, {"app_comm_channel",0, app_com_channel_init1, app_com_channel_init2, (app_func_cb)app_com_channel, NULL, 0, NULL}, {"app_com_scan", 0, app_com_scan_init1, app_com_scan_init2, (app_func_cb)app_com_scan, NULL, 0, NULL}, {"app_iec", 0, app_iec_init1, app_iec_init2, (app_func_cb)app_iec, NULL, 0, NULL}, @@ -231,3 +235,57 @@ stru_app *app_get_ptr(uint32_t app_id) + +LOCAL int app_sys_init1(void *arg) +{ + if(0 != datacenter_init()) + { + MY_LOG_E("app_sys_init failed"); + return -1; + } + return 0; +} + +LOCAL int app_sys_init2(void *arg) +{ + return 0; +} + +LOCAL void *app_sys(void *arg) +{ + if(NULL == arg) + { + LOG_E("app_sys arg null"); + return NULL; + } + + stru_app *p_app = (stru_app *)arg; + uint32_t event; + + while(1) + { + task_event_recv(p_app->p_event, + EV_TIMER1 | EV_TIMER2 | EV_TIMER3, + TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR, + TASK_EVENT_WAIT_FOREVER, + &event); + + if(event & EV_TIMER1) + { + ; + } + + if(event & EV_TIMER2) + { + datacenter_run_100ms(); + } + + if(event & EV_TIMER3) + { + datacenter_run_1000ms(); + p_app->run_cnt++; + } + } + + return NULL; +} diff --git a/src/system/RTU/src/self_ptl_cfg.cpp b/src/system/RTU/src/self_ptl_cfg.cpp index d273330..20ef255 100644 --- a/src/system/RTU/src/self_ptl_cfg.cpp +++ b/src/system/RTU/src/self_ptl_cfg.cpp @@ -1,6 +1,7 @@ #include "myBase.h" #include "mySystem.h" #include "tinyxml2.h" +#include "myDatacenter.h" LOCAL const char *ele_Root = "Root"; diff --git a/src/system/libdatacenter/inc/dc_event.h b/src/system/libdatacenter/inc/dc_event.h new file mode 100644 index 0000000..9fc9978 --- /dev/null +++ b/src/system/libdatacenter/inc/dc_event.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + + +void dc_disturb_dd_queue_pop(); +void dc_event_queue_pop(); +void dc_fault_queue_pop(); \ No newline at end of file diff --git a/src/system/libdatacenter/inc/dc_param.h b/src/system/libdatacenter/inc/dc_param.h index 7986e5a..7456be2 100644 --- a/src/system/libdatacenter/inc/dc_param.h +++ b/src/system/libdatacenter/inc/dc_param.h @@ -1,8 +1,8 @@ #pragma once #include "myBase.h" -#include "mySystem.h" #include "dc_signal.h" +#include "myDatacenter.h" #define DC_PARAM_PATH "/mnt/RTU/test/file/PARAM/param.xml" diff --git a/src/system/libdatacenter/inc/dc_signal.h b/src/system/libdatacenter/inc/dc_signal.h index b7d1f06..4024301 100644 --- a/src/system/libdatacenter/inc/dc_signal.h +++ b/src/system/libdatacenter/inc/dc_signal.h @@ -1,15 +1,17 @@ #pragma once + + #include "myBase.h" #include "xxhash.h" -#include "mySystem.h" + #include #include #include #include - +#include "myDatacenter.h" typedef struct stru_signal { uint32_t id; diff --git a/src/system/libdatacenter/src/datacenter.cpp b/src/system/libdatacenter/src/datacenter.cpp index c2f36bb..134ef23 100644 --- a/src/system/libdatacenter/src/datacenter.cpp +++ b/src/system/libdatacenter/src/datacenter.cpp @@ -1,64 +1,30 @@ -#include "mySystem.h" + #include "myLog.h" #include "dc_param.h" #include "dc_signal.h" +#include "dc_event.h" - -int app_datacenter_init1(void *arg) +int datacenter_init() { dc_param_cfg_parse(); return 0; } -int app_datacenter_init2(void *arg) +void datacenter_run_100ms() { - return 0; + dc_signal_out_change_check(); + dc_disturb_dd_queue_pop(); + dc_event_queue_pop(); + dc_fault_queue_pop(); } - -void *app_datacenter(void *arg) +void datacenter_run_1000ms() { - if(NULL == arg) - { - LOG_E("app_datacenter: arg is NULL"); - return NULL; - } + dc_param_cfg_check(); +} - stru_app *p_app = (stru_app *)arg; - - uint32_t event; - stru_app_msg_queue *p_mq = NULL; - stru_msg_head *p_head = NULL; - stru_rtx_data *p_rtx = &p_app->rtx; - - while(1) - { - task_event_recv(p_app->p_event, - EV_TIMER1 | EV_TIMER2 | EV_TIMER3 , - TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR, - TASK_EVENT_WAIT_FOREVER, - &event); - - - if(event & EV_TIMER1) - { - ; - } - - if(event & EV_TIMER2) - { - dc_signal_out_change_check(); - } - - if(event & EV_TIMER3) - { - dc_param_cfg_check(); - p_app->run_cnt++; - } - } -} \ No newline at end of file diff --git a/src/system/libdatacenter/src/dc_event.cpp b/src/system/libdatacenter/src/dc_event.cpp new file mode 100644 index 0000000..d694e00 --- /dev/null +++ b/src/system/libdatacenter/src/dc_event.cpp @@ -0,0 +1,147 @@ +#include +#include +#include + +#include "dc_event.h" +#include "myLog.h" + +#include "myDatacenter.h" + +LOCAL std::mutex g_disturb_dd_mutex; +LOCAL std::queue g_disturb_dd_queue; +LOCAL std::vector g_disturb_dd_queue_pop_cbs; + +LOCAL std::mutex g_soe_mutex; +LOCAL std::queue g_soe_queue; +LOCAL std::vector g_soe_queue_pop_cbs; + +LOCAL std::mutex g_fault_mutex; +LOCAL std::queue g_fault_queue; +LOCAL std::vector g_fault_queue_pop_cbs; + + +int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb cb) +{ + if(!cb) + { + LOG_E("dc_disturb_dd_register_queue_pop: cb is nullptr"); + return -1; + } + + std::lock_guard lock(g_disturb_dd_mutex); + g_disturb_dd_queue_pop_cbs.push_back(cb); + return 0; +} + +int dc_disturb_dd_queue_push(const stru_disturb_dd &dd) +{ + std::lock_guard lock(g_disturb_dd_mutex); + g_disturb_dd_queue.push(dd); + return 0; +} + +void dc_disturb_dd_queue_pop() +{ + std::queue local_queue; + std::vector local_cbs; + + { + std::lock_guard lock(g_disturb_dd_mutex); + local_queue.swap(g_disturb_dd_queue); + local_cbs = g_disturb_dd_queue_pop_cbs; + } + + while(!local_queue.empty()) + { + const auto &dd = local_queue.front(); + for(const auto &cb : local_cbs) + { + cb((void *)&dd); + } + local_queue.pop(); + } +} + +int dc_event_register_queue_pop(dc_queue_pop_cb cb) +{ + if(!cb) + { + LOG_E("dc_event_register_queue_pop: cb is nullptr"); + return -1; + } + + std::lock_guard lock(g_soe_mutex); + g_soe_queue_pop_cbs.push_back(cb); + return 0; +} + +int dc_event_queue_push(const stru_dc_soe &soe) +{ + std::lock_guard lock(g_soe_mutex); + g_soe_queue.push(soe); + return 0; +} + +void dc_event_queue_pop() +{ + std::queue local_queue; + std::vector local_cbs; + + { + std::lock_guard lock(g_soe_mutex); + local_queue.swap(g_soe_queue); + local_cbs = g_soe_queue_pop_cbs; + } + + while(!local_queue.empty()) + { + const auto &soe = local_queue.front(); + for(const auto &cb : local_cbs) + { + cb((void *)&soe); + } + local_queue.pop(); + } +} + +int dc_fault_register_queue_pop(dc_queue_pop_cb cb) +{ + if(!cb) + { + LOG_E("dc_fault_register_queue_pop: cb is nullptr"); + return -1; + } + + std::lock_guard lock(g_fault_mutex); + g_fault_queue_pop_cbs.push_back(cb); + return 0; +} + +int dc_fault_queue_push(const stru_dc_fault &fault) +{ + std::lock_guard lock(g_fault_mutex); + g_fault_queue.push(fault); + return 0; +} + +void dc_fault_queue_pop() +{ + std::queue local_queue; + std::vector local_cbs; + + { + std::lock_guard lock(g_fault_mutex); + local_queue.swap(g_fault_queue); + local_cbs = g_fault_queue_pop_cbs; + } + + while(!local_queue.empty()) + { + const auto &fault = local_queue.front(); + for(const auto &cb : local_cbs) + { + cb((void *)&fault); + } + local_queue.pop(); + } +} \ No newline at end of file diff --git a/src/system/libdatacenter/src/dc_signal.cpp b/src/system/libdatacenter/src/dc_signal.cpp index 4c2574c..abf3396 100644 --- a/src/system/libdatacenter/src/dc_signal.cpp +++ b/src/system/libdatacenter/src/dc_signal.cpp @@ -8,11 +8,12 @@ #include "dc_signal.h" #include "dc_param.h" #include "myLog.h" -#include "mySystem.h" #include "myCmd.h" #include "tinyxml2.h" +#include "myDatacenter.h" + struct XXH128Hash { size_t operator()(const XXH128_hash_t& h) const noexcept { // 低版本库无XXH3_64bits_fromCanonical,手动混合高低64位生成哈希 @@ -952,6 +953,34 @@ int dc_signal_out_with_callback(const std::string &saddr, const std::string &des return dc_signal_add_to_map(signal, g_datacenter.signal_out); } +int dc_signal_out_link_with_callback(const std::string &saddr, void **p_data, out_signal_change_cb cb) +{ + stru_signal *p_signal = dc_find_out_signal(saddr); + if(nullptr == p_signal) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + + if(p_signal->vec_p_data.empty() || nullptr == p_signal->vec_p_data[0]) + { + MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); + return -1; + } + + if(p_data != nullptr) + { + (*p_data) = p_signal->vec_p_data[0]; + } + + if(nullptr != cb) + { + p_signal->out_change_cb_list.push_back(cb); + } + + return 0; +} + int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data) { if(p_data == nullptr) diff --git a/src/system/libiec/inc/iec_cfg_parse.h b/src/system/libiec/inc/iec_cfg_parse.h index 830608c..addc842 100644 --- a/src/system/libiec/inc/iec_cfg_parse.h +++ b/src/system/libiec/inc/iec_cfg_parse.h @@ -6,14 +6,15 @@ typedef struct { - std::string saddr; + // std::string saddr; std::string desc; std::string link; uint16_t inf; uint8_t type; - std::vector vec_p_data; - std::vector vec_p_last_data; - std::vector vec_p_default_data; + uint8_t invert; // 遥信专用,遥测没有该属性 + float factor; // 遥测专用,遥信没有该属性 + float offset; // 遥测专用,遥信没有该属性 + void *p_data; }stru_cfg_base; diff --git a/src/system/libiec/inc/iec_method.h b/src/system/libiec/inc/iec_method.h index 19593a6..0bbb73c 100644 --- a/src/system/libiec/inc/iec_method.h +++ b/src/system/libiec/inc/iec_method.h @@ -2,7 +2,7 @@ #include "myBase.h" #include "iec.h" -#include "lib60870_common.h" +// #include "lib60870_common.h" #include @@ -87,17 +87,21 @@ typedef struct stYX_CHANGE_INFO astSoeInfo[SOE_LEN]; //soe信息 }stSOE_INFORM; - +#ifdef SRC_INC_IEC60870_COMMON_H_ +#include "lib60870_common.h" +typedef __CP56Time2a stCP56Time2a; +#else typedef struct { - uint8_t ucLMs; /*毫秒低位*/ - uint8_t ucHMs; /*毫秒高位*/ - uint8_t ucMin; /*分钟*/ - uint8_t ucHour; /*小时*/ - uint8_t ucWeek; /*week: 0-不用,n-星期n */ - uint8_t ucMonth; /*月*/ - uint8_t ucYear; /*年*/ + u8 ucLMs; /*毫秒低位*/ + u8 ucHMs; /*毫秒高位*/ + u8 ucMin; /*分钟*/ + u8 ucHour; /*小时*/ + u8 ucWeek; /*week: 0-不用,n-星期n */ + u8 ucMonth; /*月*/ + u8 ucYear; /*年*/ } stCP56Time2a; +#endif /** * @brief SOE 记录信息 @@ -121,6 +125,31 @@ typedef struct float fVal; /*遥测值*/ }stYcInfo; + +/** +* @brief 单条DD记录结构 +*/ +typedef struct +{ + uint16_t usIndex; // 序号 数据表中的位置 + float fDdValue; // 电度 + stCP56Time2a stTime; // 发生时间stTime; + uint16_t usMs; // SOE时标 毫秒 + uint32_t uiSeconds; // SOE时标 秒 +}stDD_RECORD; + +/** +* @brief 电度记录缓存区 +*/ +typedef struct +{ + bool isInit; + sem_t sem; + uint16_t usInptr; /*入指针*/ + std::vector astOutptr; + stDD_RECORD astDd[Dd_LEN]; +}stDD_CHANGE_INFORM; + /** * @brief 单条故障事件结构体(通信板) */ @@ -159,6 +188,8 @@ int32_t GetYcValueByGroup(uint16_t usGroupID, uint16_t usIdx, Yc_Info *pstInfo, int32_t GetDiturbYc(Yc_Info *pstInfo, void *pvParam, uint32_t uiPos); int32_t GetDiturbYcSendNum(void *pvArg); int32_t UpdateDiturbYcPtrOut(void *pvParam, uint32_t uiPos); +int UserWriteDisturbYc(uint16_t usIndex, float fVal); + int32_t GetYxCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf); int32_t GetYxStatusByGroup(uint16_t usGroupID, uint16_t usIdx, Yx_Info *pstInfo, void *pvParam); @@ -166,12 +197,23 @@ int32_t GetYxStatusByGroup(uint16_t usGroupID, uint16_t usIdx, Yx_Info *pstInfo, int32_t GetSOE(SOE_Info *pstInfo, void *pvParam, uint32_t uiPos); int32_t GetSOESendNum(void *pvArg); int32_t UpdateSoePtrOut(void *pvParam, uint32_t uiPos); +int UserWriteSoeEvent(uint16_t usIndex, uint8_t ucState, uint32_t uiSeconds, uint16_t usMs); int32_t GetDdCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf, uint8_t ucTimeEn); int32_t GetDdValueByGroup(uint16_t usGroupID, uint16_t usIdx, TimeDd_Info *pstInfo, void *pvParam, uint8_t ucTimeEn); +int32_t GetTimeDdu(TimeDd_Info *pstInfo, void *pvParam, uint32_t uiPos); +int32_t GetTimeDduSendNum(void *pvArg); +int32_t UpdateTimeDduPtrOut(void *pvParam, uint32_t uiPos); +int UserWriteDisturbDd(uint16_t usIndex, float fVal, uint32_t uiSeconds, uint16_t usMs); int32_t GetEventSendNum(void *pvArg); int32_t GetFaultEvent(FAULT_EVENT_Info *pstInfo, void *pvParam, uint32_t uiPos); int32_t UpdateFaultEventPtrOut(void *pvParam, uint32_t uiPos); +int UserWriteFaultEvent(stSOEInfo *pstInfo, uint8_t ucYxNum, stYcInfo *pstYcInfo, uint8_t ucYcNum); + +uint8_t Cs10xYkVerifyItfs(void *pvParam); + +uint16_t GbParamGetParamArea(uint8_t ucType, void *pvHandle); +uint16_t GbParamSetParamArea(uint16_t usArea, void *pvHandle); diff --git a/src/system/libiec/inc/iec_point.h b/src/system/libiec/inc/iec_point.h new file mode 100644 index 0000000..7fad55f --- /dev/null +++ b/src/system/libiec/inc/iec_point.h @@ -0,0 +1,9 @@ +#pragma once + +#include "myBase.h" +#include "mySystem.h" + +#include "iec_cfg_parse.h" +#include "iec.h" + +int iec_point_init(); \ No newline at end of file diff --git a/src/system/libiec/src/iec.cpp b/src/system/libiec/src/iec.cpp index e842ba4..31ac0ed 100644 --- a/src/system/libiec/src/iec.cpp +++ b/src/system/libiec/src/iec.cpp @@ -4,10 +4,11 @@ #include "iec.h" #include "iec_method.h" #include "iec_cfg_parse.h" +#include "iec_point.h" +#include "myDatacenter.h" - -stru_iec_60870 g_iec60870[MAX_IEC_NUM]; -uint32_t g_uilinkOverTime = 600000; +LOCAL stru_iec_60870 g_iec60870[MAX_IEC_NUM]; +LOCAL uint32_t g_uilinkOverTime = 600000; int iec_data_tx(uint8_t *p_tx, uint16_t tx_len, void *arg); @@ -89,29 +90,29 @@ void set_ptl_itfc(stru_iec_60870 *p_iec) { CS10x *pstCs10x = &p_iec->cs10x; /*系统时间接口*/ - // CS10x_TimeRWHandler(pstCs10x, GetTimeItfs, SetTimeItfs); - // CS10x_WR_ResetHandler(pstCs10x, Cs10xReadFileResetCOI, Cs10xWriteFileResetCOI); + CS10x_TimeRWHandler(pstCs10x, GetTimeItfs, SetTimeItfs); + CS10x_WR_ResetHandler(pstCs10x, Cs10xReadFileResetCOI, Cs10xWriteFileResetCOI); /*子站时,配置获取信息接口*/ if (CS104_TYPE_S == p_iec->iec_type || CS101_TYPE_S == p_iec->iec_type) { /*遥测接口*/ - // CS10x_S_GetYcByGroupHandler(pstCs10x, GetYcCountByGroup, GetYcValueByGroup); + CS10x_S_GetYcByGroupHandler(pstCs10x, GetYcCountByGroup, GetYcValueByGroup); /*扰动遥测接口*/ - // CS10x_S_DiturbYcHandler(pstCs10x, GetDiturbYc, GetDiturbYcSendNum, UpdateDiturbYcPtrOut); + CS10x_S_DiturbYcHandler(pstCs10x, GetDiturbYc, GetDiturbYcSendNum, UpdateDiturbYcPtrOut); /*遥信接口*/ - // CS10x_S_GetYxByGroupHandler(pstCs10x, GetYxCountByGroup, GetYxStatusByGroup); + CS10x_S_GetYxByGroupHandler(pstCs10x, GetYxCountByGroup, GetYxStatusByGroup); /*SOE接口*/ - // CS10x_S_SOEHandler(pstCs10x, GetSOE, GetSOESendNum, UpdateSoePtrOut); + CS10x_S_SOEHandler(pstCs10x, GetSOE, GetSOESendNum, UpdateSoePtrOut); /*电能量接口*/ - // CS10x_S_GetDdByGroupHandler(pstCs10x,GetDdCountByGroup,GetDdValueByGroup); + CS10x_S_GetDdByGroupHandler(pstCs10x,GetDdCountByGroup,GetDdValueByGroup); /*扰动电度接口*/ - // CS10x_S_DiturbDduHandler(pstCs10x, GetTimeDdu, GetTimeDduSendNum, UpdateTimeDduPtrOut); + CS10x_S_DiturbDduHandler(pstCs10x, GetTimeDdu, GetTimeDduSendNum, UpdateTimeDduPtrOut); /*故障事件接口*/ - // CS10x_S_FaultEventHandler(pstCs10x, GetEventSendNum, GetFaultEvent, UpdateFaultEventPtrOut); + CS10x_S_FaultEventHandler(pstCs10x, GetEventSendNum, GetFaultEvent, UpdateFaultEventPtrOut); /*遥控操作校验*/ - // CS10x_S_YkVerifyHandler(pstCs10x, Cs10xYkVerifyItfs); + CS10x_S_YkVerifyHandler(pstCs10x, Cs10xYkVerifyItfs); /*定值区号相关接口*/ - // CS10x_S_ParamAreaHandler(pstCs10x, GbParamGetParamArea, GbParamSetParamArea); + CS10x_S_ParamAreaHandler(pstCs10x, GbParamGetParamArea, GbParamSetParamArea); // /*IECP参数相关接口*/ // CS10x_S_IECParamHandler(pstCs10x, GbParamAddElement, GbParamRunRding, GbParamRunWting); // /*获取参数信息相关接口*/ @@ -297,20 +298,6 @@ LOCAL void iec60870_decode(uint8_t *data, uint16_t len, uint32_t interface) CS10x_DoRecv(&p_iec->cs10x, (char *)data, len); } -LOCAL void iec_signal_link_change(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data) -{ - if(saddr.empty() || NULL == p_data || NULL == p_last_data) - { - return; - } - - -} - -LOCAL void iec_signal_ctrl_change(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data) -{ - -} int iec_data_tx(uint8_t *p_tx, uint16_t tx_len, void *arg) { @@ -407,6 +394,12 @@ void iec60870_task(uint16_t usGap) int app_iec_init1(void *arg) { + if(0 != iec_cfg_parse("/mnt/RTU/test/config/iec1014.xml")) + { + MY_LOG_E("app_iec_init1 iec_cfg_parse failed"); + 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); @@ -415,57 +408,12 @@ int app_iec_init1(void *arg) int app_iec_init2(void *arg) { - stru_iec_cfg *p_iec_cfg = iec_cfg_ptr_get(); - if(NULL == p_iec_cfg) + if(0 != iec_point_init()) { - LOG_E("iec_cfg_ptr_get return NULL"); + MY_LOG_E("app_iec_init2 iec_point_init failed"); return -1; } - int ret = 0; - std::vector *p_vec = nullptr; - - std::vector *> vec_st_mx_dd = {&p_iec_cfg->vec_st, &p_iec_cfg->vec_mx, &p_iec_cfg->vec_dd}; - std::vector *> vec_co_ao_param = {&p_iec_cfg->vec_co, &p_iec_cfg->vec_ao, &p_iec_cfg->vec_param}; - - for(uint32_t i = 0; i < vec_st_mx_dd.size(); i++) - { - p_vec = vec_st_mx_dd[i]; - for(uint32_t j = 0; j < p_vec->size(); j++) - { - void *p_data = nullptr; - ret = dc_signal_in_with_callback(p_vec->at(j).saddr, p_vec->at(j).desc, p_vec->at(j).link, &p_data, iec_signal_link_change); - if(ret != 0) - { - LOG_E("dc_signal_in failed, saddr %s, desc %s, link %s, type %s", - p_vec->at(j).saddr, p_vec->at(j).desc, p_vec->at(j).link, dc_get_data_type_str_by_id(p_vec->at(j).type)); - return -1; - } - - p_vec->at(j).vec_p_data.push_back(p_data); - } - } - - for(uint32_t i = 0; i < vec_co_ao_param.size(); i++) - { - p_vec = vec_co_ao_param[i]; - for(uint32_t j = 0; j < p_vec->size(); j++) - { - void *p_data = nullptr; - ret = dc_signal_yk_link_with_callback(p_vec->at(j).saddr, &p_data, iec_signal_ctrl_change); - if(ret != 0) - { - LOG_E("dc_signal_yk_link failed, saddr %s, type %s", - p_vec->at(j).saddr, dc_get_data_type_str_by_id(p_vec->at(j).type)); - return -1; - } - - p_vec->at(j).vec_p_data.push_back(p_data); - } - - } - - return 0; } diff --git a/src/system/libiec/src/iec_cfg_parse.cpp b/src/system/libiec/src/iec_cfg_parse.cpp index 47793a3..096eff0 100644 --- a/src/system/libiec/src/iec_cfg_parse.cpp +++ b/src/system/libiec/src/iec_cfg_parse.cpp @@ -1,5 +1,6 @@ #include "iec_cfg_parse.h" #include +#include "myDatacenter.h" using namespace tinyxml2; @@ -13,11 +14,15 @@ LOCAL const char *ele_Param = "Param"; LOCAL const char *ele_Signal = "Signal"; LOCAL const char *ele_Item = "Item"; -LOCAL const char *attr_saddr = "saddr"; +// LOCAL const char *attr_saddr = "saddr"; LOCAL const char *attr_desc = "desc"; LOCAL const char *attr_link = "link"; LOCAL const char *attr_inf = "inf"; LOCAL const char *attr_type = "type"; +LOCAL const char *attr_invert = "invert"; +LOCAL const char *attr_factor = "factor"; +LOCAL const char *attr_offset = "offset"; + LOCAL stru_iec_cfg g_iec_cfg = {}; @@ -60,17 +65,23 @@ LOCAL int parse_base(XMLElement *root) while(signal_ele != nullptr) { stru_cfg_base cfg_base = {}; - const char *saddr = signal_ele->Attribute(attr_saddr); + // const char *saddr = signal_ele->Attribute(attr_saddr); const char *desc = signal_ele->Attribute(attr_desc); const char *link = signal_ele->Attribute(attr_link); const char *inf = signal_ele->Attribute(attr_inf); const char *type = signal_ele->Attribute(attr_type); + const char *invert = signal_ele->Attribute(attr_invert); + const char *factor = signal_ele->Attribute(attr_factor); + const char *offset = signal_ele->Attribute(attr_offset); - cfg_base.saddr = (saddr == nullptr ? "" : std::string(saddr)); + // cfg_base.saddr = (saddr == nullptr ? "" : std::string(saddr)); cfg_base.desc = (desc == nullptr ? "" : std::string(desc)); cfg_base.link = (link == nullptr ? "" : std::string(link)); cfg_base.inf = (inf == nullptr ? 0 : atoi(inf)); cfg_base.type = (type == nullptr ? 0 : dc_get_data_type_id_by_str(type)); + cfg_base.invert = (invert == nullptr ? 0 : atoi(invert)); + cfg_base.factor = (factor == nullptr ? 0 : atof(factor)); + cfg_base.offset = (offset == nullptr ? 0 : atof(offset)); if(cfg_base.type == 0) { diff --git a/src/system/libiec/src/iec_method.cpp b/src/system/libiec/src/iec_method.cpp index d075d4d..8bd4efa 100644 --- a/src/system/libiec/src/iec_method.cpp +++ b/src/system/libiec/src/iec_method.cpp @@ -1,688 +1,769 @@ -// #include "iec_method.h" - -// #include "mySystem.h" +#include "iec_method.h" +#include "mySystem.h" +#include "iec_point.h" +#include "myLog.h" - - -// #define YX_START_PORT 0x01 //遥信起始位置 -// #define YC_START_PORT 0x4001 //遥测起始位置 -// #define DD_START_PORT 0x6401 //电度起始位置 +#define YX_START_PORT 0x01 //遥信起始位置 +#define YC_START_PORT 0x4001 //遥测起始位置 +#define DD_START_PORT 0x6401 //电度起始位置 -// stDISTURB_YC_AVR g_stDisturbYcAvr = {.isInit = false}; -// stSOE_INFORM g_stSoeInform = {.isInit = false}; -// stFAULT_INFORM_MAIN g_stFaultInformMain = {.isInit = false}; +stDISTURB_YC_AVR g_stDisturbYcAvr = {.isInit = false}; +stSOE_INFORM g_stSoeInform = {.isInit = false}; +stDD_CHANGE_INFORM g_stDdChangeInform = {.isInit = false}; +stFAULT_INFORM_MAIN g_stFaultInformMain = {.isInit = false}; -// int GetTimeItfs(__CP56Time2a *pTime) -// { -// return 0; -// } +int GetTimeItfs(__CP56Time2a *pTime) +{ + return 0; +} -// int SetTimeItfs(__CP56Time2a *pTime) -// { +int SetTimeItfs(__CP56Time2a *pTime) +{ -// return 0; -// } + return 0; +} -// void StampToCp56(__CP56Time2a *pTime, uint32_t uiSeconds, uint16_t usMs) -// { -// if(NULL == pTime) -// { -// return; -// } +void StampToCp56(__CP56Time2a *pTime, uint32_t uiSeconds, uint16_t usMs) +{ + if(NULL == pTime) + { + return; + } -// // 1. 处理毫秒:拆分高低8位 -// uint16_t ms = usMs % 1000; // 确保毫秒范围 0~999 -// pTime->ucLMs = (unsigned char)(ms & 0xFF); // 低8位 -// pTime->ucHMs = (unsigned char)((ms >> 8) & 0x01); // 高8位(仅用bit0) + const time_t stStamp = uiSeconds; + struct tm *pstNow; + uint8_t ucWeek; + + pstNow = gmtime(&stStamp); + + // usMs += pstNow->tm_sec * 1000; // 当前的ms中已经带了秒了,后续估计会调整 + ucWeek = pstNow->tm_wday == 0?7:pstNow->tm_wday; + pTime->ucYear = pstNow->tm_year - 100; + pTime->ucMonth = pstNow->tm_mon + 1; + pTime->ucWeek = pstNow->tm_mday | (ucWeek << 5); + pTime->ucHour = pstNow->tm_hour; + pTime->ucMin = pstNow->tm_min; + pTime->ucHMs = usMs >> 8; + pTime->ucLMs = usMs; +} -// // 2. 从秒时间戳分解 年/月/日/时/分/秒/星期 -// const uint16_t month_days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; -// uint32_t sec = uiSeconds; -// uint32_t day_cnt = sec / 86400; // 总天数 -// uint32_t sec_today = sec % 86400; // 当日秒数 - -// // 分解时分 -// pTime->ucHour = (unsigned char)(sec_today / 3600); -// uint32_t remain_sec = sec_today % 3600; -// pTime->ucMin = (unsigned char)(remain_sec / 60); - -// // 计算星期(基准:1970-01-01 是周四) -// pTime->ucWeek = (unsigned char)((day_cnt + 4) % 7); -// if(pTime->ucWeek == 0) pTime->ucWeek = 7; // 周日=7,符合CP56规范 - -// // 计算年月日(相对于2000年) -// uint32_t year = 1970; -// while(1) -// { -// uint8_t is_leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); -// uint16_t days = is_leap ? 366 : 365; -// if(day_cnt < days) break; -// day_cnt -= days; -// year++; -// } - -// // 计算月 -// uint8_t is_leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); -// uint32_t month = 0; -// while(1) -// { -// uint16_t m_days = month_days[month]; -// if(month == 1 && is_leap) m_days = 29; // 闰年2月 -// if(day_cnt < m_days) break; -// day_cnt -= m_days; -// month++; -// } -// pTime->ucMonth = month + 1; -// pTime->ucYear = (unsigned char)(year - 2000); // 年份=实际年份-2000 -// } - -// void Cs10xWriteFileResetCOI(uint8_t ucCoi) -// { -// // SysResetDelay(5); //延迟重启 +void Cs10xWriteFileResetCOI(uint8_t ucCoi) +{ + // SysResetDelay(5); //延迟重启 -// return; -// } + return; +} -// uint8_t Cs10xReadFileResetCOI(void) -// { -// return 0; -// } +uint8_t Cs10xReadFileResetCOI(void) +{ + return 0; +} -// /** -// * @brief 获取遥测数据组中的遥测数目 -// * @param[in] usGroupID-组号 20是总招 21-36是组招 pvParam-设备指针 -// * @param[in] pvParam-通信口指针 -// * @param[out] puiStartInf-起始信息体地址 -// * @param[out] puiEndInf-结束信息体地址 -// * @return 数量 0-表示该分组未配置数据 g_astYcTable -// */ -// int32_t GetYcCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf) -// { -// stru_app_cfg *p_app_cfg = get_app_cfg_ptr(); +/** + * @brief 获取遥测数据组中的遥测数目 + * @param[in] usGroupID-组号 20是总招 21-36是组招 pvParam-设备指针 + * @param[in] pvParam-通信口指针 + * @param[out] puiStartInf-起始信息体地址 + * @param[out] puiEndInf-结束信息体地址 + * @return 数量 0-表示该分组未配置数据 g_astYcTable + */ +int32_t GetYcCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf) +{ + std::vector &vec_mx = iec_cfg_ptr_get()->vec_mx; -// *puiStartInf = YC_START_PORT; -// *puiEndInf = YC_START_PORT + p_app_cfg->mx_info_vec.size(); + *puiStartInf = YC_START_PORT; + *puiEndInf = YC_START_PORT + vec_mx.size(); -// return p_app_cfg->mx_info_vec.size(); -// } + return vec_mx.size(); +} -// /** -// * @brief 总召获取遥测数据值 -// * @param[in] usGroupID-组号 未用 -// * @param[in] usIdx-组内ID从0开始 -// * @param[in] pvParam-设备指针 -// * @param[out] pstInfo-数据指针 -// * @return 0-失败 1-成功 -// */ -// int32_t GetYcValueByGroup(uint16_t usGroupID, uint16_t usIdx, Yc_Info *pstInfo, void *pvParam) -// { -// uint16_t usTabIdx = 0; -// uint16_t usInfoAddr = 0; -// stYC_TABLE stYcTable = {0}; +/** + * @brief 总召获取遥测数据值 + * @param[in] usGroupID-组号 未用 + * @param[in] usIdx-组内ID从0开始 + * @param[in] pvParam-设备指针 + * @param[out] pstInfo-数据指针 + * @return 0-失败 1-成功 +*/ +int32_t GetYcValueByGroup(uint16_t usGroupID, uint16_t usIdx, Yc_Info *pstInfo, void *pvParam) +{ + uint16_t usTabIdx = 0; + uint16_t usInfoAddr = 0; + stYC_TABLE stYcTable = {0}; -// stru_app_cfg *p_app_cfg = get_app_cfg_ptr(); -// uint32_t yc_config_num = p_app_cfg->mx_info_vec.size(); + std::vector &vec_mx = iec_cfg_ptr_get()->vec_mx; + uint32_t yc_config_num = vec_mx.size(); -// if(usIdx > yc_config_num) /*总召遥测数量超过配置遥测数量*/ -// { -// return 0; -// } -// // usInfoAddr = usIdx + YC_START_PORT; -// /*遥测置数数据*/ -// // if(g_stYcYxSet.uiYcHoldTime) -// // { -// // for(ucI=0;ucIfVal = g_stYcYxSet.astYcSetParam[ucI].fYcValue; -// // pstInfo->uiInfoAddr = usInfoAddr; -// // return 1; -// // } -// // } -// // } + if(usIdx > yc_config_num) /*总召遥测数量超过配置遥测数量*/ + { + return 0; + } + // usInfoAddr = usIdx + YC_START_PORT; + /*遥测置数数据*/ +// if(g_stYcYxSet.uiYcHoldTime) +// { +// for(ucI=0;ucIfVal = g_stYcYxSet.astYcSetParam[ucI].fYcValue; +// pstInfo->uiInfoAddr = usInfoAddr; +// return 1; +// } +// } +// } -// stru_iec_mx_info *p_mx_info = &p_app_cfg->mx_info_vec[usIdx]; + stru_cfg_base *p_mx_info = &vec_mx[usIdx]; + float fVal = 0; + if(p_mx_info->p_data == NULL) + { + fVal = 0; // 遥测值,默认为0 + } + else + { + fVal = *(float *)p_mx_info->p_data; + } + pstInfo->fVal = fVal * p_mx_info->factor + p_mx_info->offset; + pstInfo->uiInfoAddr = p_mx_info->inf; -// pstInfo->fVal = p_mx_info->data * p_mx_info->factor; -// pstInfo->uiInfoAddr = p_mx_info->inf; - -// return 1; -// } + return 1; +} -// stINFOR_OUT *GetInforOut(void *pvParam, std::vector &stInforOut) -// { -// uint32_t interface = *(uint32_t *)pvParam; -// stru_iec_60870 *p_iec = iec60870_get_by_interface(interface); +stINFOR_OUT *GetInforOut(void *pvParam, std::vector &stInforOut) +{ + uint32_t interface = *(uint32_t *)pvParam; + stru_iec_60870 *p_iec = iec60870_get_by_interface(interface); -// for(uint32_t i = 0; i < stInforOut.size(); i++) -// { -// if(stInforOut[i].ucPrtocol == p_iec->iec_type && stInforOut[i].uiChannelType == interface) -// { -// return &stInforOut[i]; -// } -// } + for(uint32_t i = 0; i < stInforOut.size(); i++) + { + if(stInforOut[i].ucPrtocol == p_iec->iec_type && stInforOut[i].uiChannelType == interface) + { + return &stInforOut[i]; + } + } -// stINFOR_OUT stInfor; -// stInfor.ucPrtocol = p_iec->iec_type; -// stInfor.uiChannelType = interface; -// stInfor.usOutNum = 0; -// stInforOut.push_back(stInfor); + stINFOR_OUT stInfor; + stInfor.ucPrtocol = p_iec->iec_type; + stInfor.uiChannelType = interface; + stInfor.usOutNum = 0; + stInforOut.push_back(stInfor); -// return &stInforOut.back(); -// } + return &stInforOut.back(); +} -// void local_sem_init(bool &isInit, sem_t *p_sem) -// { -// if(!isInit) -// { -// sem_init(p_sem, 0, 1); -// isInit = true; -// } -// } +void local_sem_init(bool &isInit, sem_t *p_sem) +{ + if(!isInit) + { + sem_init(p_sem, 0, 1); + isInit = true; + } +} -// int UserWriteDisturbYc(uint16_t usIndex, float fVal) -// { -// usIndex += YC_START_PORT; +int UserWriteDisturbYc(uint16_t usIndex, float fVal) +{ + usIndex += YC_START_PORT; -// local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); -// sem_wait(&g_stDisturbYcAvr.sem); -// g_stDisturbYcAvr.astYc[g_stDisturbYcAvr.usInptr].usIndex = usIndex; -// g_stDisturbYcAvr.astYc[g_stDisturbYcAvr.usInptr].fVal = fVal; -// g_stDisturbYcAvr.usInptr++; -// g_stDisturbYcAvr.usInptr %= DISTURB_YC_LEN; -// sem_post(&g_stDisturbYcAvr.sem); + local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); + sem_wait(&g_stDisturbYcAvr.sem); + g_stDisturbYcAvr.astYc[g_stDisturbYcAvr.usInptr].usIndex = usIndex; + g_stDisturbYcAvr.astYc[g_stDisturbYcAvr.usInptr].fVal = fVal; + g_stDisturbYcAvr.usInptr++; + g_stDisturbYcAvr.usInptr %= DISTURB_YC_LEN; + sem_post(&g_stDisturbYcAvr.sem); -// return 1; -// } + return 1; +} -// /** -// * @brief 数据表中获取扰动遥测数据 -// * @param[in] *pvParam 通信接口 -// * @param[in] uiPos 取数据的偏移量 -// * @param[out] *pstInfo 获取单条扰动数据值和点号 -// * @return -// */ -// int32_t GetDiturbYc(Yc_Info *pstInfo, void *pvParam, uint32_t uiPos) -// { -// uint8_t ucInforNum = 0; -// stYC_RECORD stYcInfo; +/** + * @brief 数据表中获取扰动遥测数据 + * @param[in] *pvParam 通信接口 + * @param[in] uiPos 取数据的偏移量 + * @param[out] *pstInfo 获取单条扰动数据值和点号 + * @return + */ +int32_t GetDiturbYc(Yc_Info *pstInfo, void *pvParam, uint32_t uiPos) +{ + uint8_t ucInforNum = 0; + stYC_RECORD stYcInfo; -// stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stDisturbYcAvr.astOutptr); + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stDisturbYcAvr.astOutptr); -// local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); -// sem_wait(&g_stDisturbYcAvr.sem); -// uint16_t pos = uiPos + pstInfor->usOutNum; -// pos %= DISTURB_YC_LEN; + local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); + sem_wait(&g_stDisturbYcAvr.sem); + uint16_t pos = uiPos + pstInfor->usOutNum; + pos %= DISTURB_YC_LEN; -// pstInfo->uiInfoAddr = g_stDisturbYcAvr.astYc[pos].usIndex; -// pstInfo->fVal = g_stDisturbYcAvr.astYc[pos].fVal; + pstInfo->uiInfoAddr = g_stDisturbYcAvr.astYc[pos].usIndex; + pstInfo->fVal = g_stDisturbYcAvr.astYc[pos].fVal; -// sem_post(&g_stDisturbYcAvr.sem); + sem_post(&g_stDisturbYcAvr.sem); -// return 1; -// } + return 1; +} -// /** -// * @brief 获取扰动遥测数量 -// * @param[in] pvArg - 通信接口指针 -// * @param[out] 无 -// * @return 失败返回0, 成功返回>0 -// */ -// int32_t GetDiturbYcSendNum(void *pvArg) -// { -// int32_t iSendNum = 0; +/** + * @brief 获取扰动遥测数量 + * @param[in] pvArg - 通信接口指针 + * @param[out] 无 + * @return 失败返回0, 成功返回>0 + */ +int32_t GetDiturbYcSendNum(void *pvArg) +{ + int32_t iSendNum = 0; -// stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stDisturbYcAvr.astOutptr); + stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stDisturbYcAvr.astOutptr); -// local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); -// sem_wait(&g_stDisturbYcAvr.sem); + local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); + sem_wait(&g_stDisturbYcAvr.sem); -// if(g_stDisturbYcAvr.usInptr >= pstInfor->usOutNum) -// { -// iSendNum = g_stDisturbYcAvr.usInptr - pstInfor->usOutNum; -// } -// else -// { -// iSendNum = DISTURB_YC_LEN - pstInfor->usOutNum + g_stDisturbYcAvr.usInptr; -// } + if(g_stDisturbYcAvr.usInptr >= pstInfor->usOutNum) + { + iSendNum = g_stDisturbYcAvr.usInptr - pstInfor->usOutNum; + } + else + { + iSendNum = DISTURB_YC_LEN - pstInfor->usOutNum + g_stDisturbYcAvr.usInptr; + } -// sem_post(&g_stDisturbYcAvr.sem); + sem_post(&g_stDisturbYcAvr.sem); -// return iSendNum; -// } + return iSendNum; +} -// /** -// * @brief 数据表中更新扰动遥测数据出指针接口函数 -// * @param[in] pvParam - 通信接口指针 -// * @param[in] uiPos 取数据的偏移量 表征取出记录个数 -// * @return 0-异常 1-正常 -// */ -// int32_t UpdateDiturbYcPtrOut(void *pvParam, uint32_t uiPos) -// { -// uint8_t ucInforNum = 0; +/** + * @brief 数据表中更新扰动遥测数据出指针接口函数 + * @param[in] pvParam - 通信接口指针 + * @param[in] uiPos 取数据的偏移量 表征取出记录个数 + * @return 0-异常 1-正常 + */ +int32_t UpdateDiturbYcPtrOut(void *pvParam, uint32_t uiPos) +{ + uint8_t ucInforNum = 0; -// if(uiPos == 0 || pvParam == NULL) -// { -// return 0; -// } + if(uiPos == 0 || pvParam == NULL) + { + return 0; + } -// stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stDisturbYcAvr.astOutptr); + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stDisturbYcAvr.astOutptr); -// local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); -// sem_wait(&g_stDisturbYcAvr.sem); -// pstInfor->usOutNum += uiPos; -// pstInfor->usOutNum %= DISTURB_YC_LEN; -// sem_post(&g_stDisturbYcAvr.sem); + local_sem_init(g_stDisturbYcAvr.isInit, &g_stDisturbYcAvr.sem); + sem_wait(&g_stDisturbYcAvr.sem); + pstInfor->usOutNum += uiPos; + pstInfor->usOutNum %= DISTURB_YC_LEN; + sem_post(&g_stDisturbYcAvr.sem); -// return 1; -// } + return 1; +} -// /** -// * @brief 数据表中获取遥信数据组中的遥信数目的接口函数 -// * @param[in] ucGroupID-组号 20是总招 21-36是组招 未用 -// * @param[in] pvParam-设备指针 数据传输路径 -// * @param[out] puiStartInf-起始信息体地址 从1开始 -// * @param[out] puiEndInf-结束信息体地址 -// * @return 已配遥信数量 -// */ -// int32_t GetYxCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf) -// { - -// stru_app_cfg *p_app_cfg = get_app_cfg_ptr(); +/** + * @brief 数据表中获取遥信数据组中的遥信数目的接口函数 + * @param[in] ucGroupID-组号 20是总招 21-36是组招 未用 + * @param[in] pvParam-设备指针 数据传输路径 + * @param[out] puiStartInf-起始信息体地址 从1开始 + * @param[out] puiEndInf-结束信息体地址 + * @return 已配遥信数量 + */ +int32_t GetYxCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf) +{ + std::vector &vec_st = iec_cfg_ptr_get()->vec_st; -// *puiStartInf = YX_START_PORT; -// *puiEndInf = *puiStartInf + p_app_cfg->st_info_vec.size(); + *puiStartInf = YX_START_PORT; + *puiEndInf = *puiStartInf + vec_st.size(); -// return p_app_cfg->st_info_vec.size(); -// } + return vec_st.size(); +} -// /** -// *@brief 总召获取遥信数据 -// * @param[in] ucGroupID-组号 未使用 -// * @param[in] usIdx-遥信数据偏移量 从0开始 -// * @param[in] pvParam-设备指针 数据传输路径 -// * @param[out] pstInfo-数据指针 获取遥信状态信息 -// * @return 0-获取数据失败 1-成功 -// */ -// int32_t GetYxStatusByGroup(uint16_t usGroupID, uint16_t usIdx, Yx_Info *pstInfo, void *pvParam) -// { -// uint16_t usTabIdx = 0; /*数据表下标*/ -// uint16_t usInfoAddr = 0; -// uint32_t uiItfs = *(uint32_t*)pvParam; /*通信接口*/ -// stru_iec_60870 *p_iec = {0}; /*规约实体*/ -// // stYX_TABLE stYxTable = {0}; /*单个点号配置信息*/ +/** + *@brief 总召获取遥信数据 + * @param[in] ucGroupID-组号 未使用 + * @param[in] usIdx-遥信数据偏移量 从0开始 + * @param[in] pvParam-设备指针 数据传输路径 + * @param[out] pstInfo-数据指针 获取遥信状态信息 + * @return 0-获取数据失败 1-成功 +*/ +int32_t GetYxStatusByGroup(uint16_t usGroupID, uint16_t usIdx, Yx_Info *pstInfo, void *pvParam) +{ + uint16_t usTabIdx = 0; /*数据表下标*/ + uint16_t usInfoAddr = 0; + uint32_t uiItfs = *(uint32_t*)pvParam; /*通信接口*/ + stru_iec_60870 *p_iec = {0}; /*规约实体*/ + // stYX_TABLE stYxTable = {0}; /*单个点号配置信息*/ -// stru_app_cfg *p_app_cfg = get_app_cfg_ptr(); -// uint32_t yx_config_num = p_app_cfg->st_info_vec.size(); + std::vector &vec_st = iec_cfg_ptr_get()->vec_st; + uint32_t yx_config_num = vec_st.size(); -// if(usIdx > yx_config_num) /*默认遥信全配置 后续改遥信配置数量*/ -// { -// return 0; -// } + if(usIdx > yx_config_num) /*默认遥信全配置 后续改遥信配置数量*/ + { + return 0; + } -// usInfoAddr = usIdx + YX_START_PORT; -// /*遥信置数*/ -// // if(g_stYcYxSet.uiYxHoldTime) -// // { -// // for(ucI=0;ucIucStatus = g_stYcYxSet.astYxSetParam[ucI].ucYxValue; -// // pstInfo->uiInfoAddr = usInfoAddr; -// // return 1; -// // } -// // } -// // } + usInfoAddr = usIdx + YX_START_PORT; + /*遥信置数*/ +// if(g_stYcYxSet.uiYxHoldTime) +// { +// for(ucI=0;ucIucStatus = g_stYcYxSet.astYxSetParam[ucI].ucYxValue; +// pstInfo->uiInfoAddr = usInfoAddr; +// return 1; +// } +// } +// } -// stru_iec_st_info *p_st_info = &p_app_cfg->st_info_vec[usIdx]; + stru_cfg_base *p_st_info = &vec_st[usIdx]; -// pstInfo->ucStatus = p_st_info->data; -// pstInfo->uiInfoAddr = p_st_info->inf; -// pstInfo->ucStateType = 0; /*遥信单双点属性*/ + pstInfo->ucStatus = p_st_info->p_data ? *((uint8_t *)p_st_info->p_data) : 0; // 遥信状态值,默认为0 + pstInfo->uiInfoAddr = p_st_info->inf; + pstInfo->ucStateType = 0; /*遥信单双点属性*/ -// // usDYxStartPos = &g_stYxInform.stYxSoft.stYxDouble.astDoubleYx[0] - (stYX_STATE*)&g_stYxInform; //计算双点遥信起始下标号 -// p_iec = iec60870_get_by_interface(uiItfs); /*获取规约实体*/ + // usDYxStartPos = &g_stYxInform.stYxSoft.stYxDouble.astDoubleYx[0] - (stYX_STATE*)&g_stYxInform; //计算双点遥信起始下标号 + p_iec = iec60870_get_by_interface(uiItfs); /*获取规约实体*/ -// if(p_iec->cs10x.usYxType) //104规约-遥信传输类型为双点 -// { -// pstInfo->ucStateType = 1; //双点遥信 -// // if((usTabIdx < usDYxStartPos || usTabIdx >= (usDYxStartPos+DOUBLEYX_NUM))) /*单点遥信处理*/ -// // { -// // pstInfo->ucStatus += 1; -// // } -// if(p_st_info->invert) /*遥信取反*/ -// { -// if(pstInfo->ucStatus == 2) -// { -// pstInfo->ucStatus = 1; -// } -// else if(pstInfo->ucStatus == 1) -// { -// pstInfo->ucStatus = 2; -// } -// } -// } -// else //104规约-遥信传输类型为单点 -// { -// // if((usTabIdx >= usDYxStartPos && usTabIdx < (usDYxStartPos+DOUBLEYX_NUM))) /*双点遥信 */ -// // { -// // pstInfo->ucStateType = 1; -// // if(stYxTable.ucAttr) /*遥信取反*/ -// // { -// // if(pstInfo->ucStatus == 2) -// // { -// // pstInfo->ucStatus = 1; -// // } -// // else if(pstInfo->ucStatus == 1) -// // { -// // pstInfo->ucStatus = 2; -// // } -// // } -// // } -// // else //单点遥信 -// { -// pstInfo->ucStateType = 0; -// if(p_st_info->invert) /*遥信取反*/ -// { -// if(pstInfo->ucStatus) -// { -// pstInfo->ucStatus = 0; -// } -// else -// { -// pstInfo->ucStatus = 1; -// } -// } -// } -// } -// return 1; -// } + if(p_iec->cs10x.usYxType) //104规约-遥信传输类型为双点 + { + pstInfo->ucStateType = 1; //双点遥信 +// if((usTabIdx < usDYxStartPos || usTabIdx >= (usDYxStartPos+DOUBLEYX_NUM))) /*单点遥信处理*/ +// { +// pstInfo->ucStatus += 1; +// } + if(p_st_info->invert) /*遥信取反*/ + { + if(pstInfo->ucStatus == 2) + { + pstInfo->ucStatus = 1; + } + else if(pstInfo->ucStatus == 1) + { + pstInfo->ucStatus = 2; + } + } + } + else //104规约-遥信传输类型为单点 + { +// if((usTabIdx >= usDYxStartPos && usTabIdx < (usDYxStartPos+DOUBLEYX_NUM))) /*双点遥信 */ +// { +// pstInfo->ucStateType = 1; +// if(stYxTable.ucAttr) /*遥信取反*/ +// { +// if(pstInfo->ucStatus == 2) +// { +// pstInfo->ucStatus = 1; +// } +// else if(pstInfo->ucStatus == 1) +// { +// pstInfo->ucStatus = 2; +// } +// } +// } +// else //单点遥信 + { + pstInfo->ucStateType = 0; + if(p_st_info->invert) /*遥信取反*/ + { + if(pstInfo->ucStatus) + { + pstInfo->ucStatus = 0; + } + else + { + pstInfo->ucStatus = 1; + } + } + } + } + return 1; +} -// int UserWriteSoeEvent(uint16_t usIndex, uint8_t ucState, uint32_t uiSeconds, uint16_t usMs) -// { -// // usIndex += YX_START_PORT; -// local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); -// sem_wait(&g_stSoeInform.sem); -// stYX_CHANGE_INFO *p_soe_info = &g_stSoeInform.astSoeInfo[g_stSoeInform.usInptr]; -// p_soe_info->usYxPot = usIndex; -// p_soe_info->ucState = ucState; -// p_soe_info->uiSeconds = uiSeconds; -// p_soe_info->usMs = usMs; -// g_stSoeInform.usInptr++; -// g_stSoeInform.usInptr %= SOE_LEN; -// sem_post(&g_stSoeInform.sem); +int UserWriteSoeEvent(uint16_t usIndex, uint8_t ucState, uint32_t uiSeconds, uint16_t usMs) +{ + usIndex += YX_START_PORT; + local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); + sem_wait(&g_stSoeInform.sem); + stYX_CHANGE_INFO *p_soe_info = &g_stSoeInform.astSoeInfo[g_stSoeInform.usInptr]; + p_soe_info->usYxPot = usIndex; + p_soe_info->ucState = ucState; + p_soe_info->uiSeconds = uiSeconds; + p_soe_info->usMs = usMs; + g_stSoeInform.usInptr++; + g_stSoeInform.usInptr %= SOE_LEN; + sem_post(&g_stSoeInform.sem); -// return 1; -// } + return 1; +} -// /** -// * @brief 数据表中获取SOE突变遥信数据 -// * @param[in] pvParam-设备指针 -// * @param[in] uiPos 取数据的偏移量 -// * @param[out] pstInfo 获取单条SOE信息 -// * @return 失败返回0, 成功返回1 -// */ -// int32_t GetSOE(SOE_Info *pstInfo, void *pvParam, uint32_t uiPos) -// { -// stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stSoeInform.astOutptr); +/** +* @brief 数据表中获取SOE突变遥信数据 +* @param[in] pvParam-设备指针 +* @param[in] uiPos 取数据的偏移量 +* @param[out] pstInfo 获取单条SOE信息 +* @return 失败返回0, 成功返回1 +*/ +int32_t GetSOE(SOE_Info *pstInfo, void *pvParam, uint32_t uiPos) +{ + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stSoeInform.astOutptr); -// local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); -// sem_wait(&g_stSoeInform.sem); -// uint16_t pos = uiPos + pstInfor->usOutNum; -// pos %= SOE_LEN; -// stYX_CHANGE_INFO *p_soe_info = &g_stSoeInform.astSoeInfo[pos]; -// pstInfo->uiInfoAddr = p_soe_info->usYxPot; -// pstInfo->ucStatus = p_soe_info->ucState; -// pstInfo->ucStateType = p_soe_info->ucType; -// StampToCp56(&pstInfo->stCTime, p_soe_info->uiSeconds, p_soe_info->usMs); -// sem_post(&g_stSoeInform.sem); + local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); + sem_wait(&g_stSoeInform.sem); + uint16_t pos = uiPos + pstInfor->usOutNum; + pos %= SOE_LEN; + stYX_CHANGE_INFO *p_soe_info = &g_stSoeInform.astSoeInfo[pos]; + pstInfo->uiInfoAddr = p_soe_info->usYxPot; + pstInfo->ucStatus = p_soe_info->ucState; + pstInfo->ucStateType = p_soe_info->ucType; + StampToCp56(&pstInfo->stCTime, p_soe_info->uiSeconds, p_soe_info->usMs); + sem_post(&g_stSoeInform.sem); -// stru_iec_60870 *p_iec = iec60870_get_by_interface(*(uint32_t*)pvParam); -// if(p_iec->cs10x.usYxType) //104规约-遥信传输类型为双点 -// { -// pstInfo->ucStateType = 1; //双点遥信 -// pstInfo->ucStatus += 1; //双点遥信状态值加1 -// } -// else //104规约-遥信传输类型为单点 -// { -// pstInfo->ucStateType = 0; //单点遥信 -// } + stru_iec_60870 *p_iec = iec60870_get_by_interface(*(uint32_t*)pvParam); + if(p_iec->cs10x.usYxType) //104规约-遥信传输类型为双点 + { + pstInfo->ucStateType = 1; //双点遥信 + pstInfo->ucStatus += 1; //双点遥信状态值加1 + } + else //104规约-遥信传输类型为单点 + { + pstInfo->ucStateType = 0; //单点遥信 + } -// return 1; -// } + return 1; +} -// /** -// * @brief 数据表中获取突变遥信数量接口函数 -// * @param[in] pvArg - 通信接口指针 -// * @param[out] 无 -// * @return -// */ -// int32_t GetSOESendNum(void *pvArg) -// { -// int num = 0; -// stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stSoeInform.astOutptr); +/** +* @brief 数据表中获取突变遥信数量接口函数 +* @param[in] pvArg - 通信接口指针 +* @param[out] 无 +* @return +*/ +int32_t GetSOESendNum(void *pvArg) +{ + int num = 0; + stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stSoeInform.astOutptr); -// local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); -// sem_wait(&g_stSoeInform.sem); + local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); + sem_wait(&g_stSoeInform.sem); -// if(g_stSoeInform.usInptr >= pstInfor->usOutNum) -// { -// num = g_stSoeInform.usInptr - pstInfor->usOutNum; -// } -// else -// { -// num = SOE_LEN - pstInfor->usOutNum + g_stSoeInform.usInptr; -// } + if(g_stSoeInform.usInptr >= pstInfor->usOutNum) + { + num = g_stSoeInform.usInptr - pstInfor->usOutNum; + } + else + { + num = SOE_LEN - pstInfor->usOutNum + g_stSoeInform.usInptr; + } -// sem_post(&g_stSoeInform.sem); + sem_post(&g_stSoeInform.sem); -// return num; -// } + return num; +} -// /** -// * @brief 数据表中更新突变遥信数据出指针接口函数 -// * @param[in] pvParam-设备指针 -// * @param[in] uiPos 取数据的偏移量 表征取出记录个数 -// * @param[out] 无 -// * @return 0-异常 1-正常 -// */ -// int32_t UpdateSoePtrOut(void *pvParam, uint32_t uiPos) -// { -// stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stSoeInform.astOutptr); +/** +* @brief 数据表中更新突变遥信数据出指针接口函数 +* @param[in] pvParam-设备指针 +* @param[in] uiPos 取数据的偏移量 表征取出记录个数 +* @param[out] 无 +* @return 0-异常 1-正常 +*/ +int32_t UpdateSoePtrOut(void *pvParam, uint32_t uiPos) +{ + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stSoeInform.astOutptr); -// local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); -// sem_wait(&g_stSoeInform.sem); -// pstInfor->usOutNum += uiPos; -// pstInfor->usOutNum %= SOE_LEN; -// sem_post(&g_stSoeInform.sem); + local_sem_init(g_stSoeInform.isInit, &g_stSoeInform.sem); + sem_wait(&g_stSoeInform.sem); + pstInfor->usOutNum += uiPos; + pstInfor->usOutNum %= SOE_LEN; + sem_post(&g_stSoeInform.sem); -// return 1; -// } + return 1; +} -// /** -// * @brief 获取电度数据组中的遥测数目 // 数据表中有多少电能量 -// * @param[in] usGroupID-是否带时标 -// * @param[in] pvParam-设备指针 -// * @param[out] puiStartInf-起始信息体地址 -// * @param[out] puiEndInf-结束信息体地址 -// * @param[in] ucTimeEn-时标使能 -// * @return 数量 0-表示该分组未配置数据 -// */ -// int32_t GetDdCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf, uint8_t ucTimeEn) -// { -// stru_app_cfg *p_app_cfg = get_app_cfg_ptr(); -// uint32_t dd_num = p_app_cfg->dd_info_vec.size(); +/** + * @brief 获取电度数据组中的遥测数目 // 数据表中有多少电能量 + * @param[in] usGroupID-是否带时标 + * @param[in] pvParam-设备指针 + * @param[out] puiStartInf-起始信息体地址 + * @param[out] puiEndInf-结束信息体地址 + * @param[in] ucTimeEn-时标使能 + * @return 数量 0-表示该分组未配置数据 + */ +int32_t GetDdCountByGroup(uint16_t usGroupID, void *pvParam, uint32_t *puiStartInf, uint32_t *puiEndInf, uint8_t ucTimeEn) +{ + std::vector &vec_dd = iec_cfg_ptr_get()->vec_dd; + uint32_t dd_num = vec_dd.size(); -// if(0 == usGroupID) //总召 -// { -// if(ucTimeEn) -// { -// return 0; -// } + if(0 == usGroupID) //总召 + { + if(ucTimeEn) + { + return 0; + } -// *puiStartInf = DD_START_PORT; -// *puiEndInf = *puiStartInf + dd_num; + *puiStartInf = DD_START_PORT; + *puiEndInf = *puiStartInf + dd_num; -// return dd_num; -// } + return dd_num; + } -// int usNum = 8; //实时电能量8个 -// if(ucTimeEn) -// { -// *puiStartInf = DD_START_PORT + usNum; -// usNum = dd_num - usNum; -// *puiEndInf = *puiStartInf + usNum; -// return usNum; -// } + int usNum = 8; //实时电能量8个 + if(ucTimeEn) + { + *puiStartInf = DD_START_PORT + usNum; + usNum = dd_num - usNum; + *puiEndInf = *puiStartInf + usNum; + return usNum; + } -// *puiStartInf = DD_START_PORT; -// *puiEndInf = *puiStartInf + usNum; + *puiStartInf = DD_START_PORT; + *puiEndInf = *puiStartInf + usNum; -// return usNum; -// } + return usNum; +} -// int32_t GetDdValueByGroup(uint16_t usGroupID, uint16_t usIdx, TimeDd_Info *pstInfo, void *pvParam, uint8_t ucTimeEn) -// { -// stru_app_cfg *p_app_cfg = get_app_cfg_ptr(); -// uint32_t dd_num = p_app_cfg->dd_info_vec.size(); -// uint16_t usMax = 0; -// uint16_t usMin = 0; -// uint16_t usVaildSublabel = 0; +int32_t GetDdValueByGroup(uint16_t usGroupID, uint16_t usIdx, TimeDd_Info *pstInfo, void *pvParam, uint8_t ucTimeEn) +{ + std::vector &vec_dd = iec_cfg_ptr_get()->vec_dd; + uint32_t dd_num = vec_dd.size(); + uint16_t usMax = 0; + uint16_t usMin = 0; + uint16_t usVaildSublabel = 0; -// if(usIdx >= dd_num) -// { -// return 0; -// } + if(usIdx >= dd_num) + { + return 0; + } -// if(0 == usGroupID) -// { -// if(ucTimeEn) -// { -// return 0; -// } + if(0 == usGroupID) + { + if(ucTimeEn) + { + return 0; + } -// usMax = dd_num; -// usMin = 0; -// } -// else -// { -// if(0 == ucTimeEn) -// { -// usMax = 8; // 实时电能量8个 -// usMin = 0; -// } -// else -// { -// usMax = dd_num; -// usMin = 8; -// } -// } + usMax = dd_num; + usMin = 0; + } + else + { + if(0 == ucTimeEn) + { + usMax = 8; // 实时电能量8个 + usMin = 0; + } + else + { + usMax = dd_num; + usMin = 8; + } + } + return 0; +} + +int UserWriteDisturbDd(uint16_t usIndex, float fVal, uint32_t uiSeconds, uint16_t usMs) +{ + usIndex += DD_START_PORT; + local_sem_init(g_stDdChangeInform.isInit, &g_stDdChangeInform.sem); + sem_wait(&g_stDdChangeInform.sem); + + stDD_RECORD *p_dd_recode = &g_stDdChangeInform.astDd[g_stDdChangeInform.usInptr]; + p_dd_recode->usIndex = usIndex; + p_dd_recode->fDdValue = fVal; + p_dd_recode->usMs = usMs; + p_dd_recode->uiSeconds = uiSeconds; + g_stDdChangeInform.usInptr++; + g_stDdChangeInform.usInptr %= Dd_LEN; + sem_post(&g_stDdChangeInform.sem); + + return 1; +} + +int32_t GetTimeDdu(TimeDd_Info *pstInfo, void *pvParam, uint32_t uiPos) +{ + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stDdChangeInform.astOutptr); + + local_sem_init(g_stDdChangeInform.isInit, &g_stDdChangeInform.sem); + sem_wait(&g_stDdChangeInform.sem); + uint16_t pos = uiPos + pstInfor->usOutNum; + pos %= Dd_LEN; + stDD_RECORD *p_dd_recode = &g_stDdChangeInform.astDd[pos]; + pstInfo->uiInfoAddr = p_dd_recode->usIndex; + pstInfo->fVal = p_dd_recode->fDdValue; + StampToCp56(&pstInfo->stCTime, p_dd_recode->uiSeconds, p_dd_recode->usMs); + sem_post(&g_stDdChangeInform.sem); + + return 1; +} + +int32_t GetTimeDduSendNum(void *pvArg) +{ + int num = 0; + stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stDdChangeInform.astOutptr); + + local_sem_init(g_stDdChangeInform.isInit, &g_stDdChangeInform.sem); + sem_wait(&g_stDdChangeInform.sem); + + if(g_stDdChangeInform.usInptr >= pstInfor->usOutNum) + { + num = g_stDdChangeInform.usInptr - pstInfor->usOutNum; + } + else + { + num = Dd_LEN - pstInfor->usOutNum + g_stDdChangeInform.usInptr; + } + + sem_post(&g_stDdChangeInform.sem); + + return num; +} + +int32_t UpdateTimeDduPtrOut(void *pvParam, uint32_t uiPos) +{ + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stDdChangeInform.astOutptr); + + local_sem_init(g_stDdChangeInform.isInit, &g_stDdChangeInform.sem); + sem_wait(&g_stDdChangeInform.sem); + pstInfor->usOutNum += uiPos; + pstInfor->usOutNum %= Dd_LEN; + sem_post(&g_stDdChangeInform.sem); + + return 1; +} + + +int UserWriteFaultEvent(stSOEInfo *pstInfo, uint8_t ucYxNum, stYcInfo *pstYcInfo, uint8_t ucYcNum) +{ + if(ucYxNum != 1 || ucYcNum > FAULT_YC_NUM_MAIN) + { + LOG_E("ucYxNum %d, ucYcNum %d, max %d", ucYxNum, ucYcNum, FAULT_YC_NUM_MAIN); + return -1; + } + + pstInfo->uiInfoAddr += YX_START_PORT; + StampToCp56(&pstInfo->stCTime, pstInfo->uiSeconds, pstInfo->usMs); + for(uint8_t i = 0; i < ucYcNum; i++) + { + pstYcInfo[i].uiInfoAddr += YC_START_PORT; + } + + local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); + sem_wait(&g_stFaultInformMain.sem); + + stFAULT_EVENT_MAIN *p_fault = &g_stFaultInformMain.astFault[g_stFaultInformMain.usInptr]; + + p_fault->ucYxNum = ucYxNum; + memcpy(&p_fault->stSoe, pstInfo, sizeof(stSOEInfo)); + + p_fault->ucYcNum = ucYcNum; + memcpy(p_fault->astYc, pstYcInfo, sizeof(stYcInfo) * ucYcNum); + + g_stFaultInformMain.usInptr++; + g_stFaultInformMain.usInptr %= FAULT_EVENT_LEN; + + sem_post(&g_stFaultInformMain.sem); + + return 1; +} + +int32_t GetEventSendNum(void *pvArg) +{ + int num = 0; + stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stFaultInformMain.astOutptr); + + local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); + sem_wait(&g_stFaultInformMain.sem); + + num = g_stFaultInformMain.usInptr >= pstInfor->usOutNum \ + ? (g_stFaultInformMain.usInptr - pstInfor->usOutNum) \ + : (FAULT_EVENT_LEN - pstInfor->usOutNum + g_stFaultInformMain.usInptr); + + sem_post(&g_stFaultInformMain.sem); + + return num; +} + +int32_t GetFaultEvent(FAULT_EVENT_Info *pstInfo, void *pvParam, uint32_t uiPos) +{ + stFAULT_EVENT_MAIN stFaultEvenInfo; + + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stFaultInformMain.astOutptr); + + local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); + sem_wait(&g_stFaultInformMain.sem); + + uint16_t pos = uiPos + pstInfor->usOutNum; + pos %= FAULT_EVENT_LEN; + memcpy(&stFaultEvenInfo, &g_stFaultInformMain.astFault[pos], sizeof(stFAULT_EVENT_MAIN)); + + sem_post(&g_stFaultInformMain.sem); + + for(uint8_t i = 0; i < stFaultEvenInfo.ucYxNum; i++) + { + pstInfo->staSoe[i].uiInfoAddr = stFaultEvenInfo.stSoe.uiInfoAddr; + pstInfo->staSoe[i].ucStatus = stFaultEvenInfo.stSoe.ucStatus; + pstInfo->staSoe[i].ucStateType = 0; + StampToCp56(&pstInfo->staSoe[i].stCTime, stFaultEvenInfo.stSoe.uiSeconds, stFaultEvenInfo.stSoe.usMs); -// } + memcpy(&pstInfo->staSoe[i].stCTime, &stFaultEvenInfo.stSoe.stCTime, sizeof(stCP56Time2a)); + } + pstInfo->usSoeNum = stFaultEvenInfo.ucYxNum; + + for(uint8_t i = 0; i < stFaultEvenInfo.ucYcNum; i++) + { + pstInfo->staYc[i].uiInfoAddr = stFaultEvenInfo.astYc[i].uiInfoAddr; + pstInfo->staYc[i].fVal = stFaultEvenInfo.astYc[i].fVal; + } + pstInfo->usYcNum = stFaultEvenInfo.ucYcNum; + + return 1; +} + +int32_t UpdateFaultEventPtrOut(void *pvParam, uint32_t uiPos) +{ + stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stFaultInformMain.astOutptr); + + local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); + sem_wait(&g_stFaultInformMain.sem); + + pstInfor->usOutNum += uiPos; + pstInfor->usOutNum %= FAULT_EVENT_LEN; + + sem_post(&g_stFaultInformMain.sem); + + return 1; +} - - - -// int UserWriteFaultEvent(stFAULT_EVENT_MAIN *pstInfo) -// { -// local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); -// sem_wait(&g_stFaultInformMain.sem); - -// memcpy(&g_stFaultInformMain.astFault[g_stFaultInformMain.usInptr++], pstInfo, sizeof(stFAULT_EVENT_MAIN)); -// g_stFaultInformMain.usInptr %= FAULT_EVENT_LEN; - -// sem_post(&g_stFaultInformMain.sem); - -// return 1; -// } - -// int32_t GetEventSendNum(void *pvArg) -// { -// int num = 0; -// stINFOR_OUT *pstInfor = GetInforOut(pvArg, g_stFaultInformMain.astOutptr); - -// local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); -// sem_wait(&g_stFaultInformMain.sem); - -// num = g_stFaultInformMain.usInptr >= pstInfor->usOutNum \ -// ? (g_stFaultInformMain.usInptr - pstInfor->usOutNum) \ -// : (FAULT_EVENT_LEN - pstInfor->usOutNum + g_stFaultInformMain.usInptr); - -// sem_post(&g_stFaultInformMain.sem); - -// return num; -// } - -// int32_t GetFaultEvent(FAULT_EVENT_Info *pstInfo, void *pvParam, uint32_t uiPos) -// { -// stFAULT_EVENT_MAIN stFaultEvenInfo; - -// stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stFaultInformMain.astOutptr); - -// local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); -// sem_wait(&g_stFaultInformMain.sem); - -// uint16_t pos = uiPos + pstInfor->usOutNum; -// pos %= FAULT_EVENT_LEN; -// memcpy(&stFaultEvenInfo, &g_stFaultInformMain.astFault[pos], sizeof(stFAULT_EVENT_MAIN)); - -// sem_post(&g_stFaultInformMain.sem); - -// for(uint8_t i = 0; i < stFaultEvenInfo.ucYxNum; i++) -// { -// pstInfo->staSoe[i].uiInfoAddr = stFaultEvenInfo.stSoe.uiInfoAddr; -// pstInfo->staSoe[i].ucStatus = stFaultEvenInfo.stSoe.ucStatus; -// pstInfo->staSoe[i].ucStateType = 0; -// StampToCp56(&pstInfo->staSoe[i].stCTime, stFaultEvenInfo.stSoe.uiSeconds, stFaultEvenInfo.stSoe.usMs); - -// memcpy(&pstInfo->staSoe[i].stCTime, &stFaultEvenInfo.stSoe.stCTime, sizeof(stCP56Time2a)); -// } -// pstInfo->usSoeNum = stFaultEvenInfo.ucYxNum; - -// for(uint8_t i = 0; i < stFaultEvenInfo.ucYcNum; i++) -// { -// pstInfo->staYc[i].uiInfoAddr = stFaultEvenInfo.astYc[i].uiInfoAddr; -// pstInfo->staYc[i].fVal = stFaultEvenInfo.astYc[i].fVal; -// } -// pstInfo->usYcNum = stFaultEvenInfo.ucYcNum; - -// return 1; -// } - -// int32_t UpdateFaultEventPtrOut(void *pvParam, uint32_t uiPos) -// { -// stINFOR_OUT *pstInfor = GetInforOut(pvParam, g_stFaultInformMain.astOutptr); - -// local_sem_init(g_stFaultInformMain.isInit, &g_stFaultInformMain.sem); -// sem_wait(&g_stFaultInformMain.sem); - -// pstInfor->usOutNum += uiPos; -// pstInfor->usOutNum %= FAULT_EVENT_LEN; - -// sem_post(&g_stFaultInformMain.sem); - -// return 1; -// } - +uint8_t Cs10xYkVerifyItfs(void *pvParam) +{ + return 1; +} + +uint16_t GbParamGetParamArea(uint8_t ucType, void *pvHandle) +{ + return 0; +} + +uint16_t GbParamSetParamArea(uint16_t usArea, void *pvHandle) +{ + return 1; +} diff --git a/src/system/libiec/src/iec_point.cpp b/src/system/libiec/src/iec_point.cpp new file mode 100644 index 0000000..f164d11 --- /dev/null +++ b/src/system/libiec/src/iec_point.cpp @@ -0,0 +1,243 @@ + +#include +#include "iec_point.h" +#include "iec_method.h" + +#include "myLog.h" +#include "myDatacenter.h" + +LOCAL void iec_signal_st_change(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data) +{ + if(saddr.empty() || NULL == p_data || NULL == p_last_data) + { + LOG_E("iec_signal_st_change: invalid parameter, saddr %s, p_data %p, p_last_data %p", saddr.c_str(), p_data, p_last_data); + return; + } + + std::vector &vec_st = iec_cfg_ptr_get()->vec_st; + for(uint32_t i = 0; i < vec_st.size(); i++) + { + if(vec_st[i].link.compare(saddr) == 0) + { + uint8_t val = *(uint8_t *)p_data; + uint8_t last_val = *(uint8_t *)p_last_data; + if(val != last_val) + { + // UserWriteDisturbYx(i, val); + LOG_I("iec_signal_st_change: saddr %s, data %d, last_data %d", saddr.c_str(), val, last_val); + // *(uint8_t *)p_last_data = val; + } + } + } + +} + +LOCAL void iec_signal_mx_change(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data) +{ + if(saddr.empty() || NULL == p_data || NULL == p_last_data) + { + LOG_E("iec_signal_mx_change: invalid parameter, saddr %s, p_data %p, p_last_data %p", saddr.c_str(), p_data, p_last_data); + return; + } + + std::vector &vec_mx = iec_cfg_ptr_get()->vec_mx; + for(uint32_t i = 0; i < vec_mx.size(); i++) + { + if(vec_mx[i].link.compare(saddr) == 0) + { + float fVal = *(float *)p_data; + float last_fVal = *(float *)p_last_data; + if(fabs(fVal - last_fVal) > 0.1) + { + UserWriteDisturbYc(i, fVal); + // LOG_I("iec_signal_mx_change: saddr %s, data %f, last_data %f", saddr.c_str(), fVal, last_fVal); + // *(float *)p_last_data = fVal; + } + } + } + +} + +LOCAL void iec_signal_dd_change(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data) +{ + if(saddr.empty() || NULL == p_data || NULL == p_last_data) + { + LOG_E("iec_signal_dd_change: invalid parameter, saddr %s, p_data %p, p_last_data %p", saddr.c_str(), p_data, p_last_data); + return; + } + + std::vector &vec_dd = iec_cfg_ptr_get()->vec_dd; + for(uint32_t i = 0; i < vec_dd.size(); i++) + { + if(vec_dd[i].link.compare(saddr) == 0) + { + float fVal = *(float *)p_data; + float last_fVal = *(float *)p_last_data; + if(fabs(fVal - last_fVal) > 0.1) + { + // UserWriteDisturbDd(i, fVal, 0, 0); + // LOG_I("iec_signal_dd_change: saddr %s, data %f, last_data %f", saddr.c_str(), fVal, last_fVal); + // *(float *)p_last_data = fVal; + } + } + } +} + + +LOCAL void iec_signal_yk_change(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data) +{ + +} + +LOCAL void iec_signal_ao_change(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data) +{ + +} + +LOCAL void iec_disturb_dd_queue_callback(void *p_data) +{ + if(NULL == p_data) + { + LOG_E("iec_disturb_dd_queue_callback: invalid parameter, p_data %p", p_data); + return; + } + + stru_disturb_dd &dd = *(stru_disturb_dd *)p_data; + LOG_I("iec_disturb_dd_queue_callback: saddr %s, fVal %f, sec %d, ms %d", dd.saddr.c_str(), dd.fVal, dd.sec, dd.ms); + + for(uint32_t i = 0; i < iec_cfg_ptr_get()->vec_dd.size(); i++) + { + if(iec_cfg_ptr_get()->vec_dd[i].link.compare(dd.saddr) == 0) + { + LOG_I("iec_disturb_dd_queue_callback: found saddr %s in vec_dd, set fVal %f", dd.saddr.c_str(), dd.fVal); + UserWriteDisturbDd(i, dd.fVal, dd.sec, dd.ms); + } + } +} + + +LOCAL void iec_event_queue_callback(void *p_data) +{ + if(NULL == p_data) + { + LOG_E("iec_event_queue_callback: invalid parameter, p_data %p", p_data); + return; + } + + stru_dc_soe &soe = *(stru_dc_soe *)p_data; + // LOG_I("iec_event_queue_callback: saddr %s, status %d, sec %d, ums %d", soe.saddr.c_str(), soe.status, soe.sec, soe.ums); + + for(uint32_t i = 0; i < iec_cfg_ptr_get()->vec_st.size(); i++) + { + if(iec_cfg_ptr_get()->vec_st[i].link.compare(soe.saddr) == 0) + { + LOG_I("iec_event_queue_callback: found saddr %s in vec_st, set status %d, sec %d, ums %d", + soe.saddr.c_str(), soe.status, soe.sec, soe.ums); + UserWriteSoeEvent(i, soe.status, soe.sec, soe.ums); + } + } + +} + +LOCAL void iec_fault_queue_callback(void *p_data) +{ + if(NULL == p_data) + { + LOG_E("iec_fault_queue_callback: invalid parameter, p_data %p", p_data); + return; + } + + stru_dc_fault &fault = *(stru_dc_fault *)p_data; + + if(fault.vec_soe.size() != 1 || fault.vec_disturb_yc.size() == 0) + { + LOG_E("iec_fault_queue_callback: invalid parameter, fault %p", p_data); + return; + } + + std::vector &vec_st = iec_cfg_ptr_get()->vec_st; + std::vector &vec_mx = iec_cfg_ptr_get()->vec_mx; + + uint8_t ucYxNum = 1; + stSOEInfo soe_info = {0}; + for(uint32_t i = 0; i < vec_st.size(); i++) + { + if(vec_st[i].link.compare(fault.vec_soe[0].saddr) == 0) + { + soe_info.uiInfoAddr = i; + soe_info.ucStatus = fault.vec_soe[0].status; + soe_info.uiSeconds = fault.vec_soe[0].sec; + soe_info.usMs = fault.vec_soe[0].ums; + break; + } + } + + uint8_t ucYcNum = fault.vec_disturb_yc.size(); + std::vector vec_yc_info(ucYcNum); + + uint8_t j = 0; + for(uint32_t i = 0; i < vec_yc_info.size(); i++) + { + if(vec_mx[i].link.compare(fault.vec_disturb_yc[i].saddr) == 0) + { + vec_yc_info[j].uiInfoAddr = i; + vec_yc_info[j].fVal = fault.vec_disturb_yc[i].fVal; + j++; + } + } + + UserWriteFaultEvent(&soe_info, ucYxNum, vec_yc_info.data(), ucYcNum); +} + +int iec_point_init() +{ + if(0 != dc_event_register_queue_pop(iec_event_queue_callback)) + { + MY_LOG_E("dc_event_register_queue_pop failed"); + return -1; + } + + stru_iec_cfg *p_iec_cfg = iec_cfg_ptr_get(); + if(NULL == p_iec_cfg) + { + MY_LOG_E("iec_cfg_ptr_get return NULL"); + return -1; + } + + std::vector *p_vec = nullptr; + + std::vector *> vec_st_mx_dd = {&p_iec_cfg->vec_st, &p_iec_cfg->vec_mx, &p_iec_cfg->vec_dd}; + std::vector vec_out_change_cb_list = {iec_signal_st_change, iec_signal_mx_change, iec_signal_dd_change}; + for(uint32_t i = 0; i < vec_st_mx_dd.size(); i++) + { + p_vec = vec_st_mx_dd[i]; + for(uint32_t j = 0; j < p_vec->size(); j++) + { + if(0 != dc_signal_out_link_with_callback(p_vec->at(j).link, &p_vec->at(j).p_data, vec_out_change_cb_list[i])) + { + MY_LOG_E("dc_signal_out_link_with_callback failed, link %s", p_vec->at(j).link.c_str()); + return -1; + } + } + } + + for(uint32_t i = 0; i < p_iec_cfg->vec_co.size(); i++) + { + if(0 != dc_signal_yk_link_with_callback(p_iec_cfg->vec_co[i].link, &p_iec_cfg->vec_co[i].p_data, iec_signal_yk_change)) + { + MY_LOG_E("dc_signal_yk_link failed, link %s", p_iec_cfg->vec_co[i].link.c_str()); + return -1; + } + } + + for(uint32_t i = 0; i < p_iec_cfg->vec_ao.size(); i++) + { + if(0 != dc_signal_ao_link_with_callback(p_iec_cfg->vec_ao[i].link, &p_iec_cfg->vec_ao[i].p_data, iec_signal_ao_change)) + { + MY_LOG_E("dc_signal_ao_link failed, link %s, type %d", p_iec_cfg->vec_ao[i].link.c_str(), p_iec_cfg->vec_ao[i].type); + return -1; + } + } + + return 0; +} \ No newline at end of file diff --git a/src/system/libiec61850m/src/iec61850m.cpp b/src/system/libiec61850m/src/iec61850m.cpp index 542685d..5c1d5f0 100644 --- a/src/system/libiec61850m/src/iec61850m.cpp +++ b/src/system/libiec61850m/src/iec61850m.cpp @@ -2,6 +2,7 @@ #include "myLog.h" #include "myCmd.h" #include "iec61850_client.h" +#include "myDatacenter.h" LOCAL void mms_event_back(void *arg, int ret); diff --git a/src/system/libiec61850s/src/iec61850s.cpp b/src/system/libiec61850s/src/iec61850s.cpp index e1ceb2e..cd20aae 100644 --- a/src/system/libiec61850s/src/iec61850s.cpp +++ b/src/system/libiec61850s/src/iec61850s.cpp @@ -2,7 +2,7 @@ #include "iec61850s.h" #include "myLog.h" #include "myCmd.h" - +#include "myDatacenter.h" LOCAL std::vector vec_control = { diff --git a/src/system/libself_ptl/inc/method.h b/src/system/libself_ptl/inc/method.h index ce0bede..adde0cf 100644 --- a/src/system/libself_ptl/inc/method.h +++ b/src/system/libself_ptl/inc/method.h @@ -5,6 +5,62 @@ #include "myIcp67.h" #include "self_ptl.h" +#define YX_START_PORT 0x01 //遥信起始位置 +#define YC_START_PORT 0x4001 //遥测起始位置 +#define DD_START_PORT 0x6401 //电度起始位置 + +typedef struct +{ + uint8_t type; // 数据类型 + uint8_t len; // 数据长度 + uint8_t val[64]; // 数据 +}stru_tlv; + +typedef struct +{ + char name[256]; + uint8_t len; + uint32_t attr; + uint32_t size; +}stru_dir_info; + +typedef struct +{ + uint16_t rx_cnt; + uint16_t tx_cnt; + uint16_t per_cnt; + uint16_t offset; +}stru_local_ao_get; + +typedef struct +{ + uint8_t info_addr; +}stru_local_iec_info_get; + +typedef struct +{ + uint8_t sub_cmd; + std::string temp_str; + std::string dir_name; + std::string file_name; +}stru_local_file; + +typedef struct +{ + uint8_t zip_type; + std::string zip_name; + uint8_t file_num; + stru_zip_file_info file_info[2]; +}stru_local_zip_info; + +typedef struct +{ + uint32_t offset; + uint32_t size; +}stru_local_zip_file_info; + + + void ao_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data); void iec_point_tbl_pop_out(stru_icp67 *p_icp67, uint16_t info_addr, uint16_t num, uint8_t *p_data); void self_check_pop_out(stru_icp67 *p_icp67, stru_data_info *p_data, uint16_t addr); diff --git a/src/system/libself_ptl/inc/self_ptl.h b/src/system/libself_ptl/inc/self_ptl.h index a125069..1ab1d59 100644 --- a/src/system/libself_ptl/inc/self_ptl.h +++ b/src/system/libself_ptl/inc/self_ptl.h @@ -2,6 +2,7 @@ #include "myBase.h" #include "mySystem.h" +#include "myDatacenter.h" #define IEC_START 0x68 #define IEC_TAIL 0x16 diff --git a/src/system/libself_ptl/src/method.cpp b/src/system/libself_ptl/src/method.cpp index 215349f..979e6b0 100644 --- a/src/system/libself_ptl/src/method.cpp +++ b/src/system/libself_ptl/src/method.cpp @@ -15,22 +15,11 @@ #include #include -typedef struct -{ - uint8_t type; // 数据类型 - uint8_t len; // 数据长度 - uint8_t val[64]; // 数据 -}stru_tlv; +#include "myDatacenter.h" -typedef struct -{ - char name[256]; - uint8_t len; - uint32_t attr; - uint32_t size; -}stru_dir_info; -std::vector g_dir_info_vec; + +LOCAL std::vector g_dir_info_vec; LOCAL std::string g_file_path = "/mnt/RTU/test/file/"; LOCAL std::string g_down_path = "DOWN"; @@ -40,54 +29,30 @@ LOCAL std::string g_zip_path = "/mnt/RTU/test/zip/"; LOCAL std::string g_file_name = ""; LOCAL std::string g_zip_name = ""; -MD5_CTX file_md5_ctx; -typedef struct -{ - uint16_t rx_cnt; - uint16_t tx_cnt; - uint16_t per_cnt; - uint16_t offset; -}stru_local_ao_get; +// 文件md5上下文 +LOCAL MD5_CTX file_md5_ctx; + +// 参数读取结构体 LOCAL stru_local_ao_get g_local_ao_get; -typedef struct -{ - uint8_t info_addr; -}stru_local_iec_info_get; -stru_local_iec_info_get g_local_iec_info_get; +// iec点表信息获取结构体 +LOCAL stru_local_iec_info_get g_local_iec_info_get; -typedef struct -{ - uint8_t sub_cmd; - std::string temp_str; - std::string dir_name; - std::string file_name; -}stru_local_file; +// 文件相关结构体 LOCAL stru_local_file g_local_file; +// 自定义命令标志位 LOCAL uint8_t g_flag[256] = {0}; -typedef struct -{ - uint8_t zip_type; - std::string zip_name; - uint8_t file_num; - stru_zip_file_info file_info[2]; -}stru_local_zip_info; +// zip文件名相关结构体 +LOCAL stru_local_zip_info g_zip_info; -stru_local_zip_info g_zip_info; - -typedef struct -{ - uint32_t offset; - uint32_t size; -}stru_local_zip_file_info; - -stru_local_zip_file_info g_zip_file_info; +// zip文件内容相关结构体 +LOCAL stru_local_zip_file_info g_zip_file_info; typedef void (*iec_point_tbl_decode)(std::vector &tlv_vec); @@ -115,7 +80,7 @@ LOCAL void test_file(stru_icp67 *p_icp67, stru_genneral_method *p_method); -std::map g_map_iec_point_tbl_decode = +LOCAL std::map g_map_iec_point_tbl_decode = { {MX_INFO_ADDR, iec_point_tbl_decode_mx}, {ST_INFO_ADDR, iec_point_tbl_decode_st}, @@ -128,7 +93,7 @@ std::map g_map_iec_point_tbl_decode = }; typedef void (* local_test)(stru_icp67 *p_icp67, stru_genneral_method *p_method); -std::map g_map_local_test = +LOCAL std::map g_map_local_test = { {1, test_ao_get}, {3, test_iec_point_tbl_get}, @@ -152,14 +117,11 @@ void ao_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, u uint16_t pos = g_local_ao_get.offset + g_local_ao_get.rx_cnt; stru_self_ptl_cfg_param_data *p_ao_data = &p_app_cfg_data->ao_vec[pos]; - - if(p_ao_data->p_param->base.inf == addr && p_ao_data->p_param->type == type && dc_get_data_type_len(type) == len) { // dc_signal_param_set_val(p_ao_data->p_param->base.saddr, SIGNAL_CTRL_STEP::SELECT, type, p_data); // dc_signal_param_set_val(p_ao_data->p_param->base.saddr, SIGNAL_CTRL_STEP::DIRECT, type, p_data); - if(0 != dc_signal_ao_set_val_without_check(p_ao_data->p_param->base.saddr, type, (void *)p_data)) { LOG_E("dc_signal_ao_set_val_without_check failed,saddr %s, desc %s, inf %d, type %d", @@ -167,7 +129,6 @@ void ao_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, u } } - g_local_ao_get.rx_cnt++; if(g_local_ao_get.rx_cnt == g_local_ao_get.tx_cnt) { @@ -496,15 +457,10 @@ void mx_trans(stru_icp67 *p_icp67, uint16_t info_addr, float p_data) if(info_addr < p_app_cfg_data->mx_vec.size()) { - *(float *)(p_app_cfg_data->mx_vec[info_addr].p_data) = p_data; + // *(float *)(p_app_cfg_data->mx_vec[info_addr].p_data) = p_data; + + dc_set_out_signal_val(p_app_cfg_data->mx_vec[info_addr].p_base->saddr, &p_data); - // float last = *(float *)(p_app_cfg_data->mx_vec[info_addr].p_last_data); - // if(fabs(last - p_data) > 0.1) - // { - // // UserWriteDisturbYc(info_addr, p_data); - // // LOG_I("mx_trans: addr %d, data %f, old_data %f", info_addr, p_data, p_cfg->mx_info_vec[info_addr].old_data); - // } - // *(float *)(p_app_cfg_data->mx_vec[info_addr].p_last_data) = p_data; } } @@ -522,7 +478,9 @@ void st_trans(stru_icp67 *p_icp67, uint16_t info_addr, uint8_t p_data) { - *(uint8_t *)(p_app_cfg_data->st_vec[info_addr].p_data) = p_data; + // *(uint8_t *)(p_app_cfg_data->st_vec[info_addr].p_data) = p_data; + + dc_set_out_signal_val(p_app_cfg_data->st_vec[info_addr].p_base->saddr, &p_data); // if(*(uint8_t *)(p_app_cfg_data->st_vec[info_addr].p_last_data) != p_data) // { @@ -541,6 +499,13 @@ void dd_trans(stru_icp67 *p_icp67, uint16_t info_addr, float p_data) return; } + stru_self_ptl_cfg_data *p_app_cfg_data = self_ptl_cfg_data_ptr_get(); + + if(info_addr < p_app_cfg_data->dd_vec.size()) + { + + dc_set_out_signal_val(p_app_cfg_data->dd_vec[info_addr].p_base->saddr, &p_data); + } LOG_I("dd_trans: info_addr %d, p_data %f", info_addr, p_data); } @@ -564,6 +529,16 @@ void soe_trans(stru_icp67 *p_icp67, stru_st_info *p_data) status = 0; } + uint16_t addr = p_data->addr - YX_START_PORT; + stru_self_ptl_cfg_data *p_app_cfg_data = self_ptl_cfg_data_ptr_get(); + + if(addr < p_app_cfg_data->st_vec.size()) + { + // dc_set_out_signal_val(p_app_cfg_data->st_vec[p_data->addr].p_base->saddr, &status); + std::string saddr = p_app_cfg_data->st_vec[addr].p_base->saddr; + dc_event_queue_push({saddr, status, p_data->tm.t2, p_data->tm.t1}); + } + // UserWriteSoeEvent(p_data->addr, status, p_data->tm.t2, p_data->tm.t1); } @@ -575,13 +550,34 @@ void fault_trans(stru_icp67 *p_icp67, uint16_t num, stru_fault_info *p_data) return; } + stru_self_ptl_cfg_data *p_app_cfg_data = self_ptl_cfg_data_ptr_get(); + + uint16_t addr = 0; LOG_I("fault_trans: num %d", num); for(uint16_t i = 0; i < num; i++) - { + { + stru_dc_fault fault_event; + LOG_I("st num %d", p_data[i].st_num); stru_st_info *p_st = p_data[i].p_st_info; for(uint16_t j = 0; p_st && j < p_data[i].st_num; j++) { + addr = p_st[j].addr - YX_START_PORT; + if(addr < p_app_cfg_data->st_vec.size()) + { + std::string saddr = p_app_cfg_data->st_vec[addr].p_base->saddr; + uint8_t status = 0; + if(p_st[j].status == 1 || p_st[j].status == 2) + { + status = p_st[j].status - 1; + } + else + { + status = 0; + } + + fault_event.vec_soe.push_back({saddr, status, p_st[j].tm.t2, p_st[j].tm.t1}); + } LOG_I("addr %d:%04x, status %d, attr %d, t1 %d, t2 %d", p_st[j].addr, p_st[j].addr, p_st[j].status, p_st[j].attr, p_st[j].tm.t1, p_st[j].tm.t2); } @@ -589,9 +585,18 @@ void fault_trans(stru_icp67 *p_icp67, uint16_t num, stru_fault_info *p_data) stru_mx_info *p_mx = p_data[i].p_mx_info; for(uint16_t j = 0; p_mx && j < p_data[i].mx_num; j++) { + addr = p_mx[j].addr - YC_START_PORT; + if(addr < p_app_cfg_data->mx_vec.size()) + { + std::string saddr = p_app_cfg_data->mx_vec[addr].p_base->saddr; + fault_event.vec_disturb_yc.push_back({saddr, *(float *)&p_mx[j].data}); + } + LOG_I("addr %d:%04x, data %f", p_mx[j].addr, p_mx[j].addr, p_mx[j].data); } + dc_fault_queue_push(fault_event); + // stFAULT_EVENT_MAIN stFaultEvent; // stFaultEvent.ucYxNum = 1; // stFaultEvent.stSoe.uiInfoAddr = p_st[0].addr; @@ -621,6 +626,13 @@ void mx_change(stru_icp67 *p_icp67, stru_mx_info *p_data) } LOG_I("mx_change: addr %d, data %f", p_data->addr, p_data->data); + + stru_self_ptl_cfg_data *p_app_cfg_data = self_ptl_cfg_data_ptr_get(); + uint16_t addr = p_data->addr - YC_START_PORT; + if(addr < p_app_cfg_data->mx_vec.size()) + { + dc_set_out_signal_val(p_app_cfg_data->mx_vec[addr].p_base->saddr, &p_data->data); + } } diff --git a/src/system/libself_ptl/src/self_ptl.cpp b/src/system/libself_ptl/src/self_ptl.cpp index 7f79a14..3edf4ae 100644 --- a/src/system/libself_ptl/src/self_ptl.cpp +++ b/src/system/libself_ptl/src/self_ptl.cpp @@ -3,6 +3,7 @@ #include "myIcp67.h" #include "method.h" #include "self_ptl.h" +#include "myDatacenter.h" typedef struct { diff --git a/src/system/libweb_server/src/ws_method.cpp b/src/system/libweb_server/src/ws_method.cpp index 824ff70..598394c 100644 --- a/src/system/libweb_server/src/ws_method.cpp +++ b/src/system/libweb_server/src/ws_method.cpp @@ -2,6 +2,7 @@ #include "myLog.h" #include "cJSON.h" #include "mySystem.h" +#include "myDatacenter.h" typedef struct { diff --git a/test/config/iec1014.xml b/test/config/iec1014.xml index 70585e1..8a304bc 100644 --- a/test/config/iec1014.xml +++ b/test/config/iec1014.xml @@ -1,40 +1,40 @@ - - - - + + + + - - - - - + + + + + - +
- - - - - - - - - - + + + + + + + + + + - - + + - - + +