CAN优化
This commit is contained in:
@@ -204,6 +204,7 @@ namespace CANModule.ViewModels
|
|||||||
{
|
{
|
||||||
CollectionID = Guid.NewGuid(),
|
CollectionID = Guid.NewGuid(),
|
||||||
Channel = MessageChannel,
|
Channel = MessageChannel,
|
||||||
|
MethodName = CANSignalBroadcaster.BuildMethodName((uint)decimalValue, SelectedSignal),
|
||||||
MessageName = ExtractMessageName(SelectedMessage),
|
MessageName = ExtractMessageName(SelectedMessage),
|
||||||
SignalName = SelectedSignal,
|
SignalName = SelectedSignal,
|
||||||
MessageID = decimalValue,
|
MessageID = decimalValue,
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ namespace CANModule.ViewModels
|
|||||||
|
|
||||||
if (targetMsg != null)
|
if (targetMsg != null)
|
||||||
{
|
{
|
||||||
_canfd.设置报文((uint)MessageSendChannel, targetMsg.msg_id.ToString(), SelectedSignal, SValue, sendPeriod);
|
_canfd.设置报文((uint)MessageSendChannel, targetMsg.msg_id.ToString(), SelectedSignal, SValue, sendPeriod, IsDirectlySend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,7 +603,7 @@ namespace CANModule.ViewModels
|
|||||||
private void OnDbcMessageDecoded(uint channel, ZDBC.DBCMessage msg)
|
private void OnDbcMessageDecoded(uint channel, ZDBC.DBCMessage msg)
|
||||||
{
|
{
|
||||||
// DBC 解码后的报文回调
|
// DBC 解码后的报文回调
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
var msgName = System.Text.Encoding.Default.GetString(msg.strName).TrimEnd('\0');
|
var msgName = System.Text.Encoding.Default.GetString(msg.strName).TrimEnd('\0');
|
||||||
var find = CanMessageList.FirstOrDefault(s => s.报文ID == (int)msg.nID&& s.通道==channel);
|
var find = CanMessageList.FirstOrDefault(s => s.报文ID == (int)msg.nID&& s.通道==channel);
|
||||||
|
|||||||
@@ -111,10 +111,10 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 发现设备方法信号并加入 ValueLimitList / DeviceSingleList
|
// 2. 发现设备方法信号并加入 ValueLimitList / DeviceSingleList
|
||||||
foreach (var signal in DiscoverDeviceSignals())
|
foreach (var (displayName, fingerprint, methodName) in DiscoverDeviceSignals())
|
||||||
{
|
{
|
||||||
//DeviceSingleList.Add(signal);
|
//DeviceSingleList.Add(displayName);
|
||||||
EnsureValueLimit(signal);
|
EnsureValueLimit(fingerprint, displayName, displayName, methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 发现 CAN 信号并加入 ValueLimitList / DeviceSingleList
|
// 3. 发现 CAN 信号并加入 ValueLimitList / DeviceSingleList
|
||||||
@@ -122,15 +122,15 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
{
|
{
|
||||||
//DeviceSingleList.Add(displayName);
|
//DeviceSingleList.Add(displayName);
|
||||||
_canSignalMap[displayName] = (fingerprint, methodName);
|
_canSignalMap[displayName] = (fingerprint, methodName);
|
||||||
EnsureValueLimit(displayName);
|
EnsureValueLimit(fingerprint, displayName, displayName, methodName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发现当前作用域所有可监测的设备方法信号(与 MonitorViewModel 逻辑一致)。
|
/// 发现当前作用域所有可监测的设备方法信号(与 MonitorViewModel 逻辑一致)。
|
||||||
/// 返回 DisplayName 列表。
|
/// 返回 (DisplayName, Fingerprint, MethodName) 列表。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IEnumerable<string> DiscoverDeviceSignals()
|
private IEnumerable<(string DisplayName, string Fingerprint, string MethodName)> DiscoverDeviceSignals()
|
||||||
{
|
{
|
||||||
if (_deviceManager?.DeviceMap == null) yield break;
|
if (_deviceManager?.DeviceMap == null) yield break;
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
string displayName = !string.IsNullOrEmpty(attr?.Description)
|
string displayName = !string.IsNullOrEmpty(attr?.Description)
|
||||||
? $"{deviceName}.{attr.Description}"
|
? $"{deviceName}.{attr.Description}"
|
||||||
: $"{deviceName}.{method.Name}";
|
: $"{deviceName}.{method.Name}";
|
||||||
yield return displayName;
|
yield return (displayName, fingerprint, method.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,12 +191,13 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
if (_systemConfig?.ConfigurationList == null) yield break;
|
if (_systemConfig?.ConfigurationList == null) yield break;
|
||||||
|
|
||||||
var msgDb = _deviceManager.CANFD.DBCParser.MsgDatabase;
|
var msgDb = _deviceManager.CANFD.DBCParser.MsgDatabase;
|
||||||
|
string canDeviceFingerprint = _deviceManager.GetCanDeviceFingerprint();
|
||||||
foreach (var cfg in _systemConfig.ConfigurationList)
|
foreach (var cfg in _systemConfig.ConfigurationList)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(cfg.SignalName)) continue;
|
if (string.IsNullOrEmpty(cfg.SignalName)) continue;
|
||||||
if (cfg.Channel < 0 || cfg.Channel >= msgDb.Count) continue;
|
if (cfg.Channel < 0 || cfg.Channel >= msgDb.Count) continue;
|
||||||
|
|
||||||
string fingerprint = CANSignalBroadcaster.BuildFingerprint((uint)cfg.Channel);
|
string fingerprint = CANSignalBroadcaster.BuildFingerprint(canDeviceFingerprint, (uint)cfg.Channel);
|
||||||
string methodName = CANSignalBroadcaster.BuildMethodName((uint)cfg.MessageID, cfg.SignalName);
|
string methodName = CANSignalBroadcaster.BuildMethodName((uint)cfg.MessageID, cfg.SignalName);
|
||||||
string displayName = CANSignalBroadcaster.BuildDisplayName(cfg.MessageName, cfg.SignalName);
|
string displayName = CANSignalBroadcaster.BuildDisplayName(cfg.MessageName, cfg.SignalName);
|
||||||
|
|
||||||
@@ -224,13 +225,16 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 确保 ValueLimitList 中存在指定信号;不存在则添加默认值。
|
/// 确保 ValueLimitList 中存在指定信号;不存在则添加默认值。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void EnsureValueLimit(string signalName)
|
private void EnsureValueLimit(string fingerprint, string displayName, string signalName, string methodName = "")
|
||||||
{
|
{
|
||||||
if (ValueLimitList.Any(x => x.SignalName == signalName)) return;
|
if (ValueLimitList.Any(x => x.SignalName == signalName)) return;
|
||||||
|
|
||||||
ValueLimitList.Add(new ValueLimitVM
|
ValueLimitList.Add(new ValueLimitVM
|
||||||
{
|
{
|
||||||
|
DisplayName = displayName,
|
||||||
|
Fingerprint = fingerprint,
|
||||||
SignalName = signalName,
|
SignalName = signalName,
|
||||||
|
MethodName = methodName,
|
||||||
Upper = 9999,
|
Upper = 9999,
|
||||||
Lower = -9999,
|
Lower = -9999,
|
||||||
UpperExtreme = 9999,
|
UpperExtreme = 9999,
|
||||||
@@ -323,7 +327,8 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
var msgDb = _deviceManager.CANFD.DBCParser.MsgDatabase;
|
var msgDb = _deviceManager.CANFD.DBCParser.MsgDatabase;
|
||||||
if (channel < 0 || channel >= msgDb.Count) return;
|
if (channel < 0 || channel >= msgDb.Count) return;
|
||||||
|
|
||||||
string fingerprint = CANSignalBroadcaster.BuildFingerprint(args.Channel);
|
string canDeviceFingerprint = _deviceManager.GetCanDeviceFingerprint();
|
||||||
|
string fingerprint = CANSignalBroadcaster.BuildFingerprint(canDeviceFingerprint, args.Channel);
|
||||||
|
|
||||||
// 1. 移除该通道中已失效的 CAN 信号限制项
|
// 1. 移除该通道中已失效的 CAN 信号限制项
|
||||||
var staleSignals = _canSignalMap
|
var staleSignals = _canSignalMap
|
||||||
@@ -353,7 +358,7 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
_canSignalMap[displayName] = (fingerprint, methodName);
|
_canSignalMap[displayName] = (fingerprint, methodName);
|
||||||
//if (!DeviceSingleList.Contains(displayName))
|
//if (!DeviceSingleList.Contains(displayName))
|
||||||
// DeviceSingleList.Add(displayName);
|
// DeviceSingleList.Add(displayName);
|
||||||
EnsureValueLimit(displayName);
|
EnsureValueLimit(fingerprint, displayName, displayName, methodName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,7 +371,8 @@ namespace MonitorModule.ViewModels.Dialogs
|
|||||||
{
|
{
|
||||||
if (args.Scope != _systemConfig?.Title) return;
|
if (args.Scope != _systemConfig?.Title) return;
|
||||||
|
|
||||||
string fingerprint = CANSignalBroadcaster.BuildFingerprint(args.Channel);
|
string canDeviceFingerprint = _deviceManager.GetCanDeviceFingerprint();
|
||||||
|
string fingerprint = CANSignalBroadcaster.BuildFingerprint(canDeviceFingerprint, args.Channel);
|
||||||
var toRemove = _canSignalMap
|
var toRemove = _canSignalMap
|
||||||
.Where(kvp => kvp.Value.Fingerprint == fingerprint)
|
.Where(kvp => kvp.Value.Fingerprint == fingerprint)
|
||||||
.Select(kvp => kvp.Key)
|
.Select(kvp => kvp.Key)
|
||||||
|
|||||||
@@ -556,7 +556,8 @@ namespace MonitorModule.ViewModels
|
|||||||
{
|
{
|
||||||
if (_systemConfig?.ConfigurationList == null) return;
|
if (_systemConfig?.ConfigurationList == null) return;
|
||||||
|
|
||||||
string fingerprint = CANSignalBroadcaster.BuildFingerprint(channel);
|
string canDeviceFingerprint = _deviceManager?.GetCanDeviceFingerprint() ?? string.Empty;
|
||||||
|
string fingerprint = CANSignalBroadcaster.BuildFingerprint(canDeviceFingerprint, channel);
|
||||||
var configs = _systemConfig.ConfigurationList.Where(c => c.Channel == (int)channel).ToList();
|
var configs = _systemConfig.ConfigurationList.Where(c => c.Channel == (int)channel).ToList();
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
@@ -650,7 +651,8 @@ namespace MonitorModule.ViewModels
|
|||||||
{
|
{
|
||||||
if (args.Scope != TestStatus) return;
|
if (args.Scope != TestStatus) return;
|
||||||
|
|
||||||
string fingerprint = CANSignalBroadcaster.BuildFingerprint(args.Channel);
|
string canDeviceFingerprint = _deviceManager?.GetCanDeviceFingerprint() ?? string.Empty;
|
||||||
|
string fingerprint = CANSignalBroadcaster.BuildFingerprint(canDeviceFingerprint, args.Channel);
|
||||||
|
|
||||||
// 从 AvailableMethods 中移除
|
// 从 AvailableMethods 中移除
|
||||||
var toRemoveMethods = AvailableMethods.Where(m => m.Fingerprint == fingerprint).ToList();
|
var toRemoveMethods = AvailableMethods.Where(m => m.Fingerprint == fingerprint).ToList();
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace UIShare.GlobalVariable
|
|||||||
{
|
{
|
||||||
if (_disposed) return;
|
if (_disposed) return;
|
||||||
|
|
||||||
string signalFingerprint = BuildFingerprint(channel);
|
string signalFingerprint = BuildFingerprint(canFingerprint, channel);
|
||||||
var now = DateTime.Now;
|
var now = DateTime.Now;
|
||||||
|
|
||||||
// 获取引用该 CAN 设备的所有作用域
|
// 获取引用该 CAN 设备的所有作用域
|
||||||
@@ -133,11 +133,12 @@ namespace UIShare.GlobalVariable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成 CAN 信号的 Fingerprint 格式:"CAN:{Channel}"
|
/// 生成 CAN 信号的 Fingerprint 格式:"{canDeviceFingerprint}:{channel}"
|
||||||
|
/// canDeviceFingerprint 来自 DeviceManager.ExtractHardwareFingerprint,如 "CAN:0"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string BuildFingerprint(uint channel)
|
public static string BuildFingerprint(string canDeviceFingerprint, uint channel)
|
||||||
{
|
{
|
||||||
return $"CAN:{channel}";
|
return $"{canDeviceFingerprint}:{channel}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ namespace UIShare.GlobalVariable
|
|||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前作用域配置的 CAN 设备硬件指纹(与 GlobalInfo.CanPool 的 Key 一致)。
|
||||||
|
/// 如 "CAN:0",其中 0 是 CANConfig.DeviceIndex。
|
||||||
|
/// </summary>
|
||||||
|
public string GetCanDeviceFingerprint()
|
||||||
|
{
|
||||||
|
if (_systemConfig?.DeviceList == null) return string.Empty;
|
||||||
|
var canConfig = _systemConfig.DeviceList.FirstOrDefault(d =>
|
||||||
|
d != null && d.IsEnabled &&
|
||||||
|
string.Equals(d.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase));
|
||||||
|
return canConfig != null ? ExtractHardwareFingerprint(canConfig) : string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
private void InitDevices()
|
private void InitDevices()
|
||||||
{
|
{
|
||||||
DeviceMap = new Dictionary<string, IBaseInterface>(StringComparer.OrdinalIgnoreCase);
|
DeviceMap = new Dictionary<string, IBaseInterface>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ namespace UIShare.UIViewModel
|
|||||||
public string SignalName { get; set; }
|
public string SignalName { get; set; }
|
||||||
public int CollectionInterval { get; set; }
|
public int CollectionInterval { get; set; }
|
||||||
public Guid CollectionID { get; set; }
|
public Guid CollectionID { get; set; }
|
||||||
|
public string MethodName {get;set;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace UIShare.UIViewModel
|
|||||||
private string _signalName = string.Empty;
|
private string _signalName = string.Empty;
|
||||||
private string _fingerprint = string.Empty;
|
private string _fingerprint = string.Empty;
|
||||||
private string _methodName = string.Empty;
|
private string _methodName = string.Empty;
|
||||||
|
private string _displayName = string.Empty;
|
||||||
private double _upper;
|
private double _upper;
|
||||||
private double _lower;
|
private double _lower;
|
||||||
private double _upperExtreme;
|
private double _upperExtreme;
|
||||||
@@ -22,6 +23,14 @@ namespace UIShare.UIViewModel
|
|||||||
{
|
{
|
||||||
get => _signalName;
|
get => _signalName;
|
||||||
set => SetProperty(ref _signalName, value);
|
set => SetProperty(ref _signalName, value);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 信号名(显示用)
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get => _displayName;
|
||||||
|
set => SetProperty(ref _displayName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Common.Attributes;
|
using Common.Attributes;
|
||||||
|
using Logger;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -29,6 +30,10 @@ namespace ZLGUSBCANFD
|
|||||||
// DBC 循环发送任务管理:Key = (通道号, 帧ID)
|
// DBC 循环发送任务管理:Key = (通道号, 帧ID)
|
||||||
private readonly ConcurrentDictionary<(uint 通道号, uint 帧ID), CancellationTokenSource> _cyclicSenders = new ConcurrentDictionary<(uint, uint), CancellationTokenSource>();
|
private readonly ConcurrentDictionary<(uint 通道号, uint 帧ID), CancellationTokenSource> _cyclicSenders = new ConcurrentDictionary<(uint, uint), CancellationTokenSource>();
|
||||||
|
|
||||||
|
// 信号值持久化覆盖表:Key = (通道号, 帧ID),Value = 信号名 → 物理值
|
||||||
|
// 每次 设置报文 会累积写入此表,发送时以 DBC 初始值为底再叠加此表覆盖值
|
||||||
|
private readonly ConcurrentDictionary<(uint 通道号, uint 帧ID), Dictionary<string, double>> _signalOverrides = new ConcurrentDictionary<(uint, uint), Dictionary<string, double>>();
|
||||||
|
|
||||||
// 动态硬件参数
|
// 动态硬件参数
|
||||||
private readonly uint _deviceType; // 76: USBCANFD-400U
|
private readonly uint _deviceType; // 76: USBCANFD-400U
|
||||||
private readonly uint _deviceIndex; // 设备索引
|
private readonly uint _deviceIndex; // 设备索引
|
||||||
@@ -371,14 +376,17 @@ namespace ZLGUSBCANFD
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// 循环发送出错时退出,避免刷屏
|
Logger.LoggerHelper.Error($"[ZLGCANFD] 循环发送 DBC 报文失败: {ex.Message}");
|
||||||
Console.WriteLine($"[ZLGCANFD] 循环发送 DBC 报文失败: {ex.Message}");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cyclicSenders.TryRemove((通道号, 帧ID), out var removedCts);
|
// 清理:仅当字典中存的仍然是本任务创建的 CTS 时才移除,避免误删新任务的 CTS
|
||||||
removedCts?.Dispose();
|
if (_cyclicSenders.TryGetValue((通道号, 帧ID), out var current) && ReferenceEquals(current, cts))
|
||||||
|
{
|
||||||
|
_cyclicSenders.TryRemove((通道号, 帧ID), out _);
|
||||||
|
}
|
||||||
|
cts.Dispose();
|
||||||
}, cts.Token);
|
}, cts.Token);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -392,7 +400,7 @@ namespace ZLGUSBCANFD
|
|||||||
if (_cyclicSenders.TryRemove((通道号, 帧ID), out var cts))
|
if (_cyclicSenders.TryRemove((通道号, 帧ID), out var cts))
|
||||||
{
|
{
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
cts.Dispose();
|
// 不在这里 Dispose,由 Task 的清理代码负责释放,避免 Task 仍在使用已释放的 Token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,6 +417,31 @@ namespace ZLGUSBCANFD
|
|||||||
_cyclicSenders.Clear();
|
_cyclicSenders.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除指定通道、指定帧 ID 的信号覆盖值,恢复为 DBC 初始值。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void 清除信号覆盖(uint 通道号, uint 帧ID)
|
||||||
|
{
|
||||||
|
if (_signalOverrides.TryRemove((通道号, 帧ID), out var dict))
|
||||||
|
{
|
||||||
|
lock (dict) dict.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除指定通道所有帧的信号覆盖值。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void 清除通道信号覆盖(uint 通道号)
|
||||||
|
{
|
||||||
|
foreach (var key in _signalOverrides.Keys)
|
||||||
|
{
|
||||||
|
if (key.通道号 == 通道号 && _signalOverrides.TryRemove(key, out var dict))
|
||||||
|
{
|
||||||
|
lock (dict) dict.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -536,7 +569,7 @@ namespace ZLGUSBCANFD
|
|||||||
/// <param name="物理值">要写入的实际物理数值</param>
|
/// <param name="物理值">要写入的实际物理数值</param>
|
||||||
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(单位毫秒)</param>
|
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(单位毫秒)</param>
|
||||||
/// <returns>操作是否成功</returns>
|
/// <returns>操作是否成功</returns>
|
||||||
public virtual bool 设置报文(uint 通道号, string 帧IDStr, string 信号名称, double 物理值, int 循环发送间隔毫秒 = 0)
|
public virtual bool 设置报文(uint 通道号, string 帧IDStr, string 信号名称, double 物理值, int 循环发送间隔毫秒 = 0, bool 直接发送=false)
|
||||||
{
|
{
|
||||||
if (!TryParseFrameId(帧IDStr, out uint 帧ID))
|
if (!TryParseFrameId(帧IDStr, out uint 帧ID))
|
||||||
{
|
{
|
||||||
@@ -548,12 +581,18 @@ namespace ZLGUSBCANFD
|
|||||||
if (!_isDbcLoadedArray[通道号]) return false;
|
if (!_isDbcLoadedArray[通道号]) return false;
|
||||||
if (string.IsNullOrWhiteSpace(信号名称)) return false;
|
if (string.IsNullOrWhiteSpace(信号名称)) return false;
|
||||||
|
|
||||||
var merged = 构建报文发送字典(通道号, 帧ID, new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase)
|
// 将本次设置的信号值写入持久化覆盖表(累积,不会丢失之前设置的值)
|
||||||
|
var overrides = _signalOverrides.GetOrAdd((通道号, 帧ID), _ => new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase));
|
||||||
|
lock (overrides)
|
||||||
{
|
{
|
||||||
{ 信号名称, 物理值 }
|
overrides[信号名称] = 物理值;
|
||||||
});
|
}
|
||||||
|
|
||||||
return 发送DBC定义报文(通道号, 帧ID, merged, 循环发送间隔毫秒);
|
// 构建发送字典:DBC 初始值 + 持久化覆盖表(已包含本次设置)
|
||||||
|
var merged = 构建报文发送字典(通道号, 帧ID);
|
||||||
|
|
||||||
|
if (直接发送) return 发送DBC定义报文(通道号, 帧ID, merged, 循环发送间隔毫秒);
|
||||||
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -753,6 +792,7 @@ namespace ZLGUSBCANFD
|
|||||||
var msg = (ZDBC.DBCMessage)Marshal.PtrToStructure(ptrDbcMsg, typeof(ZDBC.DBCMessage));
|
var msg = (ZDBC.DBCMessage)Marshal.PtrToStructure(ptrDbcMsg, typeof(ZDBC.DBCMessage));
|
||||||
var dict = new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase);
|
var dict = new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
// 1. DBC 初始值打底
|
||||||
for (int i = 0; i < msg.nSignalCount; i++)
|
for (int i = 0; i < msg.nSignalCount; i++)
|
||||||
{
|
{
|
||||||
var signal = msg.vSignals[i];
|
var signal = msg.vSignals[i];
|
||||||
@@ -763,6 +803,17 @@ namespace ZLGUSBCANFD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 叠加持久化覆盖表(之前 设置报文 累积的值)
|
||||||
|
if (_signalOverrides.TryGetValue((通道号, 帧ID), out var persisted))
|
||||||
|
{
|
||||||
|
lock (persisted)
|
||||||
|
{
|
||||||
|
foreach (var kvp in persisted)
|
||||||
|
dict[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 叠加本次调用传入的额外覆盖(优先级最高)
|
||||||
if (额外覆盖 != null)
|
if (额外覆盖 != null)
|
||||||
{
|
{
|
||||||
foreach (var kvp in 额外覆盖)
|
foreach (var kvp in 额外覆盖)
|
||||||
@@ -776,6 +827,7 @@ namespace ZLGUSBCANFD
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
||||||
Marshal.FreeHGlobal(ptrDbcMsg);
|
Marshal.FreeHGlobal(ptrDbcMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Common\Common.csproj" />
|
<ProjectReference Include="..\Common\Common.csproj" />
|
||||||
|
<ProjectReference Include="..\Logger\Logger.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user