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; /// /// 启动线程 /// 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); } } /// /// 接收CANFD数据 /// 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); } } /// /// 数据复制到数据缓冲区中 /// /// 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);//释放缓冲区 } } }