/// <summary> /// 初始化CAN /// </summary> /// <param name="mBaudRate">波特率</param> /// <param name="pInitConfig">初始化CAN的配置参数</param> /// <returns></returns> public uint InitCAN(int mBaudRate, ref INIT_CONFIG pInitConfig) { INIT_CONFIG pConfig = CAN.CreateBasicInitConfig(); CAN.ConfigBaudRate(m_BaudRate, ref pConfig); if (pConfig.Timing0 != pInitConfig.Timing0 || pConfig.Timing1 != pInitConfig.Timing1) { Logger.Info(string.Format("baudrate[{0}] and initConfig[0x{1}:0x{2}] not match", m_BaudRate, pInitConfig.Timing0.ToString("x"), pInitConfig.Timing1.ToString("x"))); return((uint)CAN_RESULT.ERR_UNKNOWN); } this.m_BaudRate = mBaudRate; this.p_InitConfig = pInitConfig; if (CANDLL.InitCAN((UInt32)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, m_ChannelIndex, ref pInitConfig) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("init channel[{0}] successful.", m_ChannelName)); this.m_IsInitialized = true; return((uint)CAN_RESULT.SUCCESSFUL); } this.m_IsInitialized = false; uint result = (uint)CAN_RESULT.ERR_UNKNOWN; CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); if (ReadErrInfo(ref pCANErrorInfo) == (uint)CAN_RESULT.SUCCESSFUL) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("init channel[{0}] failed: [0x{1}].", m_ChannelName, result.ToString("x"))); return(result); }
/// <summary> /// 发送CAN帧数据 /// </summary> /// <param name="length">需要发送的帧数</param> /// <returns>成功发送的帧数</returns> private uint Transmit(uint length) { uint nSuccessNum = 0; for (int index = 0; index < length; index++) { CAN_FRAME pCANFrame; if (this.p_CANSendingBufQueue.TryDequeue(out pCANFrame)) { if (CANDLL.Transmit((uint)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, m_ChannelIndex, ref pCANFrame.CANObj, 1) == 1) { pCANFrame.Status = CAN_FRAME_STATUS.SUCCESS; pCANFrame.Time = DateTime.Now; nSuccessNum++; Logger.Debug(string.Format("channel[{0}] transmit a message successful.", m_ChannelName)); } else { CAN_ERR_INFO pCANErrInfo = new CAN_ERR_INFO(); if (ReadErrInfo(ref pCANErrInfo) == (uint)CAN_RESULT.SUCCESSFUL) { pCANFrame.CANErrInfo = pCANErrInfo; } pCANFrame.Status = CAN_FRAME_STATUS.FAILED; pCANFrame.Time = DateTime.Now; Logger.Info(string.Format("channel[{0}] transmit a message failed: [{1}]", m_ChannelName, pCANErrInfo.ErrCode)); } this.p_CANSendedBufQueue.Enqueue(pCANFrame); } } Logger.Info(string.Format("channel[{0}] transmit [{1}/{2}] messages successful.", m_ChannelName, nSuccessNum, length)); return(nSuccessNum); }
/// <summary> /// 复位CAN /// </summary> /// <returns></returns> public uint ResetCAN() { if (!this.m_IsStarted) { Logger.Info(string.Format("channel[{0}] already reset.", m_ChannelName)); return((uint)CAN_RESULT.SUCCESSFUL); } if (CANDLL.ResetCAN((UInt32)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, m_ChannelIndex) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("channel[{0}] reset successful.", m_ChannelName)); this.m_IsStarted = false; return((uint)CAN_RESULT.SUCCESSFUL); } CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); uint result = (uint)CAN_RESULT.ERR_UNKNOWN; if (ReadErrInfo(ref pCANErrorInfo) == (uint)CAN_RESULT.SUCCESSFUL) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("channel[{0}] reset failed: [0x{1}].", m_ChannelName, result.ToString("x"))); return(result); }
/// <summary> /// 打开设备 /// </summary> /// <returns></returns> public uint OpenDevice() { if (this.m_IsDeviceOpen) { Logger.Info(string.Format("device[{0}] already open", this.GetDeviceName())); return((uint)CAN_RESULT.SUCCESSFUL); } if (CANDLL.OpenDevice((UInt32)m_DeviceType, m_DeviceIndex, 0) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("open device[{0}] successful", this.GetDeviceName())); m_IsDeviceOpen = true; return((uint)CAN_RESULT.SUCCESSFUL); } uint result = (uint)CAN_RESULT.ERR_UNKNOWN; CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); if (CANDLL.ReadErrInfo((UInt32)m_DeviceType, m_DeviceIndex, -1, ref pCANErrorInfo) == CAN.CAN_DLL_RESULT_SUCCESS) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("open device[{0}] failed: [0x{1}]", this.GetDeviceName(), result.ToString("x"))); return(result); }
public CAN_FRAME(CAN_OBJ pCANObj, DateTime time, CAN_FRAME_DIRECTION direction, CAN_FRAME_STATUS status) { this.CANObj = pCANObj; this.Time = time; this.Direction = direction; this.Status = status; this.CANErrInfo = new CAN_ERR_INFO(); }
/// <summary> /// 读取CAN最近一次错误信息 /// </summary> /// <param name="pCanErrInfo"></param> /// <returns></returns> public uint ReadErrInfo(ref CAN_ERR_INFO pCanErrInfo) { if (CANDLL.ReadErrInfo((UInt32)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, (int)m_ChannelIndex, ref pCanErrInfo) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("channel[{0}] read error info successful.", m_ChannelName)); return((uint)CAN_RESULT.SUCCESSFUL); } Logger.Info(string.Format("channel[{0}] read error info failed.", m_ChannelName)); return((uint)CAN_RESULT.ERR_UNKNOWN); }
/// <summary> /// 清空CAN缓冲区 /// </summary> /// <returns></returns> public uint ClearBuffer() { if (CANDLL.ClearBuffer((UInt32)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, m_ChannelIndex) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("channel[{0}] clear buffer successful.", m_ChannelName)); return((uint)CAN_RESULT.SUCCESSFUL); } uint result = (uint)CAN_RESULT.ERR_UNKNOWN; CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); if (ReadErrInfo(ref pCANErrorInfo) == (uint)CAN_RESULT.SUCCESSFUL) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("channel[{0}] clear buffer failed: [0x{1}].", m_ChannelName, result.ToString("x"))); return(result); }
/// <summary> /// 设置CAN的指定类型配置参数 /// </summary> /// <param name="refType">参数类型</param> /// <param name="data">设置的值</param> /// <returns></returns> unsafe public uint SetReference(uint refType, byte *data) { if (CANDLL.SetReference((uint)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, m_ChannelIndex, refType, data) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("channel[{0}] set reference successful.", m_ChannelName)); return((uint)CAN_RESULT.SUCCESSFUL); } uint result = (uint)CAN_RESULT.ERR_UNKNOWN; CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); if (ReadErrInfo(ref pCANErrorInfo) == (uint)CAN_RESULT.SUCCESSFUL) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("channel[{0}] set reference failed: [0x{1}].", m_ChannelName, result.ToString("x"))); return(result); }
/// <summary> /// 读取板卡信息 /// </summary> /// <returns></returns> private uint ReadBoardInfo() { if (CANDLL.ReadBoardInfo((UInt32)m_DeviceType, m_DeviceIndex, ref p_DeviceInfo) == CAN.CAN_DLL_RESULT_SUCCESS) { Logger.Info(string.Format("device[{0}] read board info successful", this.GetDeviceName())); return((uint)CAN_RESULT.SUCCESSFUL); } uint result = (uint)CAN_RESULT.ERR_UNKNOWN; CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); if (CANDLL.ReadErrInfo((UInt32)m_DeviceType, m_DeviceIndex, -1, ref pCANErrorInfo) == CAN.CAN_DLL_RESULT_SUCCESS) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("device[{0}] read board info failed: [0x{1}]", this.GetDeviceName(), result.ToString("x"))); return(result); }
/// <summary> /// 接收CAN帧数据 /// </summary> /// <param name="pCanFrames">接收到的帧数组</param> /// <param name="length">需要接收的帧数</param> /// <param name="waitMilliseconds">等待时间ms</param> /// <returns>实际接收的帧数</returns> private uint Receive(out CAN_FRAME[] pCanFrames, uint length, int waitMilliseconds) { uint realRcvNum = 0; pCanFrames = null; try { IntPtr pReceive = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CAN_OBJ)) * (Int32)length); realRcvNum = CANDLL.Receive((uint)p_ParentDevice.DeviceType, p_ParentDevice.DeviceIndex, m_ChannelIndex, pReceive, length, waitMilliseconds); if (realRcvNum != uint.MaxValue) { Logger.Info(string.Format("channel[{0}] receive [{1}/{2}] messages successful.", m_ChannelName, realRcvNum, length)); pCanFrames = new CAN_FRAME[realRcvNum]; for (int index = 0; index < realRcvNum; index++) { CAN_OBJ pCANObj = (CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pReceive + index * Marshal.SizeOf(typeof(CAN_OBJ))), typeof(CAN_OBJ)); pCanFrames[index] = new CAN_FRAME(pCANObj, DateTime.Now, CAN_FRAME_DIRECTION.RECEIVE, CAN_FRAME_STATUS.SUCCESS); } Marshal.FreeHGlobal(pReceive); return(realRcvNum); } Marshal.FreeHGlobal(pReceive); CAN_ERR_INFO pCANErrorInfo = new CAN_ERR_INFO(); uint result = (uint)CAN_RESULT.ERR_UNKNOWN; if (ReadErrInfo(ref pCANErrorInfo) == (uint)CAN_RESULT.SUCCESSFUL) { result = pCANErrorInfo.ErrCode; } Logger.Info(string.Format("channel[{0}] receive failed: [0x{1}].", m_ChannelName, result.ToString("x"))); return(realRcvNum); } catch (Exception e) { Logger.Error(string.Format("channel[{0}] receive exception.", m_ChannelName), e); return(realRcvNum); } }
public static extern UInt32 ReadErrInfo(UInt32 DeviceType, UInt32 DeviceIndex, Int32 CANIndex, ref CAN_ERR_INFO pCANErrInfo);
/// <summary> /// 获取对应的错误说明 /// </summary> /// <param name="pCANErrInfo"></param> /// <returns></returns> public static CAN_ERR_DETAIL[] GetErrDetail(CAN_ERR_INFO pCANErrInfo) { List <CAN_ERR_DETAIL> pCANErrDetails = new List <CAN_ERR_DETAIL>(); foreach (CAN_RESULT pCANResult in CAN_RESULT_MAPPING.Keys) { if ((pCANErrInfo.ErrCode & (uint)pCANResult) != 0) { CAN_ERR_DETAIL pCANErrDetail = new CAN_ERR_DETAIL(); pCANErrDetail.ErrCode = (uint)CAN_RESULT.ERR_CAN_OVERFLOW; pCANErrDetail.Descreption = CAN_RESULT_MAPPING[CAN_RESULT.ERR_CAN_OVERFLOW].ToString(); pCANErrDetail.Detail = string.Empty; if (pCANResult == CAN_RESULT.ERR_CAN_PASSIVE) { StringBuilder pDetail = new StringBuilder("错误类型:"); switch ((pCANErrInfo.PassiveErrData1 & 0xc0) >> 6) { case 0: pDetail.Append("位错误"); break; case 1: pDetail.Append("格式错误"); break; case 2: pDetail.Append("填充错误"); break; case 3: default: pDetail.Append("其他错误"); break; } pDetail.Append("|传输方向:"); pDetail.Append((pCANErrInfo.PassiveErrData1 & 0x20) == 0 ? "发送" : "接收"); pDetail.Append("|错误位置:"); switch (pCANErrInfo.PassiveErrData1 & 0x1f) { case 0x03: pDetail.Append("帧开始"); break; case 0x02: pDetail.Append("ID.28-ID.21"); break; case 0x06: pDetail.Append("ID.20-ID.18"); break; case 0x04: pDetail.Append("SRTR位"); break; case 0x05: pDetail.Append("IDE位"); break; case 0x07: pDetail.Append("ID.17-ID.13"); break; case 0x0f: pDetail.Append("ID.12-ID.5"); break; case 0x0e: pDetail.Append("ID.4-ID.0"); break; case 0x0c: pDetail.Append("RTR位"); break; case 0x0b: pDetail.Append("数据长度"); break; case 0x0a: pDetail.Append("数据区"); break; case 0x08: pDetail.Append("CRC序列"); break; case 0x18: pDetail.Append("CRC定义符"); break; case 0x19: pDetail.Append("应答通道"); break; case 0x1b: pDetail.Append("应答定义符"); break; case 0x1a: pDetail.Append("帧结束"); break; case 0x12: pDetail.Append("中止"); break; case 0x11: pDetail.Append("活动错误标志"); break; case 0x16: pDetail.Append("消极错误标志"); break; case 0x13: pDetail.Append("支配(控制)位误差"); break; case 0x17: pDetail.Append("错误定义符"); break; case 0x1c: pDetail.Append("溢出标志"); break; case 0x09: case 0x0d: default: pDetail.Append("无"); break; } pDetail.Append("|接收错误计数器:").Append(pCANErrInfo.PassiveErrData2.ToString()); pDetail.Append("|发送错误计数器:").Append(pCANErrInfo.PassiveErrData3.ToString()); pCANErrDetail.Detail = pDetail.ToString(); } else if (pCANResult == CAN_RESULT.ERR_CAN_LOSE) { StringBuilder pDetail = new StringBuilder("仲裁丢失位置:"); switch (pCANErrInfo.ArLostErrData & 0x1f) { case 0x0b: pDetail.Append("SRTR位"); break; case 0x0c: pDetail.Append("IDE位"); break; case 0x1f: pDetail.Append("ERTR位"); break; default: byte pos = (byte)(pCANErrInfo.ArLostErrData & 0x1f); if (pos <= 10) { pDetail.Append("bit" + (pos + 1) + "位"); } else { pDetail.Append("bit" + (pos + 1) + "位"); } break; } pCANErrDetail.Detail = pDetail.ToString(); } pCANErrDetails.Add(pCANErrDetail); } } return(pCANErrDetails.ToArray()); }