You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
11 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using CompressorXN_Common;
using CompressorXN_Log;
using CompressorXN_Model.Enums;
using HslCommunication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using thinger.DataConvertLib;
using USB2XXX;
using static USB2XXX.USB2CAN;
namespace CompressorXN_Communication.TuMos
{
public class TMSCANFDHelper : BaseTMS
{
private static Int32 SendMsgNum = 0;
private static Int32 ret = 0;
private static Thread CANSendMsgThread = null;
//private static Thread CANSenAdditionalMsgThread = null;
private static Thread CANReadMsgThread = null;
/// <summary>
/// 启动线程
/// </summary>
public static void SendCanFDMsgThread()
{
while (true)
{
if (!GlobalVar.CAN_SendMsgFlag)
{
Thread.Sleep(10);
continue;
}
//USB2CAN.CAN_MSG[] CanMsg = new USB2CAN.CAN_MSG[1];
//CanMsg[0] = new USB2CAN.CAN_MSG
//{
// ExternFlag = GlobalVar.agreementMsgVM.FrameType == "EXTEND" ? (byte)1 : (byte)0, //bit[0] - 是否是扩展帧,bit[7] - 当前帧为错误帧
// RemoteFlag = 0,//bit[0]-是否是远程帧,bit[6..5]-当前帧通道号bit[7]-发送帧标志
// ID = Convert.ToUInt32(GlobalVar.agreementMsgVM.SendId, 16),//报文ID
// DataLen = (byte)(GlobalVar.agreementMsgVM.FrameLen & 0xFF)//数据长度(<=8)即Data中有效数据长度
//};
USB2CANFD.CANFD_MSG[] CanMsg = new USB2CANFD.CANFD_MSG[1];
CanMsg[0] = new USB2CANFD.CANFD_MSG
{
//ExternFlag = GlobalVar.agreementMsgVM.FrameType == "EXTEND" ? (byte)1 : (byte)0, //bit[0] - 是否是扩展帧,bit[7] - 当前帧为错误帧
//RemoteFlag = 0,//bit[0]-是否是远程帧,bit[6..5]-当前帧通道号bit[7]-发送帧标志
ID = Convert.ToUInt32(GlobalVar.agreementMsgVM.SendId, 16),//报文ID
DLC = (byte)(GlobalVar.agreementMsgVM.FrameLen & 0xFF),//数据长度(<=8)即Data中有效数据长度
};
CanMsg[0].Flags |= USB2CANFD.CANFD_MSG_FLAG_FDF;
switch (GlobalVar.stepEnum)
{
case StepEnum.idling:
string idlingHex = GlobalVar.agreementMsgVM.IdlingHex;
if (!string.IsNullOrEmpty(idlingHex))
{
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(idlingHex);
}
break;
case StepEnum.speed1:
string speed1Hex = GlobalVar.agreementMsgVM.Speed1Hex;
if (!string.IsNullOrEmpty(speed1Hex))
{
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}speed1Hex=={speed1Hex}");
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(speed1Hex);
}
break;
case StepEnum.speed2:
string speed2Hex = GlobalVar.agreementMsgVM.Speed2Hex;
if (!string.IsNullOrEmpty(speed2Hex))
{
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}speed2Hex=={speed2Hex}");
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(speed2Hex);
}
break;
case StepEnum.speed3:
string speed3Hex = GlobalVar.agreementMsgVM.Speed3Hex;
if (!string.IsNullOrEmpty(speed3Hex))
{
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}speed3Hex=={speed3Hex}");
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(speed3Hex);
}
break;
case StepEnum.endolead:
string endoleadHex = GlobalVar.agreementMsgVM.EndoleadHex;
if (string.IsNullOrEmpty(endoleadHex))
{
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(endoleadHex);
}
break;
case StepEnum.singleDriver:
string singleDriverHex = GlobalVar.agreementMsgVM.SingleDriverHex;
if (!string.IsNullOrEmpty(singleDriverHex))
{
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(singleDriverHex);
}
break;
}
CanMsgDataCatch(CanMsg, out IntPtr pCanSendMsg);
int SendedNum = USB2CANFD.CANFD_SendMsg(DevHandle, WriteCANIndex, pCanSendMsg, CanMsg.Length);
if (SendedNum >= 0)
{
SendMsgNum += SendedNum;
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}Success send frames:{SendMsgNum}");
}
else
{
Console.WriteLine("Send CAN data failed!");
break;
}
Marshal.FreeHGlobal(pCanSendMsg);//释放缓冲区
//附加报文
if (!string.IsNullOrEmpty(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalSendId))
{
Thread.Sleep(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalPeriod);
USB2CANFD.CANFD_MSG[] additionalCanMsg = new USB2CANFD.CANFD_MSG[1];
additionalCanMsg[0] = new USB2CANFD.CANFD_MSG
{
ID = Convert.ToUInt32(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalSendId, 16),//报文ID
DLC = 8,//数据长度(<=8)即Data中有效数据长度
Data = ByteArrayLib.GetByteArrayFromHexString(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalContent)
};
CanMsg[0].Flags |= USB2CANFD.CANFD_MSG_FLAG_FDF;
CanMsgDataCatch(CanMsg, out pCanSendMsg);
SendedNum = USB2CANFD.CANFD_SendMsg(DevHandle, WriteCANIndex, pCanSendMsg, additionalCanMsg.Length);
if (SendedNum >= 0)
{
SendMsgNum += SendedNum;
Console.WriteLine("Success send frames:{0}", SendMsgNum);
}
else
{
Console.WriteLine("Send CAN data failed!");
break;
}
}
//Thread.Sleep(45);
Thread.Sleep(GlobalVar.agreementMsgVM.SendPeriod);
}
}
/// <summary>
/// 接收CANFD数据
/// </summary>
public static void ReadCanFDMsgThread()
{
while (true)
{
if (!GlobalVar.CAN_ReadMsgFlag)
{
Thread.Sleep(10);
continue;
}
USB2CANFD.CANFD_MSG[] CanMsgBuffer = new USB2CANFD.CANFD_MSG[1024];
//申请数据缓冲区
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CAN.CAN_MSG)) * CanMsgBuffer.Length);
int CanNum = USB2CANFD.CANFD_GetMsg(DevHandle, ReadCANIndex, pt, CanMsgBuffer.Length);
if (CanNum > 0)
{
for (int i = 0; i < CanNum; i++)
{
//从缓冲区中获取数据
CanMsgBuffer[i] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG))), typeof(USB2CANFD.CANFD_MSG));
//判断获取的是不是目标报文
if (CanMsgBuffer[i].ID == Convert.ToUInt32(GlobalVar.agreementMsgVM.ReciveId, 16))
{
//如果信号值不为空,要过滤信号值
if (!string.IsNullOrEmpty(GlobalVar.agreementMsgVM.ReciveSignalVal))
{
Console.WriteLine("接收目标报文");
if (Convert.ToUInt32(GlobalVar.agreementMsgVM.ReciveSignalVal, 16) == CanMsgBuffer[i].Data[0])
{
//记录日志
//LogHelper.Error(null,$"CanMsgBuffer[{i}].ID={CanMsgBuffer[i].ID}CanMsgBuffer[{i}].Data=" + StringLib.GetHexStringFromByteArray(CanMsgBuffer[i].Data));
GetCANReciveValHelper.GetReciveVal(CanMsgBuffer[i].Data);//从接收报文中解析实际值
}
}
else
{
GetCANReciveValHelper.GetReciveVal(CanMsgBuffer[i].Data);//从接收报文中解析实际值
}
}
}
}
else if (CanNum < 0)
{
Console.WriteLine("Get CAN data error!");
LogHelper.Error(null, "Get CAN data error!");
break;
}
//释放数据缓冲区,必须释放,否则程序运行一段时间后会报内存不足
Marshal.FreeHGlobal(pt);
//Thread.Sleep(GlobalVar.agreementMsgVM.RecivePeriod);
Thread.Sleep(50);
}
}
/// <summary>
/// 数据复制到数据缓冲区中
/// </summary>
/// <returns></returns>
private static void CanMsgDataCatch(USB2CANFD.CANFD_MSG[] CanMsg, out IntPtr pCanSendMsg)
{
pCanSendMsg = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)) * CanMsg.Length);//申请缓冲区
IntPtr pPonitor = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)));
Marshal.StructureToPtr(CanMsg[0], pPonitor, true);
byte[] buffer = new byte[Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG))];
Marshal.Copy(pPonitor, buffer, 0, Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)));
Marshal.Copy(buffer, 0, (IntPtr)(UInt32)pCanSendMsg, Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)));
Marshal.FreeHGlobal(pPonitor);//释放缓冲区
}
}
}