using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Threading; using System.Globalization; //using Peak.Can.Basic; //using TPCANHandle = System.UInt16; //using TPCANBitrateFD = System.String; //using TPCANTimestampFD = System.UInt64; using S19File; using Can; using UDS; namespace CanTool { public enum EntrySecurityStatus { Idle, WaitReply, RequestSeedLevel1, SendkeyLevel1, RequestSeedLevel2, SendkeyLevel2, RequestSeedLevel3, SendkeyLevel3, RequestSeedLevel4, SendkeyLevel4, Unlock, } public enum UpdateFileType { App, UI, Rectify, }; public delegate void UDSReceivedFunc(byte[] data); public delegate void DiagRecDataHandleFunc(byte[] data); public delegate void UDSUpdateSendFunc(); public delegate void CanReadMessageDelegate(UInt32 id, byte[] data, int len); public delegate void ReadDelegateHandler(); public partial class uds_tools : Form { //CAN设备 CanDevice CanDeviceObj; PcanDevice PcanDeviceObj; ToSunDevice ToSumDeviceObj; TooMossDevice TooMossDeviceObj; ECanDevice GCanDeviceObj; ZLGCanDevice ZLGCanDeviceObj; UDSInfo UDSInfo; //功能寻址和物理寻址切换 public static byte CANIF_FUC_ON_Flag = 0; //升级数据CRC校验值 public static uint CRCValue = 0; /*发送帧类型*/ public int SendMsg_Len = 0;/*发送帧的长度*/ public byte[] SendBuff;/*发送帧的数据buff*/ public short BuffOffset = 0;/*发送数组偏移量*/ public byte CF_SN = 0x00;/*连续帧 SN*/ //报文log private StringBuilder MessagesLog; //打印报文的线程 private Thread PrintfMessageLogThread; //锁 private Object PrintfMessageLogLockObj; public static byte BlockIndex = 0x01;/*下载块的下标*/ public static byte UpdataFileFlag = 0;/*升级文件标志位区别下载文件*/ public static byte UpdataFlag = 0;/*升级数据发送完成标志*/ public static int FileOffset = 0;/*升级数组偏移量*/ public static string str_test = ""; //private EntrySecurityStatus EntrySecurityFlag = EntrySecurityStatus.Idle; private EntrySecurityStatus EntrySecurityFlag = EntrySecurityStatus.Idle; public static byte ReadDiaData = 0; byte[] diagData = new byte[40]; public string srShowVer = ""; /*安全算法种子*/ public static byte[] RecvSeed = new byte[16]; public byte[] FlashDataBuff; //flashdriver数据 public byte[] AppDataBuff; //App文件数据 public byte[] UIDataBuff; //UI文件数据 public byte[] RectifyDataBuff; //矫正文件数据 // public static byte[] FlashDriveUpdateStartAddr = new byte[4]; public static byte[] FlashDriveUpdateDataSize = new byte[4]; public static byte[] UIFlashDriveUpdateStartAddr = new byte[4]; public static byte[] AppUpdateStartAddr = new byte[4]; public static byte[] AppUpdateDataSize = new byte[4]; public static byte[] UIUpdateStartAddr = new byte[4]; public static byte[] UIUpdateDataSize = new byte[4]; public static byte[] RectifyUpdateStartAddr = new byte[4]; public static byte[] RectifyUpdateDataSize = new byte[4]; //升级文件的类型 public static UpdateFileType UpdateFileType = new UpdateFileType(); public static uint timeEscape = 0; public static uint FlashCheckSum = 0; public static uint AppCheckSum = 0; public static uint UiCheckSum = 0; public static uint RectifyCheckSum = 0; public static int UpdateFileTotalBytes = 0; public static int UpdateFileSendBytes = 0; //升级接收表驱动 public Dictionary UDSReceivedTable = new Dictionary(); //自诊断故障码对应文字说明表 public Dictionary selfDiagFaultType; List CanMessageSendTable; public uds_tools() { InitializeComponent(); this.StartPosition = FormStartPosition.CenterScreen; //创建CAN设备 CanDeviceObj = new CanDevice(); PcanDeviceObj = new PcanDevice(); ToSumDeviceObj = new ToSunDevice(); TooMossDeviceObj = new TooMossDevice(); GCanDeviceObj = new ECanDevice(); ZLGCanDeviceObj = new ZLGCanDevice(); UDSInfo = new UDSInfo(); //报文log MessagesLog = new StringBuilder(); //锁 PrintfMessageLogLockObj = new Object(); //打印报文线程 PrintfMessageLogThread = new Thread(new ThreadStart(PrintfMessageLog)); PrintfMessageLogThread.Start(); CanMessageSendTable = new List(); cbbDeviceType.SelectedIndex = 2; // 默认选择GC CAN cbbIdFilterSelect.SelectedIndex = 1; cbbCarType.SelectedIndex = 0; //诊断服务接收表初始化 DiagReceivedTableInit(); //升级配置参数初始化 UpdateConfigParamsInit(); //诊断参数初始化 DiagParamsInit(); } private void btClrDia_Load(object sender, EventArgs e) { rbtnAppSelect.Checked = true; ckbIsCycleReceive.Checked = true; ckbIsEventReceive.Checked = false; } private void CanToolForm_FormClosed(object sender, FormClosedEventArgs e) { //关闭打印线程 PrintfMessageLogThread.Abort(); } /*显示否定响应信息*/ private void NegativeResponeseDisplay(byte[] data) { bool isPrintf = true; string str = ""; switch (data[2]) { case 0x10: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:一般性拒绝\n"; break; case 0x11: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:服务不支持\n"; break; case 0x12: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:子功能不支持\n"; break; case 0x13: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:报文长度错误\n"; break; case 0x14: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:应答太长\n"; break; case 0x22: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:条件不正确\n"; break; case 0x24: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:请求次序错误\n"; break; case 0x25: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:子网部件无响应\n"; break; case 0x31: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:请求超出范围\n"; break; case 0x33: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:安全访问未通过\n"; break; case 0x35: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:密钥无效\n"; break; case 0x36: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:超过最大允许尝试次数\n"; break; case 0x37: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:要求的延时未结束\n"; break; case 0x70: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:上传/下载不能接受\n"; break; case 0x71: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:数据传输暂停\n"; break; case 0x72: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:一般性编程失败\n"; break; case 0x73: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:错误的序列模块计数\n"; break; case 0x78: //byte[] temp = new byte[2]{0x3e, 0x80}; //UDSInfo.SendPackage(temp, temp.Length, false); isPrintf = false; break; case 0x7E: str = data[1].ToString("x") + " " + data[3].ToString("x") + " 否定响应:当前会话下子功能不支持\n"; break; case 0x7f: str = data[2].ToString("x") + " " + data[3].ToString("x") + " 否定响应:当前会话下服务不支持\n"; break; default: isPrintf = false; break; } if (isPrintf) { rtxtLog.AppendText(str); } } /* //选择CAN波特率 private void cbbBaudrates_SelectedIndexChanged(object sender, EventArgs e) { // Saves the current selected baudrate register code switch (cbbBaudrates.SelectedIndex) { case 0: m_Baudrate = TPCANBaudrate.PCAN_BAUD_1M; break; case 1: m_Baudrate = TPCANBaudrate.PCAN_BAUD_800K; break; case 2: m_Baudrate = TPCANBaudrate.PCAN_BAUD_500K; break; case 3: m_Baudrate = TPCANBaudrate.PCAN_BAUD_250K; break; case 4: m_Baudrate = TPCANBaudrate.PCAN_BAUD_125K; break; case 5: m_Baudrate = TPCANBaudrate.PCAN_BAUD_100K; break; case 6: m_Baudrate = TPCANBaudrate.PCAN_BAUD_95K; break; case 7: m_Baudrate = TPCANBaudrate.PCAN_BAUD_83K; break; case 8: m_Baudrate = TPCANBaudrate.PCAN_BAUD_50K; break; case 9: m_Baudrate = TPCANBaudrate.PCAN_BAUD_47K; break; case 10: m_Baudrate = TPCANBaudrate.PCAN_BAUD_33K; break; case 11: m_Baudrate = TPCANBaudrate.PCAN_BAUD_20K; break; case 12: m_Baudrate = TPCANBaudrate.PCAN_BAUD_10K; break; case 13: m_Baudrate = TPCANBaudrate.PCAN_BAUD_5K; break; } } private void SetConnectionStatus(bool bConnected) { btnInit.Enabled = !bConnected; cbbDeviceType.Enabled = !bConnected; cbbBaudrates.Enabled = !bConnected; if (!bConnected) cbbChannel_SelectedIndexChanged(this, new EventArgs()); } */ //CAN设备发送报文 private void CanDeviceSendMessage(UInt32 id, byte[] data, int len, bool isFd) { if (false == isFd) { CanDeviceObj.CanSendMessage(id, data, len); } else { CanDeviceObj.CanFdSendMessage(id, data, len); } } //委托给UDS的函数 private void UdsSendMessage(UInt32 id, byte[] data, int len) { CanDeviceSendMessage(id, data, len, this.ckbIsCanFd.Checked); PrintfMessageLog("TX", id, data, len); } //CAN设备初始化 private int CanDeviceInit() { string retInfo; UInt32 idfilterStart; UInt32 idfilterEnd; try { idfilterStart = Convert.ToUInt32(txtIdFilterStrat.Text, 16); idfilterEnd = Convert.ToUInt32(txtIdFilterEnd.Text, 16); } catch { MessageBox.Show("ID过滤器值输入有误", "提示"); return 1; } //区分不同的CAN设备 if ("PCAN" == cbbDeviceType.Text) { CanDeviceObj = PcanDeviceObj; } else if ("TOSUN" == cbbDeviceType.Text) { CanDeviceObj = ToSumDeviceObj; } else if ("TOOMOSS" == cbbDeviceType.Text) { CanDeviceObj = TooMossDeviceObj; } else if("GC_USBCAN_II" == cbbDeviceType.Text) // 广成CAN { CanDeviceObj = GCanDeviceObj; } else if("ZLG_USBCAN-II" == cbbDeviceType.Text) // ZLG_USBCAN-II { CanDeviceObj = ZLGCanDeviceObj; } else { MessageBox.Show("设备选择错误", "提示"); return 1; } //区分标准CAN和CANFD if (false == ckbIsCanFd.Checked) { //CAN初始化 retInfo = CanDeviceObj.CanInit(); //设置ID过滤器 CanDeviceObj.CanSetFilter(idfilterStart, idfilterEnd); //是否开启事件接收 if ((true == ckbIsEventReceive.Checked) && ("OK" == retInfo) ) { //注册接受报文事件 CanDeviceObj.RegisterCanReadEvent(CanAnalysisData); //使能接收事件 CanDeviceObj.CanReceiveEventEnable(); } } else { //CAN初始化 retInfo = CanDeviceObj.CanFdInit(); //设置ID过滤器 CanDeviceObj.CanFdSetFilter(idfilterStart, idfilterEnd); //是否开启事件接收 if ((true == ckbIsEventReceive.Checked) && ("OK" == retInfo) ) { //注册接受报文事件 CanDeviceObj.RegisterCanReadEvent(CanAnalysisData); //使能接收事件 CanDeviceObj.CanFdReceiveEventEnable(); } } if ("OK" == retInfo) { return 0; } else { MessageBox.Show(retInfo, "连接失败"); return 1; } } //CAN设备逆初始化 private int CanDeviceDeInit() { string ret; //区分标准CAN和CANFD if (false == ckbIsCanFd.Checked) { ret = CanDeviceObj.CanDeInit(); } else { ret = CanDeviceObj.CanFdDeInit(); } if ("OK" == ret) { //区分标准CAN和CANFD if (false == ckbIsCanFd.Checked) { //失能接收事件 CanDeviceObj.CanReceiveEventDisable(); } else { //失能接收事件 CanDeviceObj.CanFdReceiveEventDisable(); } //删除事件 CanDeviceObj.UnregisterCanReadEventAll(); return 0; } else { MessageBox.Show(ret, "断开连接失败"); return 1; } } //连接CAN设备时 需要一些控件为使能或失能的状态 private void ConnectControlEnable() { ckbIsCanFd.Enabled = false; cbbDeviceType.Enabled = false; btnConnect.Enabled = false; cbbCarType.Enabled = false; txtIdFilterStrat.Enabled = false; txtIdFilterEnd.Enabled = false; //周期接收选项 ckbIsCycleReceive.Enabled = false; //事件接收选项 ckbIsEventReceive.Enabled = false; //使能10ms定时器解析接收报文 timerReadMsg.Enabled = true; timerSendMsg.Enabled = true; timerUDS.Enabled = true; btnRelease.Enabled = true; cbbCarType.Enabled = false; } //断开CAN设备时 需要一些控件为使能或失能的状态 private void UnconnectControlEnable() { ckbIsCanFd.Enabled = true; timerReadMsg.Enabled = false; btnRelease.Enabled = false; btnConnect.Enabled = true; cbbDeviceType.Enabled = true; cbbCarType.Enabled = true; //周期接收选项 ckbIsCycleReceive.Enabled = true; //事件接收选项 ckbIsEventReceive.Enabled = true; txtIdFilterStrat.Enabled = true; txtIdFilterEnd.Enabled = true; } private void CarTypeConfig() { switch (cbbCarType.Text) { case "鸿日": UpdateConfigParamsNow = UpdateConfigParamsHR; ReadVersionConfigNow = ReadVersionConfigHR; break; case "比亚迪": UpdateConfigParamsNow = UpdateConfigParamsBYD; ReadVersionConfigNow = ReadVersionConfigBYD; break; default: UpdateConfigParamsNow = UpdateConfigParamsHR; ReadVersionConfigNow = ReadVersionConfigHR; break; } } //连接 private void btnConnect_Click(object sender, EventArgs e) { //CAN设备初始化 if (0 == CanDeviceInit()) { rtxtLog.AppendText("连接设备成功\n"); ConnectControlEnable(); } else { rtxtLog.AppendText("连接设备失败\n"); return; } //根据选择的车厂进行配置 CarTypeConfig(); //加载读取版本号的表 LoadVersionToView(); ckbIsCrcLsb.Checked = this.UpdateConfigParamsNow.CrcIsLsb; //UDS设置ID UDSInfo.SetId(this.UpdateConfigParamsNow.CANPhyDevRxId, this.UpdateConfigParamsNow.CANPhyDevTxId, this.UpdateConfigParamsNow.CANFuncDevRxId); UDSInfo.SetCANDL(8); // 设置每包数据最长多少个字节 //UDS注册发送和接受事件 UDSInfo.UnregisterReceivedPackageEventAll(); UDSInfo.RegisterReceivedPackageEvent(UDSReceivedPackage); //UDS注册发送报文 UDSInfo.UnregisterSendMessageEventAll(); UDSInfo.RegisterSendMessageEvent(UdsSendMessage); SendBuff = new byte[this.UpdateConfigParamsNow.UDSMsgLengthMax + 4]; //cobCarType.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames()); } //断开连接 private void btnRelease_Click(object sender, EventArgs e) { if (0 == CanDeviceDeInit()) { UnconnectControlEnable(); } else { } } //加载可以读取的版本号到界面显示 private void LoadVersionToView() { ListViewItem listViewItem; foreach(VersionParams versionParams in ReadVersionConfigNow.VersionParamsTable) { listViewItem = new ListViewItem(); //版本号说明 listViewItem.Text = versionParams.VersionComment; listViewItem.SubItems.Add(""); } } //打印报文Log 将打印的数据添加进缓存区 private void PrintfMessageLog(string dir, UInt32 id, byte[] data, int len) { //string str; StringBuilder str; bool isPrintf = false; if ((0 != id) && (1 != id) && (0 != cbbIdFilterSelect.SelectedIndex) ) { //显示所有报文 if (1 == cbbIdFilterSelect.SelectedIndex) { isPrintf = true; } //为诊断的ID else if ((id == this.UpdateConfigParamsNow.CANPhyDevTxId) || (id == this.UpdateConfigParamsNow.CANPhyDevRxId) || (id == this.UpdateConfigParamsNow.CANFuncDevRxId) ) { //显示诊断报文 if (2 == cbbIdFilterSelect.SelectedIndex) { isPrintf = true; } } //显示非诊断ID else if (3 == cbbIdFilterSelect.SelectedIndex) { isPrintf = true; } } //需要打印报文 if (isPrintf) { str = new StringBuilder(); str.Append(string.Format("{0} {1} 0x{2:X3} ", GetTimeStamp(), dir, id)); for (int i = 0; i < len; i++) { str.Append(string.Format("0x{0:X2} ", data[i])); } str.Append("\r\n"); /* str = string.Format("{0} {1} 0x{2:X3} 0x{3:X2} 0x{4:X2} 0x{5:X2} 0x{6:X2} 0x{7:X2} 0x{8:X2} 0x{9:X2} 0x{10:X2} \r\n", GetTimeStamp(), dir, id, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); */ //锁 在另一个线程取链表的值打印 lock (PrintfMessageLogLockObj) { MessagesLog.Append(str.ToString()); } } } //将缓存区的数据打印到控件的线程 private void PrintfMessageLog() { bool IsPrintf = false; string Messagelog = ""; string[] MessagelogArr = new string[0]; while (true) { //锁 在另一个线程中添加报文文本 lock (PrintfMessageLogLockObj) { if (0 != MessagesLog.Length) { Messagelog = MessagesLog.ToString(); MessagesLog.Clear(); IsPrintf = true; } } //是否需要打印 if (IsPrintf) { IsPrintf = false; Invoke((EventHandler)delegate { rtxtMessagesLog.AppendText(Messagelog); //rtxtMessagesLog.Focus(); }); } Thread.Sleep(100); } } //编辑好后添加发送报文 private void AddSendMessage(UInt32 id, byte[] data, int len) { StringBuilder strBuilder = new StringBuilder(); ListViewItem listViewItem = new ListViewItem(); //界面增加 listViewItem.Text = string.Format("{0:X}", id); listViewItem.SubItems.Add(len.ToString()); for (int i = 0; i < len; i++) { strBuilder.Append(string.Format("{0:X2} ", data[i])); } listViewItem.SubItems.Add(strBuilder.ToString()); lsvSendMessagesTable.Items.Add(listViewItem); //实际使用的数据增加 CanMessageSendTable.Add(new CanMessage(id, data, len, true)); } //编辑发送报文 private void EditSendMessage(UInt32 id, byte[] data, int len) { StringBuilder strBuilder = new StringBuilder(); ListViewItem listViewItem = new ListViewItem(); int index; if (lsvSendMessagesTable.SelectedItems.Count != 0) { index = lsvSendMessagesTable.SelectedItems[0].Index; //界面修改 listViewItem.Text = string.Format("{0:X}", id); listViewItem.SubItems.Add(len.ToString()); for (int i = 0; i < len; i++) { strBuilder.Append(string.Format("{0:X2} ", data[i])); } listViewItem.SubItems.Add(strBuilder.ToString()); lsvSendMessagesTable.Items[index] = listViewItem; //实际使用的数据修改 CanMessageSendTable[index] = new CanMessage(id, data, len, true); } } //打开编辑界面增加发送报文 private void tsmiEditMessage_Click(object sender, EventArgs e) { MessageConfigForm form; CanMessage msg; int index; if (lsvSendMessagesTable.SelectedItems.Count != 0) { index = lsvSendMessagesTable.SelectedItems[0].Index; //获取发送报文表中的数据 msg = CanMessageSendTable[index]; //传入给编辑窗口 form = new MessageConfigForm(msg.Id, msg.Data, msg.Len); //添加事件 form.MessageReturn = EditSendMessage; form.ShowDialog(); } } //打开编辑界面编辑发送报文 private void tsmiAddMessage_Click(object sender, EventArgs e) { MessageConfigForm form = new MessageConfigForm(); form.MessageReturn = AddSendMessage; form.ShowDialog(); } //在发送报文列表中删除选中的报文 private void tsmiDeleteMessage_Click(object sender, EventArgs e) { int index; if (lsvSendMessagesTable.SelectedItems.Count != 0) { index = lsvSendMessagesTable.SelectedItems[0].Index; //UI显示删除 lsvSendMessagesTable.Items.RemoveAt(index); //实际使用的数据删除 CanMessageSendTable.RemoveAt(index); } } //双击发送报文列表中的报文发送 private void lsvSendMessagesTable_DoubleClick(object sender, EventArgs e) { CanMessage msg; int index; if (lsvSendMessagesTable.SelectedItems.Count != 0) { index = lsvSendMessagesTable.SelectedItems[0].Index; msg = CanMessageSendTable[index]; CanDeviceSendMessage(msg.Id, msg.Data, msg.Len, ckbIsCanFd.Checked); //打印报文 PrintfMessageLog("TX", msg.Id, msg.Data, msg.Len); } } //保存报文Log的数据 private void SaveMessagesLog() { string txtFile = ""; DateTime dt = DateTime.Now; txtFile = System.Environment.CurrentDirectory + "\\" + dt.ToString("yyyy-MM-dd HH-mm-ss ") + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + "Log" + ".txt"; System.IO.StreamWriter sw = new System.IO.StreamWriter(txtFile, true, Encoding.Unicode); sw.Write(rtxtMessagesLog.Text); sw.Flush(); sw.Close(); MessageBox.Show(txtFile + "文件保存成功!", "保存文件"); } //清除报文Log private void ToolStripMenuItem_Click(object sender, EventArgs e) { rtxtMessagesLog.Clear(); } //保存报文 private void SaveLogToolStripMenuItem_Click(object sender, EventArgs e) { SaveMessagesLog(); } //查看全部报文 private void tsmiLookAllMessagesLog_Click(object sender, EventArgs e) { cbbIdFilterSelect.SelectedIndex = 1; } //查看诊断报文 private void tsmiLookDiagMessagesLog_Click(object sender, EventArgs e) { cbbIdFilterSelect.SelectedIndex = 2; } //查看应用报文 private void tsmiLookAppMessagesLog_Click(object sender, EventArgs e) { cbbIdFilterSelect.SelectedIndex = 3; } //暂停所有报文 private void tsmiMessagesLogStop_Click(object sender, EventArgs e) { cbbIdFilterSelect.SelectedIndex = 0; } //清除log private void tsmiLogClear_Click(object sender, EventArgs e) { rtxtLog.Clear(); } private void CanAnalysisData(UInt32 id, byte[] data, int len) { if (this.InvokeRequired) { //CanReadMessageDelegate canReadDelegate = new CanReadMessageDelegate(ReceivedProcessMessage); CanReadMessageDelegate canReadDelegate = new CanReadMessageDelegate(ReceivedMessage); try { //this.Invoke(canReadDelegate, new object[] { id, data }); this.Invoke(canReadDelegate, new object[] { id, data ,len}); } catch { } } else { ReceivedMessage(id, data, len); //ReceivedProcessMessage(id, data); } } private void ReadMessages() { UInt32 id = 0; byte[] data = new byte[64]; int len = 0; if (false == ckbIsCanFd.Checked) { while (true == CanDeviceObj.CanReadMessage(ref id, data, ref len)) { CanAnalysisData(id, data, len); } } else { while (true == CanDeviceObj.CanFdReadMessage(ref id, data, ref len)) { CanAnalysisData(id, data, len); } } } private void DiagVersionDisplay(byte[] data, int len) { int index; string versionComment; string version; UInt16 did; byte[] paramsArr; if (len < 3) { return; } paramsArr = new byte[len - 3]; //获取did did = (UInt16)(data[1] << 8 | data[2]); Array.Copy(data, 3, paramsArr, 0, len - 3); //查找对应的项 index = ReadVersionConfigNow.IndexOf(data[0], did, paramsArr); versionComment = ReadVersionConfigNow.GetVersionComment(index); //获取信息 version = ReadVersionConfigNow.AnalysisVersion(index, data, (UInt32)len); if (version != "") { //打印到log rtxtLog.AppendText(string.Format("{0}:{1}\n", versionComment, version)); } } private void UdsOtherInfo(byte[] data, int len) { //单帧 if (len <= 7) { switch (data[0]) { case 0x6f: break; case 0x62: switch (data[1]) { case 0x0E: switch (data[2]) { case 0x21:// 22 0E 21 break; case 0x39:// 22 0e 39 break; default: break; } break; default: break; } break; case 0x6E: switch (data[1]) { case 0x0E: switch (data[2]) { case 0x05:// 2E 0E 05 01 break; default: break; } break; case 0xF1: switch (data[2]) { case 0x8C:// 2E F1 8C break; default: break; } break; default: break; } break; default: break; } } else { switch (data[0]) { case 0x62: switch (data[1]) { case 0x0E: switch (data[2]) { case 0x00:// 22 0E 00 break; case 0x02: // 22 0E 02 break; case 0x16: // 22 0E 16 break; case 0x17: // 22 0E 17 break; case 0x18: // 22 0E 18 break; case 0x20:// 22 0E 20 break; case 0x38:// 22 0e 38 break; default: break; } break; case 0xF0: switch (data[2]) { case 0x10:// 22 F0 10 break; default: break; } break; case 0xF1: switch (data[2]) { case 0x80:// 22 F1 80 if (len == 13) { } break; case 0x81:// 22 F1 81 if (len == 13) { } break; case 0x82:// 22 F1 82 if (len == 13) { } break; case 0x83:// 22 F1 83 if (len == 13) { textBoxDidF183.Text = Encoding.Default.GetString(data, 3, len - 3); rtxtLog.AppendText("boot版本号:" + textBoxDidF183.Text + "\n"); } break; case 0x84:// 22 F1 84 if (len == 13) { } break; case 0x87:// 22 F1 87 if (len == 18) { textBoxDidF187.Text = Encoding.Default.GetString(data, 3, len - 3); rtxtLog.AppendText("零件号:" + textBoxDidF187.Text + "\n"); } break; case 0x88:// 22 F1 88 if (len == 13) { } break; case 0x8A:// 22 F1 8A if (len == 13) { } break; case 0x8B:// 22 F1 8B if (len == 13) { } break; case 0x8C:// 22 F1 8C if (len == 13) { } break; case 0x90:// 22 F1 90 if (len == 13) { } break; case 0x93:// 22 F1 93 if (len == 13) { textBoxDidF193.Text = Encoding.Default.GetString(data, 3, len - 3); rtxtLog.AppendText("硬件版本号:" + textBoxDidF193.Text + "\n"); } break; case 0x94:// 22 F1 94 if (len == 13) { } break; case 0x95:// 22 F1 95 if (len == 13) { } break; case 0x96:// 22 F1 96 if (len == 13) { } break; case 0x97:// 22 F1 97 if (len == 13) { } break; default: break; } break; default: break; } break; default: break; } } } //UDS报文接收到一个包后处理 private void UDSReceivedPackage(byte[] data, int len) { //诊断各服务处理 if (true == UDSReceivedTable.ContainsKey(data[0])) { if (UpdateConfigParams.IsUpdate) { if(data[0] == 0x7f) { UDSReceivedTable[data[0]](data); } } else { UDSReceivedTable[data[0]](data); } } UpdateConfigParamsNow.UpdateReply(data, (UInt32)len); //版本号显示 DiagVersionDisplay(data, len); // 其他信息处理 UdsOtherInfo(data, len); } private void ReceivedMessage(UInt32 id, byte[] data, int len) { //打印报文 PrintfMessageLog("RX", id, data, len); //将报文插入到UDS模块解析 当收到一个包后会调用相关的事件 具体调用的函数 UDSInfo.InsertReceiveData(id, data); } /*10 03 进入扩展会话*/ private void GotoExtendeSession(byte se) { byte[] data = new byte[2]; data[0] = 0x10; data[1] = se; //SendFrameType = UDSFrameType.SingleFrame; UDSInfo.SendPackage(data, data.Length, false); } /*扩展会话*/ private void btExtn_Click(object sender, EventArgs e) { GotoExtendeSession(0x03); } /*编程会话*/ private void btProgram_Click(object sender, EventArgs e) { GotoExtendeSession(0x02); } /*默认会话*/ private void btDefault_Click(object sender, EventArgs e) { GotoExtendeSession(0x01); } private void btnECUReset_Click(object sender, EventArgs e) { ECUHardReset(1); } //10ms定时器读取接收报文 已替换为事件触发暂时留住 private void timerReadMsg_Tick(object sender, EventArgs e) { if (true == ckbIsCycleReceive.Checked) { ReadMessages(); } } public string GetTimeStamp() { DateTime dt = DateTime.Now; return dt.ToString("hh:mm:ss fff"); } //安全访问等级1 private void btlev1_Click(object sender, EventArgs e) { this.EntrySecurityFlag = EntrySecurityStatus.RequestSeedLevel1; } private void btnResetSecurityKey_Click(object sender, EventArgs e) { int len = 14; SendMsg_Len = len; SendBuff[0] = 0x31; SendBuff[1] = 0x01; SendBuff[2] = 0xAA; SendBuff[3] = 0x55; SendBuff[4] = 0x48; SendBuff[5] = 0x41; SendBuff[6] = 0x2D; SendBuff[7] = 0x54; SendBuff[8] = 0x43; SendBuff[9] = 0x41; SendBuff[10] = 0x2D; SendBuff[11] = 0x35; SendBuff[12] = 0x36; SendBuff[13] = 0x31; UDSInfo.SendPackage(SendBuff, len, false); //UDSInfo.SendPackage(SendBuff, len, false); rtxtLog.AppendText("重置安全密钥\n"); } private void timerSendMsg_Tick(object sender, EventArgs e) { switch (EntrySecurityFlag) { case EntrySecurityStatus.RequestSeedLevel1: { RequestSeedLevel1(); break; } case EntrySecurityStatus.SendkeyLevel1: { SendKeyLevel1(); break; } case EntrySecurityStatus.RequestSeedLevel2: { RequestSeedLevel2(); break; } case EntrySecurityStatus.SendkeyLevel2: { SendKeyLevel2(); break; } case EntrySecurityStatus.RequestSeedLevel3: { RequestSeedLevel3(); break; } case EntrySecurityStatus.SendkeyLevel3: { SendKeyLevel3(); break; } case EntrySecurityStatus.RequestSeedLevel4: { RequestSeedLevel4(); break; } case EntrySecurityStatus.SendkeyLevel4: { SendKeyLevel4(); break; } default: break; } if ((EntrySecurityFlag != EntrySecurityStatus.Idle) && (EntrySecurityFlag != EntrySecurityStatus.Unlock) ) { EntrySecurityFlag = EntrySecurityStatus.WaitReply; } } /*清除故障码*/ private void btClrDial_Click(object sender, EventArgs e) { byte[] data = new byte[8]; byte len = 4; data[0] = 0x14; data[1] = 0xff; data[2] = 0xff; data[3] = 0xff; UDSInfo.SendPackage(data, len, false); } void SendComSet(byte en) { byte[] data = new byte[3]; data[0] = 0x28; data[1] = en; data[2] = 0x01; UDSInfo.SendPackage(data, data.Length, false); //UDSInfo.SendPackage(data, len, false); } /*失能应用报文的发送和接收*/ private void btComOff_Click(object sender, EventArgs e) { SendComSet(3); } /*使能应用报文的发送和接收*/ private void btComOn_Click(object sender, EventArgs e) { SendComSet(0); } public uint GetCRC16(byte[] msg) { uint mask = 0x1021; int size = msg.Length; uint crc = 0xFFFF; int tmp; int i, j; for (i = 0; i < size; i++) { tmp = msg[i] << 8; for (j = 0; j < 8; j++) { if (((crc ^ tmp) & 0x8000u) == 0x8000u) { crc = (crc << 1) ^ mask; } else { crc <<= 1; } tmp <<= 1; } } return crc; } private void UpdateTimerSet1s() { timerFlashMain.Interval = 1000; } private void UpdateTimerSet20ms() { timerFlashMain.Interval = 20; } private void timer1Calib_Tick(object sender, EventArgs e) { UpdateConfigParamsNow.UpdateSendLoop(); } private void timer500ms_Tick(object sender, EventArgs e) { timeEscape++; textBoxTimeEscape.Text = timeEscape.ToString() + "秒"; } private void timerUDS_Tick(object sender, EventArgs e) { byte[] data = new byte[64]; if ((EntrySecurityStatus.Unlock == EntrySecurityFlag) || (UpdateConfigParams.IsUpdate) ) { data[0] = 0x02; data[1] = 0x3E; data[2] = 0x80; CanDeviceSendMessage(UpdateConfigParamsNow.CANFuncDevRxId, data, 8, ckbIsCanFd.Checked); //UDSInfo.SendPackage(data, data.Length, false); } } private void GetUpdateFileInfo(string fileName, int dataOffset, out byte[] outData, byte[] outStartAddr, uint binStartAddr,byte[] outSize, ref uint crcValue, bool isCrcLsb) { byte[] fileData; //判断bin还是s19 if ((-1 != fileName.IndexOf(".bin")) || (-1 != fileName.IndexOf(".Bin")) ) { //读取文件流 FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read); BinaryReader binFile = new BinaryReader(file); //减去头偏移大小 fileData = new byte[file.Length - dataOffset]; //去除头偏移 binFile.ReadBytes(dataOffset); //读取数据 binFile.Read(fileData, 0, fileData.Length); //拷贝到实际使用的数组 outData = new byte[fileData.Length]; fileData.CopyTo(outData, 0); //起始地址 outStartAddr[0] = (byte)((binStartAddr >> 24) & 0xff); outStartAddr[1] = (byte)((binStartAddr >> 16) & 0xff); outStartAddr[2] = (byte)((binStartAddr >> 8) & 0xff); outStartAddr[3] = (byte)((binStartAddr >> 0) & 0xff); //UIFlashDrive起始地址 /*UIFlashDriveUpdateStartAddr[0] = (byte)((this.UpdateConfigParamsNow.UIFlashDriveUpdateStartAddr >> 24) & 0xff); UIFlashDriveUpdateStartAddr[1] = (byte)((this.UpdateConfigParamsNow.UIFlashDriveUpdateStartAddr >> 16) & 0xff); UIFlashDriveUpdateStartAddr[2] = (byte)((this.UpdateConfigParamsNow.UIFlashDriveUpdateStartAddr >> 8) & 0xff); UIFlashDriveUpdateStartAddr[3] = (byte)((this.UpdateConfigParamsNow.UIFlashDriveUpdateStartAddr >> 0) & 0xff);*/ } else { //读取S19文件 S19FileStream S19File = new S19FileStream(fileName); int size = S19File.Size; int startAddr = S19File.StartAddr; //起始地址 outStartAddr[0] = (byte)((startAddr >> 24) & 0xff); outStartAddr[1] = (byte)((startAddr >> 16) & 0xff); outStartAddr[2] = (byte)((startAddr >> 8) & 0xff); outStartAddr[3] = (byte)((startAddr >> 0) & 0xff); /* UIFlashDriveUpdateStartAddr[0] = (byte)((startAddr >> 24) & 0xff); UIFlashDriveUpdateStartAddr[1] = (byte)((startAddr >> 16) & 0xff); UIFlashDriveUpdateStartAddr[2] = (byte)((startAddr >> 8) & 0xff); UIFlashDriveUpdateStartAddr[3] = (byte)((startAddr >> 0) & 0xff);*/ //拷贝到实际使用的数组 fileData = S19File.ToBinByteArray(size); //减去头偏移大小 outData = new byte[fileData.Length - dataOffset]; //拷贝到实际使用的数组 Array.Copy(fileData, dataOffset, outData, 0, outData.Length); } //获取CRC32校验和 CRC32Cls crc32 = new CRC32Cls(); #if true if (isCrcLsb) { crc32.SetLsb(); } else { crc32.SetMsb(); } #else if (true == ckbIsOldBott.Checked) { crc.SetLsb(); } else { crc.SetMsb(); } #endif crc32.Bzip2_Init(); crc32.Bzip2_Start(); crc32._Lbm_CalculateHashByDct(outData, (uint)outData.Length); crcValue = crc32.Bzip2_Verify(); //大小 outSize[0] = (byte)((outData.Length >> 24) & 0xff); outSize[1] = (byte)((outData.Length >> 16) & 0xff); outSize[2] = (byte)((outData.Length >> 8) & 0xff); outSize[3] = (byte)((outData.Length >> 0) & 0xff); } /*选择FlashDriver文件*/ private void btFlashDriver_Click(object sender, EventArgs e) { OpenFileDialog FlashDriveFileSwitchDialog = new OpenFileDialog(); //exe打开路径 FlashDriveFileSwitchDialog.InitialDirectory = System.Environment.CurrentDirectory; FlashDriveFileSwitchDialog.Title = "选择FlashDrive文件"; //FlashDriveFileSwitchDialog.Filter = "S19 files|*.s19;*.S19|BIN files|*.Bin;*.bin;"; FlashDriveFileSwitchDialog.Filter = "File|*.s19;*.S19;*.Bin;*.bin;"; if (FlashDriveFileSwitchDialog.ShowDialog() != DialogResult.OK) { textBoxFlash.Text = ""; return; } else { textBoxFlash.Text = FlashDriveFileSwitchDialog.FileName;//选中文件名 //获取升级文件信息 GetUpdateFileInfo(FlashDriveFileSwitchDialog.FileName, UpdateConfigParamsNow.FlashDriveFileOffset, out FlashDataBuff, FlashDriveUpdateStartAddr, UpdateConfigParamsNow.FlashDriveUpdateStartAddr, FlashDriveUpdateDataSize, ref FlashCheckSum, ckbIsCrcLsb.Checked); FlashDriveUpdateStartAddr.CopyTo(UIFlashDriveUpdateStartAddr, 0); rtxtLog.AppendText(string.Format("FlashDriver文件CRC32为0x{0:X}\n", FlashCheckSum)); } } /*选择APP文件*/ private void btAPP_Click(object sender, EventArgs e) { OpenFileDialog AppFileSwitchDialog = new OpenFileDialog(); //exe的路径 AppFileSwitchDialog.InitialDirectory = System.Environment.CurrentDirectory; AppFileSwitchDialog.Title = "选择APP升级文件"; //AppFileSwitchDialog.Filter = "S19 files|*.s19;*.S19|BIN files|*.Bin;*.bin;"; AppFileSwitchDialog.Filter = "File|*.s19;*.S19;*.Bin;*.bin;"; if (AppFileSwitchDialog.ShowDialog() != DialogResult.OK) { textBoxApp.Text = ""; return; } else { textBoxApp.Text = AppFileSwitchDialog.FileName;//选中文件名 //获取升级文件信息 GetUpdateFileInfo(AppFileSwitchDialog.FileName, UpdateConfigParamsNow.AppFileOffset, out AppDataBuff, AppUpdateStartAddr, UpdateConfigParamsNow.AppUpdateStartAddr, AppUpdateDataSize, ref AppCheckSum, ckbIsCrcLsb.Checked); rtxtLog.AppendText(string.Format("APP文件CRC32为0x{0:X}\n", AppCheckSum)); } } private void btnUIUpdateFileSwitch_Click(object sender, EventArgs e) { OpenFileDialog UIFileSwitchDialog = new OpenFileDialog(); //exe的路径 UIFileSwitchDialog.InitialDirectory = System.Environment.CurrentDirectory; UIFileSwitchDialog.Title = "选择UI升级文件"; //UIFileSwitchDialog.Filter = "S19 files|*.s19;*.S19|BIN files|*.Bin;*.bin;"; UIFileSwitchDialog.Filter = "File|*.s19;*.S19;*.Bin;*.bin;"; if (UIFileSwitchDialog.ShowDialog() != DialogResult.OK) { txtUIUpdateFilePath.Text = ""; return; } else { txtUIUpdateFilePath.Text = UIFileSwitchDialog.FileName;//选中文件名 //获取升级文件信息 GetUpdateFileInfo(UIFileSwitchDialog.FileName, UpdateConfigParamsNow.UIFileOffset, out UIDataBuff, UIUpdateStartAddr, UpdateConfigParamsNow.UIUpdateStartAddr, UIUpdateDataSize, ref UiCheckSum, ckbIsCrcLsb.Checked); //rtxtLog.AppendText(string.Format("UI文件起始地址为0x{0:X} 大小为0x{1:X} CRC32为0x{2:X}", byte UIUpdateStartAddr)); rtxtLog.AppendText(string.Format("UI文件CRC32为0x{0:X}\n", UiCheckSum)); } } /*升级*/ private void btUpgrade_Click(object sender, EventArgs e) { UpdateFileSendBytes = 0; UpdateFileTotalBytes = 0; BlockIndex = 1; BuffOffset = 0; FileOffset = 0; if (textBoxFlash.Text == "") { MessageBox.Show("请选择FlashDriver文件"); btFlashDriver.Focus(); return; } else { //UpdateFileTotalBytes += (UInt32)FlashBuffer.Count; UpdateFileTotalBytes += FlashDataBuff.Length; } if(true == rbtnAppSelect.Checked) { UpdateFileType = UpdateFileType.App; if (textBoxApp.Text == "") { MessageBox.Show("请选择相应的APP升级文件"); btAPP.Focus(); return; } else { //UpdateFileTotalBytes += (UInt32)AppBuffer.Count; UpdateFileTotalBytes += AppDataBuff.Length; } } else if(true == rbtnUiSelect.Checked) { UpdateFileType = UpdateFileType.UI; if (txtUIUpdateFilePath.Text == "") { MessageBox.Show("请选择相应的UI升级文件"); btAPP.Focus(); return; } else { //UpdateFileTotalBytes += (UInt32)AppBuffer.Count; UpdateFileTotalBytes += UIDataBuff.Length; } } UpdateConfigParams.UpdateStepNum = 0; UpdateConfigParams.UpdateSendCmdFlag = true; UpdateConfigParams.IsUpdate = true; timerFlashMain.Enabled = true; this.progressBar1.Value = Convert.ToInt32(0); textBoxTimeEscape.Text = "0秒"; timeEscape = 0; timer1s.Enabled = true; EntrySecurityFlag = EntrySecurityStatus.Idle; } /*版本信息*/ private void btVersionInfo_Click(object sender, EventArgs e) { MessageBox.Show("版本号V0.001-20241113"); } private void btEnterEndofLineCaliMode_Click(object sender, EventArgs e) { } private void idStratTextBox_TextChanged(object sender, EventArgs e) { } private void UDSUpdateDownloadFlashDriver() { rtxtLog.AppendText("请求下载FlashDriver\n"); UpdataFileFlag = 1; if ((UpdateFileType.App == UpdateFileType) || (UpdateFileType.Rectify == UpdateFileType) ) { RequestDownload(FlashDriveUpdateStartAddr, FlashDriveUpdateDataSize); } else if (UpdateFileType.UI == UpdateFileType) { RequestDownload(UIFlashDriveUpdateStartAddr, FlashDriveUpdateDataSize); } } private void UDSUpdateEraseMemoryLen13() { rtxtLog.AppendText("擦除Flash\n"); if (UpdateFileType.App == UpdateFileType) { RequestEraseMemoryLen13(AppUpdateStartAddr, AppUpdateDataSize); } else if (UpdateFileType.UI == UpdateFileType) { RequestEraseMemoryLen13(UIUpdateStartAddr, UIUpdateDataSize); } else if (UpdateFileType.Rectify == UpdateFileType) { RequestEraseMemoryLen13(RectifyUpdateStartAddr, RectifyUpdateDataSize); } } private void UDSUpdateDownloadAppFile() { UpdataFileFlag = 2; if (UpdateFileType.App == UpdateFileType) { RequestDownload(AppUpdateStartAddr, AppUpdateDataSize); } else if (UpdateFileType.UI == UpdateFileType) { RequestDownload(UIUpdateStartAddr, UIUpdateDataSize); } else if (UpdateFileType.Rectify == UpdateFileType) { RequestDownload(RectifyUpdateStartAddr, RectifyUpdateDataSize); } } private void UDSUpdateTransferData() { if (1 == UpdataFileFlag)//区分升级文件为flash driver还是app { TransferData(ref FlashDataBuff, FlashDriveUpdateDataSize); } else if (2 == UpdataFileFlag)//区分升级文件为flash driver还是app { if (UpdateFileType.App == UpdateFileType) { TransferData(ref AppDataBuff, AppUpdateDataSize); } else if (UpdateFileType.UI == UpdateFileType) { TransferData(ref UIDataBuff, UIUpdateDataSize); } else if (UpdateFileType.Rectify == UpdateFileType) { TransferData(ref RectifyDataBuff, RectifyUpdateDataSize); } } } private void UDSUpdateFlashCheckSumLen4() { rtxtLog.AppendText("FlashDriver校验和\n"); RequestCheckSum(this.UpdateConfigParamsNow.FlashCheckMemoryParams); } private void UDSUpdateFlashCheckSumLen8() { rtxtLog.AppendText("FlashDriver校验和\n"); RequestCheckSum(this.UpdateConfigParamsNow.FlashCheckMemoryParams ,FlashCheckSum); } private void UDSUpdateFlashCheckSumCRC32() { rtxtLog.AppendText("FlashDriver校验和检测\n"); RequestCheckSumHR(this.UpdateConfigParamsNow.FlashCheckMemoryParams, FlashCheckSum); } private void UDSUpdateFlashCheckSumLen16() { rtxtLog.AppendText("FlashDriver校验和\n"); RequestCheckSum(this.UpdateConfigParamsNow.FlashCheckMemoryParams, FlashDriveUpdateStartAddr, FlashDriveUpdateDataSize, FlashCheckSum); } private void UDSUpdateAppCheckSumLen4() { rtxtLog.AppendText("App校验和\n"); RequestCheckSum(this.UpdateConfigParamsNow.AppCheckMemoryParams); } private void UDSUpdateAppCheckSumLen8() { uint checkSum; rtxtLog.AppendText("App校验和\n"); switch (UpdateFileType) { case UpdateFileType.App: { checkSum = AppCheckSum; break; } case UpdateFileType.UI: { checkSum = UiCheckSum; break; } case UpdateFileType.Rectify: { checkSum = RectifyCheckSum; break; } default: { checkSum = AppCheckSum; break; } } RequestCheckSum(this.UpdateConfigParamsNow.AppCheckMemoryParams, checkSum); } private void UDSUpdateAppCheckSumHR() { uint checkSum; rtxtLog.AppendText("App校验和\n"); switch (UpdateFileType) { case UpdateFileType.App: { checkSum = AppCheckSum; break; } case UpdateFileType.UI: { checkSum = UiCheckSum; break; } case UpdateFileType.Rectify: { checkSum = RectifyCheckSum; break; } default: { checkSum = AppCheckSum; break; } } RequestCheckSumHR(this.UpdateConfigParamsNow.AppCheckMemoryParams, checkSum); } private void UDSUpdateAppCheckSumLen16() { uint checkSum; byte[] startAddr; byte[] size; rtxtLog.AppendText("App校验和\n"); switch (UpdateFileType) { case UpdateFileType.App: { startAddr = AppUpdateStartAddr; size = AppUpdateDataSize; checkSum = AppCheckSum; break; } case UpdateFileType.UI: { startAddr = UIUpdateStartAddr; size = UIUpdateDataSize; checkSum = UiCheckSum; break; } case UpdateFileType.Rectify: { startAddr = RectifyUpdateStartAddr; size = RectifyUpdateDataSize; checkSum = RectifyCheckSum; break; } default: { startAddr = AppUpdateStartAddr; size = AppUpdateDataSize; checkSum = AppCheckSum; break; } } RequestCheckSum(this.UpdateConfigParamsNow.AppCheckMemoryParams, startAddr, size, checkSum); } private void UDSUpdateECUHardReset0x03() { ECUHardReset(3); timer1s.Enabled = false; } // uds 后测试工具 private void UpdateToolsDeinit() { } private void cobCarType_SelectedIndexChanged(object sender, EventArgs e) { } private void btnStartUpdataBoot_Click(object sender, EventArgs e) { byte len = 7; SendMsg_Len = len; SendBuff[0] = 0x31; SendBuff[1] = 0x01; SendBuff[2] = 0xaa; SendBuff[3] = 0x55; SendBuff[4] = 0x35; SendBuff[5] = 0x37; SendBuff[6] = 0x38; UDSInfo.SendPackage(SendBuff, len, false); } private void timer1_Tick(object sender, EventArgs e) { } private void timer2_Tick(object sender, EventArgs e) { } private void ckbIsCanFd_CheckedChanged(object sender, EventArgs e) { } private void btDidF183_Click(object sender, EventArgs e) { byte[] data = new byte[8]; byte len = 3; data[0] = 0x22; data[1] = 0xF1; data[2] = 0x83; UDSInfo.SendPackage(data, len, false); // rtxtLog.AppendText("ECU复位\n"); } private void btDidF187_Click(object sender, EventArgs e) { byte[] data = new byte[8]; byte len = 3; data[0] = 0x22; data[1] = 0xF1; data[2] = 0x87; UDSInfo.SendPackage(data, len, false); } private void btDidF193_Click(object sender, EventArgs e) { byte[] data = new byte[8]; byte len = 3; data[0] = 0x22; data[1] = 0xF1; data[2] = 0x93; UDSInfo.SendPackage(data, len, false); } } }