<修改>1、调整数据中心,优化数据存储内存的表;

2、修改定值初始化的程序,修复了重启后定值表中的定值恢复到配置文件中的默认值;
3、调整mms客户端的配置文件,mms的信号路径必须到最下层。
4、调整mms客户端库,定值和参数的类型由获取到的类型为准
This commit is contained in:
ypc 2026-05-30 14:13:49 +08:00
parent 4bd6f53d09
commit 0fa7b70001
7 changed files with 182 additions and 222 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ release/arm/
src/system/uart_trans/
src/system/FTU_cfg_parse/
libiec61850-1.5.3/
doc/

View File

@ -104,7 +104,7 @@ static void mms_m_put_value(stru_mms_m_obj &obj, stru_mms_m_out_value &out_value
}
}
static void mms_m_show_MmsValue(MmsValue* mms_value)
static void mms_m_show_MmsValue(MmsValue* mms_value, uint8_t *p_out_mms_type)
{
if(NULL == mms_value)
{
@ -118,10 +118,17 @@ static void mms_m_show_MmsValue(MmsValue* mms_value)
float fVal;
MmsType mmsType = MmsValue_getType(mms_value);
LOG_I("show_mms_value mmsType %d", mmsType);
if(NULL != p_out_mms_type)
{
*p_out_mms_type = mmsType;
}
switch(mmsType)
{
case MMS_STRUCTURE:
return mms_m_show_MmsValue(MmsValue_getElement(mms_value, 0));
return mms_m_show_MmsValue(MmsValue_getElement(mms_value, 0), p_out_mms_type);
break;
case MMS_BOOLEAN:
bVal = MmsValue_getBoolean(mms_value);
@ -144,6 +151,7 @@ static void mms_m_show_MmsValue(MmsValue* mms_value)
LOG_I("show_mms_value fVal: %f\n", fVal);
break;
case MMS_STRING:
case MMS_VISIBLE_STRING:
strVal= (char *)MmsValue_toString(mms_value);
LOG_I("show_mms_value strVal %s\r\n", strVal);
break;
@ -213,7 +221,7 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event
{
if(item.type != event.value_type)
{
LOG_E("value type not match");
LOG_E("value type not match, item.type = %d, event.value_type = %d", item.type, event.value_type);
return -1;
}
@ -239,6 +247,9 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event
case MMS_STRING:
item.set_value = MmsValue_newMmsString((char *)event.val);
break;
case MMS_VISIBLE_STRING:
item.set_value = MmsValue_newVisibleString((char *)event.val);
break;
default:
LOG_E("value type not support");
return -1;
@ -264,6 +275,9 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event
case MMS_STRING:
MmsValue_setMmsString(item.set_value, (char *)event.val);
break;
case MMS_VISIBLE_STRING:
MmsValue_setVisibleString(item.set_value, (char *)event.val);
break;
default:
LOG_E("value type not support");
return -1;
@ -304,7 +318,7 @@ static int mms_m_send_ao_write(stru_mms_m_obj &obj, stru_mms_m_event &event)
{
// if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag)
{
mms_m_show_MmsValue(p_value);
mms_m_show_MmsValue(p_value, &p_item->type);
}
}
else
@ -364,7 +378,7 @@ static int mms_m_send_param_write(stru_mms_m_obj &obj, stru_mms_m_event &event)
{
if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag)
{
mms_m_show_MmsValue(p_value);
mms_m_show_MmsValue(p_value, &p_item->type);
}
}
else
@ -457,7 +471,7 @@ static void mms_m_send_read_ao(stru_mms_m_obj &obj, stru_mms_m_event &event)
if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag)
{
mms_m_show_MmsValue(p_value);
mms_m_show_MmsValue(p_value, &p_item->type);
}
void *p_val = event.set_zone >= p_item->value.vec_p_val.size() ? NULL : p_item->value.vec_p_val[event.set_zone];
@ -551,7 +565,7 @@ static int mms_m_send_co_select(stru_mms_m_obj &obj, stru_point_item &item)
if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag)
{
mms_m_show_MmsValue(item.set_value);
mms_m_show_MmsValue(item.set_value, &item.type);
}
if (ControlObjectClient_selectWithValue(item.control, item.set_value))
@ -758,7 +772,7 @@ static void mms_m_send_call_all(stru_mms_m_obj &obj)
if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag)
{
mms_m_show_MmsValue(p_value);
mms_m_show_MmsValue(p_value, &it->type);
}
if(0 != mms_m_get_mmsValue(p_value, it->type, it->value.vec_p_val[0]))

View File

@ -412,7 +412,10 @@ LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value)
Dbpos_toMmsValue(da->mmsValue, pos);
LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, (char *)value, pos);
if(mms_s_dbg_get())
{
LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, (char *)value, pos);
}
}
/**

View File

@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
typedef struct stru_signal
@ -21,7 +22,7 @@ typedef struct stru_signal
void *p_last_data; // 上一次数据指针
std::vector<void *> vec_p_default_data; // 默认值指针列表(支持多条目)
std::vector<std::string> link_saddrs;
// stru_signal_ctrl ctrl; // 信号扩展信息
std::unordered_set<std::string> link_set; // O(1) 查重
uint8_t ctrl_type; // 信号控制类型
stru_signal_param param; // 信号参数信息
std::vector<out_signal_change_cb> out_change_cb_list; // 输出类型信号变化回调函数列表

View File

@ -3,7 +3,7 @@
#include <tuple>
#include <map>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include "dc_signal.h"
#include "dc_param.h"
@ -36,7 +36,7 @@ struct XXH128Equal {
}
};
typedef std::unordered_map<XXH128_hash_t, stru_signal, XXH128Hash, XXH128Equal> hash_signal_map;
typedef std::unordered_multimap<XXH128_hash_t, stru_signal, XXH128Hash, XXH128Equal> hash_signal_map;
typedef struct
@ -44,9 +44,7 @@ typedef struct
std::mutex mtx;
uint32_t signal_id;
hash_signal_map map_signals;
std::unordered_map<XXH128_hash_t, std::vector<stru_signal*>, XXH128Hash, XXH128Equal> hash_conflict_table;
std::unordered_map<XXH128_hash_t, std::string, XXH128Hash, XXH128Equal> hash_index;
std::unordered_map<XXH128_hash_t, std::vector<std::string>, XXH128Hash, XXH128Equal> hash_conflicts;
std::vector<stru_signal*> id_index; // ID→指针 O(1) 索引
}stru_signal_map;
@ -65,11 +63,22 @@ static stru_datacenter g_datacenter = {};
LOCAL bool g_param_cfg_change = false;
LOCAL std::mutex g_param_cfg_change_mutex;
// 脏信号队列:记录值发生变化的 out 信号,用于增量变化检测
static std::vector<stru_signal*> g_dirty_out_signals;
static std::mutex g_dirty_out_mutex;
static void dc_mark_signal_dirty(stru_signal *p_signal)
{
if (p_signal == nullptr) return;
std::lock_guard<std::mutex> lock(g_dirty_out_mutex);
g_dirty_out_signals.push_back(p_signal);
}
LOCAL int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2);
LOCAL int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data);
LOCAL stru_signal* dc_find_signal(const XXH128_hash_t &hash, stru_signal_map &dc_signal_map);
LOCAL stru_signal* dc_find_signal(const std::string &saddr, stru_signal_map &dc_signal_map);
LOCAL int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map);
LOCAL stru_signal* dc_find_out_signal(const std::string &saddr);
LOCAL stru_signal* dc_find_in_signal(const std::string &saddr);
@ -153,7 +162,7 @@ int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &
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)
{
stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_ao);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao);
if(p_signal == nullptr)
{
MY_LOG_E("saddr %s not found", saddr.c_str());
@ -202,7 +211,7 @@ int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &
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<void *> *p_vec_p_data, std::vector<void *> *p_vec_p_default_data)
{
stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_param);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param);
if(p_signal == nullptr)
{
MY_LOG_E("saddr %s not found", saddr.c_str());
@ -251,7 +260,7 @@ int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_
int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, void **p_data)
{
stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_yk);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk);
if(p_signal == nullptr)
{
MY_LOG_E("saddr %s not found", saddr.c_str());
@ -271,19 +280,33 @@ int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &
void dc_signal_out_change_check()
{
for(auto it = g_datacenter.signal_out.map_signals.begin(); it != g_datacenter.signal_out.map_signals.end(); it++)
std::vector<stru_signal*> dirty;
{
stru_signal *p_signal = &it->second;
if(!p_signal->out_change_cb_list.empty() && nullptr != p_signal->vec_p_data[0] && nullptr != p_signal->p_last_data)
{
if(0 != dc_data_compare(p_signal->data_type, p_signal->vec_p_data[0], p_signal->p_last_data))
{
for(auto cb : p_signal->out_change_cb_list)
{
cb(p_signal->saddr, p_signal->data_type, p_signal->vec_p_data[0], p_signal->p_last_data);
}
std::lock_guard<std::mutex> lock(g_dirty_out_mutex);
dirty.swap(g_dirty_out_signals);
}
dc_set_signal_val(p_signal->p_last_data, p_signal->data_type, p_signal->vec_p_data[0]);
if (dirty.empty()) return;
// 去重:同一信号可能多次写入
std::sort(dirty.begin(), dirty.end());
auto last = std::unique(dirty.begin(), dirty.end());
for (auto it = dirty.begin(); it != last; ++it) {
stru_signal *p_signal = *it;
if (!p_signal->out_change_cb_list.empty() &&
nullptr != p_signal->vec_p_data[0] &&
nullptr != p_signal->p_last_data)
{
if (0 != dc_data_compare(p_signal->data_type,
p_signal->vec_p_data[0], p_signal->p_last_data))
{
for (auto cb : p_signal->out_change_cb_list) {
cb(p_signal->saddr, p_signal->data_type,
p_signal->vec_p_data[0], p_signal->p_last_data);
}
dc_set_signal_val(p_signal->p_last_data,
p_signal->data_type, p_signal->vec_p_data[0]);
}
}
}
@ -347,11 +370,11 @@ LOCAL int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2)
return -1;
}
LOCAL bool dc_signal_ao_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param &param, uint8_t ctrl_type, void *p_data, void *p_default_data)
LOCAL bool dc_signal_ao_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param &param, uint8_t ctrl_type, void *p_default_data)
{
if(p_signal == nullptr || p_data == nullptr || p_default_data == nullptr)
if(p_signal == nullptr || p_default_data == nullptr)
{
LOG_E("p_signal, p_data or p_default_data is nullptr");
LOG_E("p_signal or p_default_data is nullptr");
return false;
}
@ -389,7 +412,7 @@ LOCAL bool dc_signal_ao_add_check(stru_signal *p_signal, const std::string &desc
return change;
}
LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param &param, uint8_t ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data)
LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param &param, uint8_t ctrl_type, std::vector<void *> &vec_p_default_data)
{
bool change = false;
@ -417,17 +440,9 @@ LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &d
change = true;
}
// for(size_t i = 0; i < vec_p_default_data.size(); i++)
// {
// if(0 != dc_data_compare(p_signal->data_type, vec_p_default_data[i], p_signal->vec_p_default_data[i]))
// {
// change = true;
// }
// }
for(size_t i = 0; i < vec_p_data.size(); i++)
for(size_t i = 0; i < vec_p_default_data.size(); i++)
{
if(0 != dc_data_compare(p_signal->data_type, vec_p_data[i], p_signal->vec_p_data[i]))
if(0 != dc_data_compare(p_signal->data_type, vec_p_default_data[i], p_signal->vec_p_default_data[i]))
{
change = true;
}
@ -839,89 +854,30 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, uint8_t setting_zone,
LOCAL void dc_update_global_index(const stru_signal &signal, stru_signal_map &dc_signal_map)
{
auto it = dc_signal_map.hash_index.find(signal.hash);
if(it != dc_signal_map.hash_index.end())
{
if(it->second != signal.saddr)
{
MY_LOG_E("hash collision: %s -> %s", it->second.c_str(), signal.saddr.c_str());
dc_signal_map.hash_conflicts[signal.hash].push_back(it->second);
dc_signal_map.hash_conflicts[signal.hash].push_back(signal.saddr);
}
}
else
{
dc_signal_map.hash_index.emplace(signal.hash, signal.saddr);
}
}
LOCAL int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map)
{
std::lock_guard<std::mutex> lock(dc_signal_map.mtx);
hash_signal_map &signal_map = dc_signal_map.map_signals;
auto conflict_it = dc_signal_map.hash_conflict_table.find(signal.hash);
if (conflict_it != dc_signal_map.hash_conflict_table.end())
{
for(stru_signal *exist_signal : conflict_it->second)
{
if(exist_signal->saddr == signal.saddr)
{
uint32_t old_id = exist_signal->id;
*exist_signal = signal;
exist_signal->id = old_id;
return 0;
}
}
auto [it, inserted] = signal_map.emplace(signal.hash, signal);
stru_signal *new_sig = &it->second;
new_sig->id = dc_signal_map.signal_id++;
conflict_it->second.push_back(new_sig);
dc_update_global_index(*new_sig, dc_signal_map);
}
else
{
auto map_it = signal_map.find(signal.hash);
if(map_it != signal_map.end())
{
if(map_it->second.saddr != signal.saddr)
{
std::vector<stru_signal*> conficts;
conficts.push_back(&map_it->second);
auto [it, inserted] = signal_map.emplace(signal.hash, signal);
stru_signal *new_sig = &it->second;
new_sig->id = dc_signal_map.signal_id++;
conficts.push_back(new_sig);
dc_signal_map.hash_conflict_table[signal.hash] = conficts;
dc_update_global_index(*new_sig, dc_signal_map);
return 0;
}
else
{
auto old_id = map_it->second.id;
map_it->second = signal;
map_it->second.id = old_id;
return 0;
}
}
else
{
auto [it, inserted] = signal_map.emplace(signal.hash, signal);
stru_signal &new_sig = it->second;
new_sig.id = dc_signal_map.signal_id++;
dc_update_global_index(new_sig, dc_signal_map);
// 先查找是否已有相同 saddr 的信号(更新场景)
auto range = dc_signal_map.map_signals.equal_range(signal.hash);
for (auto it = range.first; it != range.second; ++it) {
if (it->second.saddr == signal.saddr) {
// 已有相同 saddr更新内容保留 id
uint32_t old_id = it->second.id;
it->second = signal;
it->second.id = old_id;
return 0;
}
}
// 新信号,插入 multimap
auto it = dc_signal_map.map_signals.emplace(signal.hash, signal);
it->second.id = dc_signal_map.signal_id++;
if (dc_signal_map.id_index.size() <= it->second.id) {
dc_signal_map.id_index.resize(it->second.id + 1, nullptr);
}
dc_signal_map.id_index[it->second.id] = &it->second;
return 0;
}
@ -1034,18 +990,9 @@ int dc_signal_in(const std::string &saddr, const std::string &desc, const std::s
signal.data_type = p_signal_out->data_type;
signal.vec_p_data.push_back((*p_data));
bool found = false;
for(auto it = p_signal_out->link_saddrs.begin(); it != p_signal_out->link_saddrs.end(); ++it)
{
if(it->compare(saddr) == 0)
{
found = true;
break;
}
}
if(!found)
if(p_signal_out->link_set.find(saddr) == p_signal_out->link_set.end())
{
p_signal_out->link_set.insert(saddr);
p_signal_out->link_saddrs.push_back(saddr);
}
@ -1096,7 +1043,11 @@ int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc
p_signal_out->out_change_cb_list.push_back(cb);
}
p_signal_out->link_saddrs.push_back(saddr);
if(p_signal_out->link_set.find(saddr) == p_signal_out->link_set.end())
{
p_signal_out->link_set.insert(saddr);
p_signal_out->link_saddrs.push_back(saddr);
}
signal.link_saddrs.push_back(link_saddr);
@ -1112,10 +1063,10 @@ int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao);
if(p_signal != nullptr && !p_signal->vec_p_data.empty() && !p_signal->vec_p_default_data.empty() && nullptr != p_signal->vec_p_data[0] && nullptr != p_signal->vec_p_default_data[0])
{
if(true == dc_signal_ao_add_check(p_signal, desc, data_type, param, ctrl_type, p_data, p_default_data))
if(true == dc_signal_ao_add_check(p_signal, desc, data_type, param, ctrl_type, p_default_data))
{
dc_set_param_cfg_change(true);
}
@ -1144,7 +1095,7 @@ int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data
dc_signal_add_to_map(signal, g_datacenter.signal_ao);
p_signal = dc_find_signal(hash, g_datacenter.signal_ao);
p_signal = dc_find_signal(saddr, g_datacenter.signal_ao);
if(p_signal != nullptr )
{
p_signal->vec_p_data.push_back(p_data);
@ -1170,7 +1121,7 @@ int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, sig
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao);
if(p_signal != nullptr)
{
if(cb)
@ -1194,7 +1145,7 @@ int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_s
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao);
if(p_signal != nullptr)
{
if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data))
@ -1260,7 +1211,7 @@ int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_ty
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao);
if(p_signal != nullptr && !p_signal->vec_p_data.empty() && p_signal->data_type == data_type && p_signal->vec_p_data[0])
{
if(p_signal->data_type != data_type)
@ -1305,11 +1256,11 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param);
if(p_signal != nullptr)
{
// dc_set_signal_val(p_data, data_type, p_signal->p_data);
if(true == dc_signal_param_add_check(p_signal, desc, data_type, param, ctrl_type, vec_p_data, vec_p_default_data))
if(true == dc_signal_param_add_check(p_signal, desc, data_type, param, ctrl_type, vec_p_default_data))
{
dc_set_param_cfg_change(true);
}
@ -1354,7 +1305,7 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d
dc_signal_add_to_map(signal, g_datacenter.signal_param);
p_signal = dc_find_signal(hash, g_datacenter.signal_param);
p_signal = dc_find_signal(saddr, g_datacenter.signal_param);
if(p_signal != nullptr )
{
for(size_t i = 0; i < vec_p_data.size(); i++)
@ -1376,7 +1327,7 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d
int dc_signal_param_link_with_callback(const std::string &saddr, std::vector<void *> &vec_p_data, signal_change_cb cb)
{
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param);
if(p_signal != nullptr)
{
// if(p_signal->data_type != data_type)
@ -1411,7 +1362,7 @@ int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, str
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param);
if(p_signal != nullptr)
{
if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data))
@ -1476,7 +1427,7 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param);
if(p_signal != nullptr && setting_zone < p_signal->vec_p_data.size())
{
if(p_signal->data_type != data_type)
@ -1513,7 +1464,7 @@ int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data
dc_signal_add_to_map(signal, g_datacenter.signal_yk);
stru_signal *p_signal = dc_find_signal(signal.hash, g_datacenter.signal_yk);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk);
if(p_signal != nullptr)
{
if(cb)
@ -1538,7 +1489,7 @@ int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, sig
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_yk);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk);
if(p_signal != nullptr)
{
if(cb)
@ -1561,7 +1512,7 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str
}
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_yk);
stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk);
if(p_signal != nullptr)
{
if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data))
@ -1610,35 +1561,29 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str
}
LOCAL stru_signal* dc_find_signal(const XXH128_hash_t &hash, stru_signal_map &dc_signal_map)
LOCAL stru_signal* dc_find_signal(const std::string &saddr, stru_signal_map &dc_signal_map)
{
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
std::lock_guard<std::mutex> lock(dc_signal_map.mtx);
hash_signal_map &signal_map = dc_signal_map.map_signals;
auto map_it = signal_map.find(hash);
if(map_it != signal_map.end())
{
return &map_it->second;
}
else
{
return nullptr;
auto range = dc_signal_map.map_signals.equal_range(hash);
for (auto it = range.first; it != range.second; ++it) {
if (it->second.saddr == saddr) {
return &it->second;
}
}
return nullptr;
}
LOCAL stru_signal* dc_find_out_signal(const std::string &saddr)
{
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
return dc_find_signal(hash, g_datacenter.signal_out);
return dc_find_signal(saddr, g_datacenter.signal_out);
}
LOCAL stru_signal* dc_find_in_signal(const std::string &saddr)
{
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
return dc_find_signal(hash, g_datacenter.signal_in);
return dc_find_signal(saddr, g_datacenter.signal_in);
}
LOCAL std::map<uint8_t, std::string> g_data_type_str = {
@ -1955,6 +1900,7 @@ int dc_set_out_signal_val(const std::string &saddr, void *set_data)
stru_signal *p_signal = dc_find_out_signal(saddr);
if(p_signal != nullptr)
{
dc_mark_signal_dirty(p_signal);
return dc_set_signal_val(p_signal->vec_p_data[0], p_signal->data_type, set_data);
}
@ -2117,13 +2063,8 @@ void dc_delete_signal_data(void *p_data, uint8_t data_type)
LOCAL stru_signal *dc_find_signal_by_id(uint32_t id, stru_signal_map &dc_signal_map)
{
for(auto it = dc_signal_map.map_signals.begin(); it != dc_signal_map.map_signals.end(); ++it)
{
if(it->second.id == id)
{
return &it->second;
}
}
if (id < dc_signal_map.id_index.size())
return dc_signal_map.id_index[id];
return nullptr;
}
@ -2196,7 +2137,7 @@ void dc_param_cfg_check()
{
XMLElement *item_elem = doc.NewElement("Item");
item_elem->SetAttribute("index", i+1);
item_elem->SetAttribute("val", dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type).c_str());
item_elem->SetAttribute("value", dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type).c_str());
item_elem->SetAttribute("default", dc_get_signal_val(p_param->vec_p_default_data[i], p_param->data_type).c_str());
sig_elem->InsertEndChild(item_elem);
@ -2226,27 +2167,46 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map)
hash_signal_map &signal_map = dc_signal_map.map_signals;
// 定义列宽(单位:字符,考虑中英文混合
const int COL_ID = 12;
const int COL_SADDR = 48;
const int COL_DESC = 64;
const int COL_TYPE = 12;
const int COL_VAL = 32;
const int COL_LINK = 64;
// 定义列宽(单位:终端视觉列数中文占2列ASCII占1列
const int COL_ID = 8;
const int COL_SADDR = 36;
const int COL_DESC = 48;
const int COL_TYPE = 10;
const int COL_VAL = 24;
const int COL_LINK = 48;
// 打印表头严格对齐使用left对齐
// 按终端视觉宽度左对齐辅助函数
auto visual_width = [](const std::string &s) -> int {
int w = 0;
for (size_t i = 0; i < s.size();) {
unsigned char c = s[i];
if (c < 0x80) { w += 1; i += 1; }
else if (c < 0xC0) { i += 1; } // 连续字节不计宽
else if (c < 0xE0) { w += 2; i += 2; } // 2字节字符
else if (c < 0xF0) { w += 2; i += 3; } // CJK 3字节
else { w += 2; i += 4; } // 4字节字符
}
return w;
};
auto pad_left = [&](const std::string &s, int width) -> std::string {
int vw = visual_width(s);
int pad = width - vw;
if (pad > 0) return s + std::string(pad, ' ');
return s + ' ';
};
// 打印表头
cout << "\t"
<< left
<< setw(COL_ID) << "id"
<< setw(COL_SADDR) << "saddr"
<< setw(COL_DESC) << "desc"
<< setw(COL_TYPE) << "data_type"
<< setw(COL_VAL) << "val"
<< setw(COL_LINK) << "link_saddrs"
<< pad_left("id", COL_ID)
<< pad_left("saddr", COL_SADDR)
<< pad_left("desc", COL_DESC)
<< pad_left("type", COL_TYPE)
<< pad_left("val", COL_VAL)
<< pad_left("link_saddrs", COL_LINK)
<< endl;
// 打印分隔线(总长度 = 各列宽度之和)
int total_width = COL_SADDR + COL_DESC + COL_TYPE + COL_VAL + COL_LINK;
// 打印分隔线
int total_width = COL_ID + COL_SADDR + COL_DESC + COL_TYPE + COL_VAL + COL_LINK;
cout << "\t" << string(total_width, '-') << endl;
// 遍历信号表
@ -2261,7 +2221,7 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map)
continue;
}
// 1. 先把所有列的内容拼接成字符串,再一次性输出,避免中间打断setw对齐
// 1. 先把所有列的内容拼接成字符串,再一次性输出,避免中间打断对齐
string link_str;
bool first = true;
for (const auto &link : p_signal->link_saddrs)
@ -2271,15 +2231,16 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map)
first = false;
}
// 2. 输出所有列严格使用setw控制宽度
std::string val_str = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type);
// 2. 输出所有列,按视觉宽度对齐
cout << "\t"
<< left
<< setw(COL_ID) << p_signal->id
<< setw(COL_SADDR) << p_signal->saddr
<< setw(COL_DESC) << p_signal->desc
<< setw(COL_TYPE) << dc_get_data_type_str_by_id(p_signal->data_type)
<< setw(COL_VAL) << dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type)
<< setw(COL_LINK) << link_str
<< pad_left(std::to_string(p_signal->id), COL_ID)
<< pad_left(p_signal->saddr, COL_SADDR)
<< pad_left(p_signal->desc, COL_DESC)
<< pad_left(dc_get_data_type_str_by_id(p_signal->data_type), COL_TYPE)
<< pad_left(val_str, COL_VAL)
<< pad_left(link_str, COL_LINK)
<< endl;
}
@ -2287,26 +2248,6 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map)
cout << "signal_id: " << dc_signal_map.signal_id << endl;
cout << "signal count: " << signal_map.size() << endl;
cout << "conflict count: " << dc_signal_map.hash_conflicts.size() << endl;
if(dc_signal_map.hash_conflicts.empty())
{
cout << "no conflict" << endl;
}
else
{
cout << "conflicts: count " << dc_signal_map.hash_conflicts.size() << endl;
for(auto it = dc_signal_map.hash_conflicts.begin(); it != dc_signal_map.hash_conflicts.end(); ++it)
{
const auto &hash = it->first;
const auto &saddrs = it->second;
cout << " hash: " << hash.low64 << "-" << hash.high64 << " num: " << saddrs.size() << endl;
for(auto &saddr : saddrs)
{
cout << " " << saddr.c_str() << endl;
}
}
}
cout << endl;
}

View File

@ -38,7 +38,7 @@ LOCAL std::map<uint8_t, uint8_t> g_mms_m_type_to_local_type = {
{MMS_UNSIGNED, DATA_TYPE_U32},
{MMS_FLOAT, DATA_TYPE_F32},
{MMS_STRING, DATA_TYPE_STR},
{MMS_VISIBLE_STRING, DATA_TYPE_STR},
// {MMS_VISIBLE_STRING, DATA_TYPE_STR},
};
LOCAL std::map<uint8_t, uint8_t> g_mms_m_ctrl_type_to_local_ctrl_type = {
@ -251,7 +251,7 @@ LOCAL int iec61850m_signal_change_decode(std::string saddr, SIGNAL_CTRL_STEP ste
std::string data_type_str = "";
data_type_str = dc_get_data_type_str_by_id(data_type);
MY_LOG_I("iec61850m_signal_change_callback saddr %s, step %s, data_type %s, value %s", saddr.c_str(), step_str.c_str(), data_type_str.c_str(), value.c_str());
MY_LOG_I("iec61850m_signal_change_callback saddr %s, step %s, data_type %s, mms_type %d, value %s", saddr.c_str(), step_str.c_str(), data_type_str.c_str(), mms_type, value.c_str());
return 0;
}
@ -308,7 +308,7 @@ LOCAL void iec61850m_signal_ao_change_callback(std::string saddr, SIGNAL_CTRL_ST
if(p_config->p_ao_sig[j].sig.saddr == saddr)
{
std::string val = dc_get_signal_val(p_data, data_type);
MY_LOG_I("iec61850m_signal_change_callback val %s, ctrl_type %d", val.c_str(), ctrl_type);
MY_LOG_I("iec61850m_signal_change_callback val %s, ctrl_type %d, mms_type %d", val.c_str(), ctrl_type, mms_type);
mms_send_control(p_info->fd, saddr.c_str(), val.c_str(), mms_type, ctrl_type, 0);
}
}

View File

@ -26,7 +26,7 @@
</Co>
<Ao desc="参数">
<Item no="0" type="4" ctlModel="4" saddr="iec61850m.prj.ao.0" desc="参数01" LDev="PROT" LNode="LPHD1" DoName="SettingGrp.setVal" fc="2" min="1" max="30" step="1" unit="" value="1" default="1"/>
<Item no="1" type="13" ctlModel="4" saddr="iec61850m.prj.ao.1" desc="参数02" LDev="PROT" LNode="LPHD1" DoName="DeviceName" fc="2" min="" max="" step="" unit="" value="1" default="1"/>
<Item no="1" type="13" ctlModel="4" saddr="iec61850m.prj.ao.1" desc="参数02" LDev="PROT" LNode="LPHD1" DoName="DeviceName.setVal" fc="2" min="" max="" step="" unit="" value="1" default="1"/>
</Ao>
<Param desc="定值">
<Item no="0" type="6" ctlModel="4" saddr="iec61850m.prj.param.0" desc="定值01" LDev="PROT" LNode="PTOC1" DoName="StrVal.setMag.f" fc="2" min="0.05" max="150" step="0.001" unit="A" num="2">