public bool CAN_OpenChannel(int mode) { int _hnd = -1; if (mode == 0) { _hnd = Canlib.canOpenChannel(this._Channel, Canlib.canOPEN_ACCEPT_LARGE_DLC); } else { _hnd = Canlib.canOpenChannel(this._Channel, Canlib.canOPEN_ACCEPT_LARGE_DLC); } if (_hnd >= 0) { this.handle = _hnd; Canlib.canAccept(handle, 0x7DF, Canlib.canFILTER_SET_CODE_STD); Canlib.canAccept(handle, 0x7D0, Canlib.canFILTER_SET_MASK_STD); return(true); } else { return(false); } }
public bool CanLongMsgSend(int id, byte[] data, int datalength, int retrycount, double timeout, ref int EcuID, ref byte[] READDATA, ref string errmsg) { if ((datalength < 9) || (data.Length < 9)) { errmsg = "Command Data Length <=8"; return(false); } bool _LoopChk = true; int _EcuID; byte[] _EcuData = new byte[8]; int _EcuDlc; int _EcuFlags; long _EcuTime; int _Ecu_FS = -1; // 정상적으로 수신시 확인되는 값, FS FlowStatus, BS BlockSize, STmin int _Ecu_BS = 0; int _Ecu_STmin = 0; double _Ecu_Stmin_sec; // 소수점단위 계산 bool _Ecu_FlowControl_Receive_OK = false; byte[] _Data_FF = new byte[8]; byte[] _Data_CF = new byte[8]; int _LastSendDataIndex = 0; Canlib.canStatus status; Stopwatch _stopwatch_total = new Stopwatch(); Stopwatch _stopwatch_send = new Stopwatch(); // 명령 만들기 _Data_FF[0] = 0x10; Int32 _DataLength_12bit = 0x00000000; _DataLength_12bit = (Int32)datalength; _DataLength_12bit = _DataLength_12bit & 0x00000FFF; byte byte1Lownibble; byte byte2; byte1Lownibble = (byte)((_DataLength_12bit & 0x00000F00) >> 16); byte2 = (byte)(_DataLength_12bit & 0x000000FF); _Data_FF[0] = (byte)(0x10 | byte1Lownibble); _Data_FF[1] = byte2; _Data_FF[2] = data[0]; _Data_FF[3] = data[1]; _Data_FF[4] = data[2]; _Data_FF[5] = data[3]; _Data_FF[6] = data[4]; _Data_FF[7] = data[5]; _LastSendDataIndex = 6; // //Canlib.canBusOn(handle); //status = Canlib.canWrite(handle, id, _Data_FF, 8, flags); //Open up a new handle for reading readHandle = Canlib.canOpenChannel(channel, Canlib.canOPEN_ACCEPT_LARGE_DLC); status = Canlib.canAccept(readHandle, 0x7DF, Canlib.canFILTER_SET_CODE_STD); status = Canlib.canAccept(readHandle, 0x7D0, Canlib.canFILTER_SET_MASK_STD); status = Canlib.canBusOn(readHandle); if (status == Canlib.canStatus.canOK) { onBus = true; } else { onBus = false; } if (readHandle < 0) { errmsg = "canOpenChannel Handle create error"; return(false); } if (!onBus) { errmsg = "onBus false"; return(false); } _stopwatch_total.Reset(); _stopwatch_total.Start(); _stopwatch_send.Reset(); _stopwatch_send.Start(); // Receive Channel Open -> SEND Canlib.canBusOn(handle); status = Canlib.canWrite(handle, id, _Data_FF, 8, flags); while (_LoopChk) { // TimeOut Check long st = _stopwatch_total.ElapsedMilliseconds; double _durationtime = st / 1000.0; // ms -> sec if (_durationtime > timeout) { // 설정시간안에 메세지 및 처리를 못했을 경우 종료 errmsg = "timeout error"; _LoopChk = false; break; } // Message Recieve Check bool _RecvOK = false; status = Canlib.canReadWait(readHandle, out _EcuID, _EcuData, out _EcuDlc, out _EcuFlags, out _EcuTime, 100); // 100ms timeout if (status == Canlib.canStatus.canOK) { if ((_EcuFlags & Canlib.canMSG_ERROR_FRAME) == Canlib.canMSG_ERROR_FRAME) { errmsg = "***ERROR FRAME RECEIVED***"; } else { errmsg = String.Format("ID={0:X4} {1} {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10}\r", _EcuID, _EcuDlc, _EcuData[0], _EcuData[1], _EcuData[2], _EcuData[3], _EcuData[4], _EcuData[5], _EcuData[6], _EcuData[7], _EcuTime); if (_EcuID == 0x07D9) { _RecvOK = true; } } } else if (status != Canlib.canStatus.canERR_NOMSG) { errmsg = "TimeOut:NO MSG"; } //CheckStatus("Read message " + errmsg, status); //Canlib.canBusOff(readHandle); if ((_EcuID == 0x07D9) && (_RecvOK)) { byte EcuFC_Check = _EcuData[0]; EcuFC_Check = (byte)((EcuFC_Check & 0x00F0) >> 4); if (EcuFC_Check == 3) { _LoopChk = false; _Ecu_FS = (_EcuData[0] & 0x000F); _Ecu_BS = (int)(_EcuData[1] & 0x00FF); _Ecu_STmin = (int)(_EcuData[2] & 0x00FF); if (_Ecu_STmin <= 0x7F) { _Ecu_Stmin_sec = _Ecu_STmin * 0.001; } if (_Ecu_STmin >= 0xF1) { _Ecu_Stmin_sec = (_Ecu_STmin - 0xF0) * 0.0001; } _Ecu_FlowControl_Receive_OK = true; } string sndmsg = String.Format("ID={0:X4} {1} {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2}\r", id, 8, _Data_FF[0], _Data_FF[1], _Data_FF[2], _Data_FF[3], _Data_FF[4], _Data_FF[5], _Data_FF[6], _Data_FF[7]); CheckStatus("PC->ECU " + sndmsg, Canlib.canStatus.canOK); CheckStatus("ECU->PC " + errmsg, status); } } Canlib.canClose(readHandle); if (!_Ecu_FlowControl_Receive_OK) { errmsg = "Ecu FlowControl not arrived"; return(false); } if (_Ecu_FS > 0) { errmsg = "Ecu FlowControl signal Busy"; return(false); } // ECU에서 FC를 정상적으로 수신후 데이터 전송.... _stopwatch_total.Reset(); _stopwatch_total.Start(); _stopwatch_send.Reset(); _stopwatch_send.Start(); _LoopChk = true; int _SequenceNumber = 1; byte _SN = (byte)_SequenceNumber; int _BlockSendLoopCount = _Ecu_BS; Canlib.canBusOn(handle); bool _EcuLastReceiveOK = false; // CF 전송후 수신확인. //Open up a new handle for reading readHandle = Canlib.canOpenChannel(channel, Canlib.canOPEN_ACCEPT_LARGE_DLC); status = Canlib.canAccept(readHandle, 0x7DF, Canlib.canFILTER_SET_CODE_STD); status = Canlib.canAccept(readHandle, 0x7D0, Canlib.canFILTER_SET_MASK_STD); status = Canlib.canBusOn(readHandle); if (status == Canlib.canStatus.canOK) { onBus = true; } else { onBus = false; } if (readHandle < 0) { errmsg = "canOpenChannel Handle create error"; return(false); } if (!onBus) { errmsg = "onBus false"; return(false); } while (_LoopChk) { // TimeOut Check long st = _stopwatch_total.ElapsedMilliseconds; double _durationtime = st / 1000.0; // ms -> sec if (_durationtime > timeout) { // 설정시간안에 메세지 및 처리를 못했을 경우 종료 errmsg = "timeout error"; _LoopChk = false; break; } if (datalength < _LastSendDataIndex) { _LoopChk = false; break; } _stopwatch_send.Reset(); _stopwatch_send.Start(); // CF 전송 for (int hs = 0; hs < _BlockSendLoopCount; hs++) { // FF전송후 CF 데이터 전송 준비 _Data_CF[0] = 0x20; _Data_CF[0] = (byte)(_Data_CF[0] + _SN); for (int i = 0; i < 7; i++) { if (_LastSendDataIndex < datalength) { _Data_CF[1 + i] = data[_LastSendDataIndex]; } else { _Data_CF[1 + i] = 0x00; // 0xAA; } _LastSendDataIndex++; } _SN++; if (_SN > 16) { _SN = 0; } status = Canlib.canWrite(handle, id, _Data_CF, 8, flags); long _dt = _stopwatch_send.ElapsedMilliseconds; string sndmsg = String.Format("ID={0:X4} {1} {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10:D5}ms\r", id, 8, _Data_CF[0], _Data_CF[1], _Data_CF[2], _Data_CF[3], _Data_CF[4], _Data_CF[5], _Data_CF[6], _Data_CF[7], _dt); CheckStatus("PC->ECU " + sndmsg, status); break; // Only One Run-----------------------------------------------실제 전송될 데이터 길이만큼만 전송함---------------------------------------------------------- } // Message Recieve Check bool _RecvOK = false; bool _FinalReceiveCheck = true; Stopwatch _Final = new Stopwatch(); _Final.Reset(); _Final.Start(); while (_FinalReceiveCheck) { if ((_Final.ElapsedMilliseconds / 1000.0) > 3.0) { errmsg = "Finnal ECU Receive Msg TIMEOUT"; _FinalReceiveCheck = false; break; } status = Canlib.canReadWait(readHandle, out _EcuID, _EcuData, out _EcuDlc, out _EcuFlags, out _EcuTime, 100); // 100ms timeout if (status == Canlib.canStatus.canOK) { if ((_EcuFlags & Canlib.canMSG_ERROR_FRAME) == Canlib.canMSG_ERROR_FRAME) { errmsg = "***ERROR FRAME RECEIVED***"; } else { errmsg = String.Format("ID={0:X4} {1} {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10}\r", _EcuID, _EcuDlc, _EcuData[0], _EcuData[1], _EcuData[2], _EcuData[3], _EcuData[4], _EcuData[5], _EcuData[6], _EcuData[7], _EcuTime); if (_EcuID == 0x07D9) { _RecvOK = true; CheckStatus("ECU->PC " + errmsg, status); } } } else if (status != Canlib.canStatus.canERR_NOMSG) { errmsg = "TimeOut:NO MSG"; } //CheckStatus("Read message " + errmsg, status); //Canlib.canBusOff(readHandle); if ((_EcuID == 0x07D9) && (_RecvOK)) { Canlib.canBusOn(handle); byte[] temp = new byte[8] { 0x30, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA }; status = Canlib.canWrite(handle, 0x07D1, _Data_FF, 8, flags); CheckStatus("PC->ECU " + "PC AutoResponse(0x30,0x00,0x02,0xAA,0xAA,0xAA,0xAA,0xaa", status); Canlib.canBusOff(handle); status = Canlib.canReadWait(readHandle, out _EcuID, _EcuData, out _EcuDlc, out _EcuFlags, out _EcuTime, 100); if (status == Canlib.canStatus.canOK) { errmsg = String.Format("ID={0:X4} {1} {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10}\r", _EcuID, _EcuDlc, _EcuData[0], _EcuData[1], _EcuData[2], _EcuData[3], _EcuData[4], _EcuData[5], _EcuData[6], _EcuData[7], _EcuTime); if (_EcuID == 0x07D9) { _RecvOK = true; CheckStatus("ECU->PC " + errmsg, status); } } _FinalReceiveCheck = false; _EcuLastReceiveOK = true; _LoopChk = false; break; } } } if (readHandle >= 0) { Canlib.canClose(readHandle); } if (_EcuLastReceiveOK) { if (_EcuData[1] == 0x62) { return(true); } return(false); } else { return(false); } }
/* * Looks for messages and sends them to the output box. */ void Receiver_MessageHandlerLoop(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; Canlib.canStatus status = Canlib.canStatus.canERR_NOMSG; bool noError = true; int errorFrameCount = 0; //Create a Windows event handle Object winHandle = new IntPtr(-1); status = Canlib.canIoCtl(readHandle, Canlib.canIOCTL_GET_EVENTHANDLE, ref winHandle); if (status != Canlib.canStatus.canOK) { worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status); noError = false; } status = Canlib.canAccept(readHandle, 0x610, Canlib.canFILTER_SET_CODE_STD); if (status != Canlib.canStatus.canOK) { worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status); noError = false; } status = Canlib.canAccept(readHandle, 0xFFE, Canlib.canFILTER_SET_MASK_STD); if (status != Canlib.canStatus.canOK) { worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status); noError = false; } WaitHandle waitHandle = (WaitHandle) new CanlibWaitEvent(winHandle); while (noError && isReaderBusOn && readHandle >= 0) { //Wait for 25ms for an event to occur on the channel (BBMS CAN communication period: 25ms) bool eventHappened = waitHandle.WaitOne(25); if (!eventHappened) { continue; } int id; byte[] data = new byte[Defined.MAX_DLC]; int dlc; int flags; long time; string msgLog; //To attain the initial msg status = Canlib.canRead(readHandle, out id, data, out dlc, out flags, out time); //This while loop is to repeat canRead() until the msg boxes for readHandle becomes exhausted. while (status == Canlib.canStatus.canOK) { if ((flags & Canlib.canMSG_ERROR_FRAME) == Canlib.canMSG_ERROR_FRAME) { msgLog = "***ERROR FRAME RECEIVED*** Count = " + (++errorFrameCount); if (errorFrameCount > Defined.ERROR_FRAME_ENDURANCE_COUNT_LIMIT) { worker.ReportProgress((int)ReceiverReport.REPORT_RUNNING, "Too many error frames received. Bus off."); break; } } else { msgLog = String.Format("0x{0:x3} {1} {2:x2} {3:x2} {4:x2} {5:x2} {6:x2} {7:x2} {8:x2} {9:x2} @{10}", id, dlc, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], time); } //Sends the message to the ProcessMessage method worker.ReportProgress((int)ReceiverReport.REPORT_RUNNING, "[Rx] " + msgLog); //Result status of the following canRead() will finish the while loop if status!=Canlib.canStatus.canOK status = Canlib.canRead(readHandle, out id, data, out dlc, out flags, out time); } //If the reason to exit the while loop of canRead() was not canERR_NOMSG, an error is expected. if (status != Canlib.canStatus.canERR_NOMSG) { //Sends the error status to the ProcessMessage method and breaks the loop worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status); noError = false; } } if (isReaderBusOn) { worker.ReportProgress((int)ReceiverReport.FORCED_STOP, "Force Bus Off"); } }