Compare commits
No commits in common. "main" and "master" have entirely different histories.
6
BDU.sln
6
BDU.sln
@ -22,8 +22,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "加密狗", "加密狗\加
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BDU", "BDU\BDU.csproj", "{0C2B5CA2-D873-255B-1B76-741346ECA1BB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZLGCANFD", "ZLGCANFD\ZLGCANFD.csproj", "{307FD972-9EFD-453F-BBF3-92ECA032DA73}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -58,10 +56,6 @@ Global
|
||||
{0C2B5CA2-D873-255B-1B76-741346ECA1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C2B5CA2-D873-255B-1B76-741346ECA1BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0C2B5CA2-D873-255B-1B76-741346ECA1BB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{307FD972-9EFD-453F-BBF3-92ECA032DA73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{307FD972-9EFD-453F-BBF3-92ECA032DA73}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{307FD972-9EFD-453F-BBF3-92ECA032DA73}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{307FD972-9EFD-453F-BBF3-92ECA032DA73}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -27,10 +27,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ATS_DBContext\ATS_DBContext.csproj" />
|
||||
<ProjectReference Include="..\TOSUNCAN\TOSUNCAN.csproj" />
|
||||
<ProjectReference Include="..\Command\Command.csproj" />
|
||||
<ProjectReference Include="..\Common\Common.csproj" />
|
||||
<ProjectReference Include="..\DeviceCommand\DeviceCommand.csproj" />
|
||||
<ProjectReference Include="..\ZLGCANFD\ZLGCANFD.csproj" />
|
||||
<ProjectReference Include="..\TOSUNCAN\TOSUNCAN.csproj" />
|
||||
<ProjectReference Include="..\加密狗\加密狗.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using ZLGCANFD;
|
||||
using TSMasterCAN;
|
||||
|
||||
namespace BDU.Logic
|
||||
{
|
||||
@ -102,9 +102,9 @@ namespace BDU.Logic
|
||||
{
|
||||
tmpDevice.CommunicationProtocol = device.CommunicationProtocol;
|
||||
CAN.DisConnect();
|
||||
var re1 = CAN.Init(ZLGCAN.ZCAN_USBCANFD_100U,0);
|
||||
var re1 = CAN.Init("ATS测试系统");
|
||||
var re2 = CAN.LoadDBC(SystemConfig.Instance.DBCFilePath, [0, 1, 2, 3], out _);
|
||||
var re3 = CAN.Connect(0,new ZLGCAN.ZCAN_CHANNEL_INIT_CONFIG());
|
||||
var re3 = CAN.Connect();
|
||||
if (re1 == 0 && re2 == 0 && re3 == 0)
|
||||
{
|
||||
tmpDevice.Connected = true;
|
||||
@ -279,7 +279,7 @@ namespace BDU.Logic
|
||||
break;
|
||||
|
||||
case "CAN":
|
||||
var re1 = CAN.Init(ZLGCAN.ZCAN_USBCANFD_100U, 0);
|
||||
var re1 = CAN.Init("ATS测试系统");
|
||||
//var re2 = CAN.LoadDBC(SystemConfig.Instance.DBCFilePath, [0, 1, 2, 3], out _);
|
||||
//var re3 = CAN.Connect();
|
||||
if (re1 == 0 && CAN.ConnectFlag)
|
||||
|
||||
@ -15,7 +15,7 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using ZLGCANFD;
|
||||
using TSMasterCAN;
|
||||
|
||||
namespace BDU.Views
|
||||
{
|
||||
@ -57,7 +57,7 @@ namespace BDU.Views
|
||||
SignalName = DBCParse.MsgDatabase[通道][选中报文].signal_Name[选中信号],
|
||||
CatchID = Guid.NewGuid(),
|
||||
LogInterval = TimeSpan.FromMilliseconds(采集间隔),
|
||||
MessageID =(int)DBCParse.MsgDatabase[通道][选中报文].msg_id
|
||||
MessageID = DBCParse.MsgDatabase[通道][选中报文].msg_id
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@ -22,10 +22,9 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
using TSMasterCAN;
|
||||
using static BDU.Models.ParameterModel;
|
||||
using Path = System.IO.Path;
|
||||
using ZLGCANFD;
|
||||
|
||||
namespace BDU.Views
|
||||
{
|
||||
@ -376,12 +375,12 @@ namespace BDU.Views
|
||||
|
||||
private void ChannelMapping_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
//var re = CAN.ShowChannelMappingWindow(true);
|
||||
//if (re != 0)
|
||||
//{
|
||||
// var msg = CAN.GetErrorDescription(re);
|
||||
// Log.Error($"同星通道映射界面打开失败:{msg}");
|
||||
//}
|
||||
var re = CAN.ShowChannelMappingWindow(true);
|
||||
if (re != 0)
|
||||
{
|
||||
var msg = CAN.GetErrorDescription(re);
|
||||
Log.Error($"同星通道映射界面打开失败:{msg}");
|
||||
}
|
||||
}
|
||||
|
||||
private void TestDataInfo_Click(object sender, RoutedEventArgs e)
|
||||
@ -451,7 +450,7 @@ namespace BDU.Views
|
||||
var re = CAN.LoadDBC(openFileDialog.FileName, [0, 1, 2, 3], out var DataBaseID);
|
||||
if (re != 0)
|
||||
{
|
||||
Log.Error("CAN数据库加载失败:");// + CAN.GetErrorDescription(re)
|
||||
Log.Error("CAN数据库加载失败:" + CAN.GetErrorDescription(re));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -480,7 +479,7 @@ namespace BDU.Views
|
||||
}
|
||||
else
|
||||
{
|
||||
var res = CAN.Connect(ZLGCAN.ZCAN_USBCANFD_100U,new ZLGCAN.ZCAN_CHANNEL_INIT_CONFIG());
|
||||
var res = CAN.Connect();
|
||||
if (res == 0)
|
||||
{
|
||||
Log.Success($"CAN卡连接成功,返回值:{res}");
|
||||
@ -610,7 +609,5 @@ namespace BDU.Views
|
||||
{
|
||||
new DeviceManageWindow().Show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,10 +8,6 @@
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CanKit.Adapter.ZLG" Version="0.5.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
namespace ZLGCAN
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
419
ZLGCANFD/CAN.cs
419
ZLGCANFD/CAN.cs
@ -1,419 +0,0 @@
|
||||
using Common.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static Common.Attributes.ATSCommandAttribute;
|
||||
|
||||
namespace ZLGCANFD
|
||||
{
|
||||
/// <summary>
|
||||
/// ZLG CAN 驱动类 (由 TSMaster CAN 改写)
|
||||
/// </summary>
|
||||
[ATSCommand]
|
||||
[DeviceCategory("CAN卡驱动")]
|
||||
public class CAN
|
||||
{
|
||||
public static event Action ConnectEvent;
|
||||
public static event Action DisConnectEvent;
|
||||
public static bool ConnectFlag { get; set; } = false;
|
||||
|
||||
// 存储 ZLG 的设备句柄和多通道句柄
|
||||
private static nint _deviceHandle = 0;
|
||||
private static Dictionary<uint, nint> _channelHandles = new Dictionary<uint, nint>();
|
||||
|
||||
/// <summary>
|
||||
/// 用于接收 CAN FD 报文的队列
|
||||
/// </summary>
|
||||
private static readonly Queue<ZLGCAN.ZCAN_ReceiveFD_Data> _receivedMessages = new Queue<ZLGCAN.ZCAN_ReceiveFD_Data>();
|
||||
private static readonly object _lock = new object(); // 线程安全锁
|
||||
|
||||
// 接收线程控制标志
|
||||
private static bool _isReceiving = false;
|
||||
public static Action<ZLGCAN.ZCAN_ReceiveFD_Data> listener; // ZLG 接收事件委托
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class ZCAN_CANFD_FRAME
|
||||
{
|
||||
public uint can_id; // 报文ID (包含扩展帧标志位)
|
||||
public byte len; // 数据长度
|
||||
public byte flags; // CANFD标志 (0x01:CANFD, 0x02:BRS, 0x04:ESI)
|
||||
public byte __res0; // 保留
|
||||
public byte __res1; // 保留
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
public byte[] data; // 数据负载
|
||||
|
||||
// --- 添加以下属性以解决报错并适配旧代码 ---
|
||||
|
||||
/// <summary>
|
||||
/// 模拟 eff 字段:1表示扩展帧,0表示标准帧
|
||||
/// </summary>
|
||||
public uint eff
|
||||
{
|
||||
get { return (can_id & 0x80000000) != 0 ? 1u : 0u; }
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
can_id |= 0x80000000; // 将最高位置1,表示扩展帧
|
||||
else
|
||||
can_id &= 0x7FFFFFFF; // 将最高位清0,表示标准帧
|
||||
}
|
||||
}
|
||||
|
||||
public ZCAN_CANFD_FRAME()
|
||||
{
|
||||
data = new byte[64];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 CAN 驱动
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public static int Init(uint deviceType, uint deviceIndex)
|
||||
{
|
||||
if (_deviceHandle != 0) return 0;
|
||||
|
||||
_deviceHandle = ZLGCAN.ZCAN_OpenDevice(deviceType, deviceIndex, 0);
|
||||
|
||||
if (_deviceHandle == 0)
|
||||
{
|
||||
Debug.WriteLine("ZLG 设备初始化失败!");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放 CAN 驱动
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public static void Release()
|
||||
{
|
||||
DisConnect();
|
||||
if (_deviceHandle != 0)
|
||||
{
|
||||
ZLGCAN.ZCAN_CloseDevice(_deviceHandle);
|
||||
_deviceHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册监听器
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public static int RegisterListener(Action<ZLGCAN.ZCAN_ReceiveFD_Data> listenEvent)
|
||||
{
|
||||
listener = listenEvent;
|
||||
|
||||
if (!_isReceiving)
|
||||
{
|
||||
_isReceiving = true;
|
||||
Task.Run(ReceiveThreadProcess);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销监听器
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public static int UnRegisterListener()
|
||||
{
|
||||
listener = null;
|
||||
_isReceiving = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void ReceiveThreadProcess()
|
||||
{
|
||||
while (_isReceiving)
|
||||
{
|
||||
bool hasData = false;
|
||||
foreach (var chnHandle in _channelHandles.Values)
|
||||
{
|
||||
uint len = ZLGCAN.ZCAN_GetReceiveNum(chnHandle, ZDBC.FT_CANFD);
|
||||
if (len > 0)
|
||||
{
|
||||
int size = Marshal.SizeOf(typeof(ZLGCAN.ZCAN_ReceiveFD_Data));
|
||||
nint ptr = Marshal.AllocHGlobal((int)len * size);
|
||||
|
||||
uint readLen = ZLGCAN.ZCAN_ReceiveFD(chnHandle, ptr, len, 50);
|
||||
|
||||
for (int i = 0; i < readLen; i++)
|
||||
{
|
||||
nint pItem = ptr + i * size;
|
||||
var frame = Marshal.PtrToStructure<ZLGCAN.ZCAN_ReceiveFD_Data>(pItem);
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
_receivedMessages.Enqueue(frame);
|
||||
}
|
||||
listener?.Invoke(frame);
|
||||
}
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
hasData = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasData) Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Connect(uint channel, ZLGCAN.ZCAN_CHANNEL_INIT_CONFIG config)
|
||||
{
|
||||
if (_deviceHandle == 0) return -1;
|
||||
|
||||
nint chnHandle = ZLGCAN.ZCAN_InitCAN(_deviceHandle, channel, ref config);
|
||||
if (chnHandle == 0)
|
||||
{
|
||||
Debug.WriteLine($"CAN 通道 {channel} 初始化失败");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZLGCAN.ZCAN_StartCAN(chnHandle) == 1)
|
||||
{
|
||||
_channelHandles[channel] = chnHandle;
|
||||
ConnectFlag = true;
|
||||
Task.Run(() => ConnectEvent?.Invoke());
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"CAN 通道 {channel} 启动失败");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static int DisConnect()
|
||||
{
|
||||
foreach (var handle in _channelHandles.Values)
|
||||
{
|
||||
ZLGCAN.ZCAN_ResetCAN(handle);
|
||||
}
|
||||
_channelHandles.Clear();
|
||||
ConnectFlag = false;
|
||||
Task.Run(() => DisConnectEvent?.Invoke());
|
||||
return 0;
|
||||
}
|
||||
[Browsable(false)]
|
||||
public static int LoadDBC(string filePath, int[] channel, out uint databaseID)
|
||||
{
|
||||
// 1. 初始化 ZDBC 模块,获取句柄
|
||||
databaseID = ZDBC.ZDBC_Init(0, 1);
|
||||
|
||||
if (databaseID == ZDBC.INVALID_DBC_HANDLE)
|
||||
{
|
||||
return -1; // 初始化失败
|
||||
}
|
||||
|
||||
// 2. 构造文件信息结构体并加载
|
||||
ZDBC.FileInfo fileInfo = new ZDBC.FileInfo();
|
||||
fileInfo.strFilePath = new byte[ZDBC._MAX_FILE_PATH_ + 1];
|
||||
byte[] pathBytes = System.Text.Encoding.Default.GetBytes(filePath);
|
||||
Array.Copy(pathBytes, fileInfo.strFilePath, Math.Min(pathBytes.Length, ZDBC._MAX_FILE_PATH_));
|
||||
|
||||
fileInfo.type = ZDBC.PROTOCOL_OTHER; // 默认普通 CAN/CANFD
|
||||
fileInfo.merge = 0; // 清除原有数据加载新文件
|
||||
|
||||
// 将结构体封送到非托管内存
|
||||
nint pFileInfo = Marshal.AllocHGlobal(Marshal.SizeOf(fileInfo));
|
||||
Marshal.StructureToPtr(fileInfo, pFileInfo, false);
|
||||
|
||||
bool success = ZDBC.ZDBC_LoadFile(databaseID, pFileInfo);
|
||||
Marshal.FreeHGlobal(pFileInfo); // 释放临时内存
|
||||
|
||||
if (!success) return -2; // 加载文件失败
|
||||
|
||||
// 3. 将加载的数据同步到您本地的缓存(如 MsgDatabase)
|
||||
// 注意:ZLG 的加载通常是全局的,如果您的业务逻辑需要分 channel 存储,
|
||||
// 需要根据您的解析类进行填充
|
||||
foreach (var ch in channel)
|
||||
{
|
||||
// 这里的 Parse 需要您根据 ZDBC 的 API 重新实现(见下方第2点)
|
||||
DBCParse.Parse(databaseID, ch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public static int UnLoadDBC(uint? databaseID = null)
|
||||
{
|
||||
// 1. 如果传入了句柄,释放 ZDBC 引擎资源
|
||||
if (databaseID.HasValue && databaseID.Value != ZDBC.INVALID_DBC_HANDLE)
|
||||
{
|
||||
ZDBC.ZDBC_Release(databaseID.Value);
|
||||
}
|
||||
|
||||
// 2. 清除本地缓存
|
||||
DBCParse.MsgDatabase.Clear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#region 信号值获取方法 (ZLG 适配版)
|
||||
|
||||
public static double GetSignalValue(byte channel, string AMsgName, string ASgnName)
|
||||
{
|
||||
double value = double.NaN;
|
||||
var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
|
||||
|
||||
if (find != null)
|
||||
{
|
||||
int re = GetZlgSignalValue(ref find.ACANFD, AMsgName, ASgnName, ref value);
|
||||
|
||||
if (re != 1)
|
||||
{
|
||||
Debug.WriteLine($"GetSignalValue: 获取信号值失败, 消息: {AMsgName}, 信号: {ASgnName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"GetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public static int GetSignalValue(byte channel, string AMsgName, string ASgnName, ref double value)
|
||||
{
|
||||
var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
|
||||
if (find != null)
|
||||
{
|
||||
return GetZlgSignalValue(ref find.ACANFD, AMsgName, ASgnName, ref value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"GetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public static int GetSignalValue(ref ZCAN_CANFD_FRAME ACANFD, string AMsgName, string ASgnName, ref double value)
|
||||
{
|
||||
return GetZlgSignalValue(ref ACANFD, AMsgName, ASgnName, ref value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ZLG 私有解析辅助
|
||||
|
||||
private static int GetZlgSignalValue(ref ZCAN_CANFD_FRAME frame, string msgName, string sigName, ref double val)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 模拟或调用 ZLG 外部 DBC 库进行信号解析
|
||||
return 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static Dictionary<string, System.Timers.Timer> _cyclicTimers = new Dictionary<string, System.Timers.Timer>();
|
||||
|
||||
#region 信号值设置方法 (ZLG 适配版)
|
||||
|
||||
public static int SetSignalValue(byte channel, string AMsgName, string ASgnName, double AValue, bool isSend = false, float sendPeriod = 0)
|
||||
{
|
||||
var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
|
||||
if (find == null)
|
||||
{
|
||||
Debug.WriteLine($"SetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int re = EncodeZlgSignal(ref find.ACANFD, AMsgName, ASgnName, AValue);
|
||||
|
||||
if (re != 0)
|
||||
{
|
||||
Debug.WriteLine($"设置信号值编码失败! 消息:{AMsgName}, 信号:{ASgnName}");
|
||||
return re;
|
||||
}
|
||||
|
||||
if (isSend)
|
||||
{
|
||||
return TransmitLogic(channel, find, sendPeriod);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int SetSignalValue(uint channel, string AMsgName, float sendPeriod = 0)
|
||||
{
|
||||
var find = DBCParse.MsgDatabase[(byte)channel].FirstOrDefault(s => s.msg_name == AMsgName);
|
||||
if (find == null)
|
||||
{
|
||||
Debug.WriteLine($"SetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return TransmitLogic((byte)channel, find, sendPeriod);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部辅助逻辑
|
||||
|
||||
private static int TransmitLogic(byte channel, ZLG_Msg msg, float period)
|
||||
{
|
||||
if (period <= 0)
|
||||
{
|
||||
return SendZlgFrame(channel, msg.ACANFD);
|
||||
}
|
||||
else
|
||||
{
|
||||
string key = $"{channel}_{msg.msg_id}";
|
||||
|
||||
if (_cyclicTimers.ContainsKey(key))
|
||||
{
|
||||
_cyclicTimers[key].Stop();
|
||||
_cyclicTimers[key].Dispose();
|
||||
}
|
||||
|
||||
var timer = new System.Timers.Timer(period);
|
||||
timer.Elapsed += (s, e) => SendZlgFrame(channel, msg.ACANFD);
|
||||
timer.AutoReset = true;
|
||||
timer.Enabled = true;
|
||||
_cyclicTimers[key] = timer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static int SendZlgFrame(byte channel, ZCAN_CANFD_FRAME frame)
|
||||
{
|
||||
if (!_channelHandles.ContainsKey(channel)) return -1;
|
||||
|
||||
nint ptr = Marshal.AllocHGlobal(Marshal.SizeOf(frame));
|
||||
try
|
||||
{
|
||||
Marshal.StructureToPtr(frame, ptr, false);
|
||||
uint result = ZLGCAN.ZCAN_TransmitFD(_channelHandles[channel], ptr, 1);
|
||||
return result == 1 ? 0 : -1;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
private static int EncodeZlgSignal(ref ZCAN_CANFD_FRAME frame, string msgName, string sigName, double val)
|
||||
{
|
||||
// 信号编码逻辑实现
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,148 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace ZLGCANFD
|
||||
{
|
||||
public class ZLG_Msg
|
||||
{
|
||||
public int msg_type { get; set; }
|
||||
public uint msg_id { get; set; }
|
||||
public double msg_cyclic { get; set; }
|
||||
public byte msg_dlc { get; set; }
|
||||
public string msg_name { get; set; }
|
||||
public List<ZDBC.DBCSignal> signals { get; set; } = new List<ZDBC.DBCSignal>();
|
||||
public string[] signal_Name { get; set; }
|
||||
|
||||
// 适配 ZLG 的 CANFD 帧结构 (来自 2.txt)
|
||||
public CAN.ZCAN_CANFD_FRAME ACANFD;
|
||||
}
|
||||
|
||||
public class DBCParse
|
||||
{
|
||||
// 存储多通道的消息数据库
|
||||
public static List<List<ZLG_Msg>> MsgDatabase { get; set; } =
|
||||
Enumerable.Range(0, 12).Select(_ => new List<ZLG_Msg>()).ToList();
|
||||
|
||||
/// <summary>
|
||||
/// ZLG 专用解析逻辑:遍历 ZDBC 内部的消息链表并填充到 MsgDatabase
|
||||
/// </summary>
|
||||
/// <param name="hDBC">ZDBC_Init 返回的句柄</param>
|
||||
/// <param name="channel">目标通道索引</param>
|
||||
public static void Parse(uint hDBC, int channel)
|
||||
{
|
||||
if (hDBC == ZDBC.INVALID_DBC_HANDLE) return;
|
||||
|
||||
// 1. 初始化指针空间
|
||||
int msgSize = Marshal.SizeOf(typeof(ZDBC.DBCMessage));
|
||||
nint pMsg = Marshal.AllocHGlobal(msgSize);
|
||||
|
||||
try
|
||||
{
|
||||
// 清空当前通道旧数据
|
||||
MsgDatabase[channel].Clear();
|
||||
|
||||
// 2. 迭代获取所有消息
|
||||
bool hasMessage = ZDBC.ZDBC_GetFirstMessage(hDBC, pMsg);
|
||||
while (hasMessage)
|
||||
{
|
||||
ZDBC.DBCMessage dbMsg = Marshal.PtrToStructure<ZDBC.DBCMessage>(pMsg);
|
||||
|
||||
ZLG_Msg temp = new ZLG_Msg();
|
||||
temp.msg_id = dbMsg.nID;
|
||||
temp.msg_name = Encoding.Default.GetString(dbMsg.strName).TrimEnd('\0');
|
||||
temp.msg_dlc = (byte)dbMsg.nSize;
|
||||
temp.msg_cyclic = dbMsg.nCycleTime;
|
||||
temp.msg_type = dbMsg.nExtend; // 0-标准帧, 1-扩展帧
|
||||
|
||||
// 3. 处理信号
|
||||
int sigCount = (int)dbMsg.nSignalCount;
|
||||
temp.signal_Name = new string[sigCount];
|
||||
for (int i = 0; i < sigCount; i++)
|
||||
{
|
||||
var sig = dbMsg.vSignals[i];
|
||||
temp.signals.Add(sig);
|
||||
temp.signal_Name[i] = Encoding.Default.GetString(sig.strName).TrimEnd('\0');
|
||||
}
|
||||
|
||||
// 4. 初始化对应的 ZLG 发送帧结构 (预设好 ID 和 DLC)
|
||||
temp.ACANFD = new CAN.ZCAN_CANFD_FRAME();
|
||||
temp.ACANFD.can_id = dbMsg.nID;
|
||||
temp.ACANFD.len = (byte)dbMsg.nSize;
|
||||
temp.ACANFD.eff = dbMsg.nExtend;
|
||||
temp.ACANFD.data = new byte[64];
|
||||
|
||||
MsgDatabase[channel].Add(temp);
|
||||
|
||||
// 获取下一条
|
||||
hasMessage = ZDBC.ZDBC_GetNextMessage(hDBC, pMsg);
|
||||
}
|
||||
|
||||
// 按 ID 排序
|
||||
MsgDatabase[channel].Sort((a, b) => a.msg_id.CompareTo(b.msg_id));
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 释放内存
|
||||
Marshal.FreeHGlobal(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载 DBC 的入口函数
|
||||
/// </summary>
|
||||
public static int LoadDBC(string filePath, int[] channels, out uint databaseID)
|
||||
{
|
||||
// 初始化
|
||||
databaseID = ZDBC.ZDBC_Init(0, 1);
|
||||
if (databaseID == ZDBC.INVALID_DBC_HANDLE) return -1;
|
||||
|
||||
// 准备文件信息
|
||||
ZDBC.FileInfo fileInfo = new ZDBC.FileInfo();
|
||||
fileInfo.strFilePath = new byte[ZDBC._MAX_FILE_PATH_ + 1];
|
||||
byte[] pathBytes = Encoding.Default.GetBytes(filePath);
|
||||
Array.Copy(pathBytes, fileInfo.strFilePath, Math.Min(pathBytes.Length, ZDBC._MAX_FILE_PATH_));
|
||||
fileInfo.type = ZDBC.PROTOCOL_OTHER;
|
||||
fileInfo.merge = 0;
|
||||
|
||||
// 加载文件
|
||||
nint pFileInfo = Marshal.AllocHGlobal(Marshal.SizeOf(fileInfo));
|
||||
Marshal.StructureToPtr(fileInfo, pFileInfo, false);
|
||||
bool success = ZDBC.ZDBC_LoadFile(databaseID, pFileInfo);
|
||||
Marshal.FreeHGlobal(pFileInfo);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
ZDBC.ZDBC_Release(databaseID);
|
||||
return -2;
|
||||
}
|
||||
|
||||
// 解析到各通道
|
||||
foreach (var ch in channels)
|
||||
{
|
||||
Parse(databaseID, ch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载 DBC 并释放 ZDBC 句柄
|
||||
/// </summary>
|
||||
public static int UnLoadDBC(uint? databaseID = null)
|
||||
{
|
||||
if (databaseID.HasValue && databaseID.Value != ZDBC.INVALID_DBC_HANDLE)
|
||||
{
|
||||
ZDBC.ZDBC_Release(databaseID.Value);
|
||||
}
|
||||
|
||||
foreach (var list in MsgDatabase)
|
||||
{
|
||||
list.Clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
1236
ZLGCANFD/ZLGAPI.cs
1236
ZLGCANFD/ZLGAPI.cs
File diff suppressed because it is too large
Load Diff
@ -1,19 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="ZLGCANFD.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Reference in New Issue
Block a user