Imports System.ComponentModel Imports System.IO.Ports Imports System.Security.Cryptography Imports System.IO Public Class Form1 Public Class ROW_ITEM_INFO Public index As Integer Public upgradeCheck As Boolean Public address As Integer Public devModel As String Public devId As String Public runType As String Public status As String Public btnAllChip As String Public btnApp As String Public btnEEP As String End Class Public Enum COLS INDEX UPGRADE ADDR DEV_MODEL DEVID RUN_FLAG STATUS READ_ALL_CHIP READ_APP READ_EEPROM End Enum Public Enum CMD LOADER_CMD_SEARCH = &H63 LOADER_CMD_SET_PARAM = &H69 LOADER_CMD_WRITE_FLASH = &H60 LOADER_CMD_READ_FLASH = &H61 LOADER_CMD_ERASE_FLASH = &H62 LOADER_CMD_READ_EEPROM = &H65 LOADER_CMD_JUMP_TO_APP = &H68 LOADER_CMD_CHECK = &H67 LOADER_CMD_APP_SEARCH = &H1 LOADER_CMD_APP_JUMP = &H2 'BLC-C1 special LOADER_CMD_READ_FEATURE_AREA = &H80 LOADER_CMD_WRITE_FEATURE_AREA = &H81 End Enum Public Enum FMT SN CMD LEN CHECK_SUM PARAM End Enum Public Enum FMT_C1 SN CMD LEN_H LEN_L CHECK_SUM PARAM End Enum Public Enum DEV_TYPE NANO_485 PB_485 BLV_C1 End Enum Public Enum OPT_PROTOCOL_MODE HEX_MODE TEXT_MODE End Enum '定义全局变量 Private Opt_ProtocolMode As Integer = OPT_PROTOCOL_MODE.TEXT_MODE Const LOADER_PKT_LEN = 5100 'for C1 每一包有效数据4096byte Const LOADER_CMD_OFFSET = &H10 Const HANDSHAKE_BAUD = 512000 '2400 'V5.0 Loader_File_Size 重定义大小,应对C1使用需求 'Const LOADER_FILE_SIZE_MAX = 100 * 1024 '加载的文件的最大大小 'Const LOADER_DATA_SIZE_MAX = 32 * 1024 '下载的数据的最大字节数 Const LOADER_FILE_SIZE_MAX = 2 * 1024 * 1024 Const LOADER_DATA_SIZE_MAX = 2 * 1024 * 1024 Const BOOT_TIMEROUT_MIN = 10 'BOOT区最小超时 10s Property ERASE_CMD_TIMEROUT = 1000 '擦除命令的超时时间 Const BOOT_START_ADDR = &H6800 'BOOT起始地址 Private COLOR_ERROR As Color = Color.Red Private COLOR_NORMAL As Color = Color.Blue Private COLOR_MESSAGE As Color = Color.Black Private g_SendBuffer(LOADER_PKT_LEN - 1) As Byte Private g_RecvBuffer(LOADER_PKT_LEN - 1) As Byte 'V50 Add bigger Download Package Data Len to fit to C1’ Private g_HexStartAdd_For_C1 As UInt32 = 0 Private g_Download_DataLenght_Pre_Package As UInt16 = 128 Private g_Download_ParamLenght_Pre_Package As UInt16 = 130 Private g_RecvLen As UInt16 Private g_SearchStart As Boolean = False '搜索标志 Private g_GroupAddrFlag As Boolean = False '群地址使能标志 Private g_ParamOffset As UInt16 '参数偏移量 Private g_SendSn As Byte = 1 '序列号 Private g_UpgradeFlag As Boolean = False '升级标志 Private g_UpgradeBtnPressCnt As Byte = 0 '升级按钮按下次数,,针对群升级使用 Private g_DevType As DEV_TYPE = DEV_TYPE.NANO_485 Private g_BLVCxPackageLen As UInteger = 2048 'BLV_Cx主机串口升级包长,默认2048 - 20220509 曹聪 Private g_BLVCxBackupAppOffsetAddr As UInt32 = &H40000 'BLV_Cx主机备份APP偏移地址 Private g_SearchCount As Integer = 0 Private g_SelectCount As Integer = 0 Private g_SuccessCount As Integer = 0 Private g_FailCount As Integer = 0 Private g_LoaderHexFileBuffer(LOADER_FILE_SIZE_MAX - 1) As Byte Private g_LoaderDataBuffer(LOADER_DATA_SIZE_MAX - 1) As Byte Private g_LoaderEndAddr As UInt32 Private g_BlvBus As BlvBus Private g_RichTextBoxLastTick As DateTime Private SEARCH_TIMEROUT As UInt16 '搜索超时时间 Private g_UpgradeTimerout As UInt16 '升级包超时时间 Private g_maxRetry As UInt16 '重发次数 Private g_ReadBtnPressCnt As Byte = 0 '读取Flash按钮的计数 Private g_ReadEepBtnPressCnt As Byte = 0 '读取EEP Private g_SN_CustomProtocol As Byte = 0 Private g_CustomProtocolPacketLen As Byte = 0 '自定义协议的包长 Private g_RcvedPackageLen As Byte = 0 '接收数据包长 Private g_UpgradeRetryCnt As Byte = 0 Private g_UpgradeMaxRetry As Byte = 5 Private Sub UpdateDevType() Select Case Cbo_BusType.Text Case "NANO 485" g_DevType = DEV_TYPE.NANO_485 g_Download_DataLenght_Pre_Package = 128 ERASE_CMD_TIMEROUT = 2000 Case "PB 485" g_DevType = DEV_TYPE.PB_485 g_Download_DataLenght_Pre_Package = 128 Case "BLV_C1","CH592" g_DevType = DEV_TYPE.BLV_C1 'g_Download_DataLenght_Pre_Package = Val(tb_C1PackageLen.Text) g_Download_DataLenght_Pre_Package = g_BLVCxPackageLen Case Else Cbo_BusType.Text = "NANO 485" g_DevType = DEV_TYPE.NANO_485 End Select End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load AddCboPort() '加载一个串口号到控件 My.Settings.Reload() Cbo_Port.Text = My.Settings.CommPortNumber tb_CustomeProtocol_JumpToBl.Text = My.Settings.CustomeProtocol_JumpToBootloader tb_CustomeProtocol_Serach.Text = My.Settings.CustomeProtocol_Serach 'Tb_HexFilePath.Text = My.Settings.HexFilePatch Tb_HexFilePath.Text = Nothing num_AddrStart.Value = My.Settings.SerachAddStart num_AddrEnd.Value = My.Settings.SerachAddEnd Cbo_BusType.Text = My.Settings.BusType 'tb_C1PackageLen.Text = My.Settings.C1PackageLenght Me.Height = My.Settings.Windows_High If My.Settings.SerachTimeout > 0 Then TextBox1.Text = My.Settings.SerachTimeout If My.Settings.UpgradeTimeout > 0 Then TextBox2.Text = My.Settings.UpgradeTimeout If My.Settings.BootloaderTimeout > 0 Then Tb_Timeout.Text = My.Settings.BootloaderTimeout If My.Settings.CommBaudRate > 0 Then Cbo_Baud.Text = My.Settings.CommBaudRate Chk_UpgradeAllSel.Checked = My.Settings.chk_UpgradeAllSelect 'Cbo_ProType.Text = My.Settings.AppProtocolSetectedItem Opt_ProtocolMode = My.Settings.Opt_ProtocolMode If Opt_ProtocolMode = OPT_PROTOCOL_MODE.HEX_MODE Then opt_ProtocolHexMode.Checked = True If Opt_ProtocolMode = OPT_PROTOCOL_MODE.TEXT_MODE Then opt_ProtocolTextMode.Checked = True Cbo_ProType.Text = "Customize Protocol" g_BlvBus = New BlvBus(RichTextBox1) UpdateCountInfo() UpdateDevType() SEARCH_TIMEROUT = Val(TextBox1.Text) g_UpgradeTimerout = Val(TextBox2.Text) g_maxRetry = NumericUpDown3.Value btn_Reload.PerformClick() Me.Text = "Massduino Nano485 Loader(" & Application.ProductVersion & ")" & " - " & Tb_HexFilePath.Text TabPage2.Parent = Nothing TabPage3.Parent = Nothing End Sub Private Sub AddCboPort() Dim pItem As String() = System.IO.Ports.SerialPort.GetPortNames If pItem.Length Then Cbo_Port.Items.Clear() Cbo_Port.Items.AddRange(pItem) Cbo_Port.SelectedIndex = 0 End If End Sub Private Sub Chk_OneAddEn_CheckedChanged(sender As Object, e As EventArgs) Handles chk_OneAddEn.CheckedChanged If chk_OneAddEn.Checked Then chk_GroupAddEn.Checked = False Else chk_GroupAddEn.Checked = True End If End Sub Private Sub Chk_GroupAddEn_CheckedChanged(sender As Object, e As EventArgs) Handles chk_GroupAddEn.CheckedChanged If chk_GroupAddEn.Checked Then chk_OneAddEn.Checked = False Btn_Search.Enabled = False Else chk_OneAddEn.Checked = True Btn_Search.Enabled = True End If End Sub Private Sub Chk_AllSelect_CheckedChanged(sender As Object, e As EventArgs) Handles chk_AllSelect.CheckedChanged SetGroupAddCheckBoxAll(chk_AllSelect.Checked) End Sub Private Sub GetGroupAddr(ByRef groupAdd() As Byte) Dim i As Byte Dim j As Byte Array.Clear(groupAdd, 0, 4) For j = 0 To 3 For i = 0 To 7 If GetGroupAddrCheckBox(j * 8 + i) Then groupAdd(j) += 2 ^ i End If Next Next End Sub Private Sub SetGroupAddrCheckBox(ByVal index As Byte, ByVal isEn As Boolean) Select Case index Case 0 CheckBox1.Checked = isEn Case 1 CheckBox2.Checked = isEn Case 2 CheckBox3.Checked = isEn Case 3 CheckBox4.Checked = isEn Case 4 CheckBox5.Checked = isEn Case 5 CheckBox6.Checked = isEn Case 6 CheckBox7.Checked = isEn Case 7 CheckBox8.Checked = isEn Case 8 CheckBox9.Checked = isEn Case 9 CheckBox10.Checked = isEn Case 10 CheckBox11.Checked = isEn Case 11 CheckBox12.Checked = isEn Case 12 CheckBox13.Checked = isEn Case 13 CheckBox14.Checked = isEn Case 14 CheckBox15.Checked = isEn Case 15 CheckBox16.Checked = isEn Case 16 CheckBox17.Checked = isEn Case 17 CheckBox18.Checked = isEn Case 18 CheckBox19.Checked = isEn Case 19 CheckBox20.Checked = isEn Case 20 CheckBox21.Checked = isEn Case 21 CheckBox22.Checked = isEn Case 22 CheckBox23.Checked = isEn Case 23 CheckBox24.Checked = isEn Case 24 CheckBox25.Checked = isEn Case 25 CheckBox26.Checked = isEn Case 26 CheckBox27.Checked = isEn Case 27 CheckBox28.Checked = isEn Case 28 CheckBox29.Checked = isEn Case 29 CheckBox30.Checked = isEn Case 30 CheckBox31.Checked = isEn Case 31 CheckBox32.Checked = isEn End Select End Sub Private Function GetGroupAddrCheckBox(ByVal index As Byte) As Boolean Dim retCheck As Boolean Select Case index Case 0 retCheck = CheckBox1.Checked Case 1 retCheck = CheckBox2.Checked Case 2 retCheck = CheckBox3.Checked Case 3 retCheck = CheckBox4.Checked Case 4 retCheck = CheckBox5.Checked Case 5 retCheck = CheckBox6.Checked Case 6 retCheck = CheckBox7.Checked Case 7 retCheck = CheckBox8.Checked Case 8 retCheck = CheckBox9.Checked Case 9 retCheck = CheckBox10.Checked Case 10 retCheck = CheckBox11.Checked Case 11 retCheck = CheckBox12.Checked Case 12 retCheck = CheckBox13.Checked Case 13 retCheck = CheckBox14.Checked Case 14 retCheck = CheckBox15.Checked Case 15 retCheck = CheckBox16.Checked Case 16 retCheck = CheckBox17.Checked Case 17 retCheck = CheckBox18.Checked Case 18 retCheck = CheckBox19.Checked Case 19 retCheck = CheckBox20.Checked Case 20 retCheck = CheckBox21.Checked Case 21 retCheck = CheckBox22.Checked Case 22 retCheck = CheckBox23.Checked Case 23 retCheck = CheckBox24.Checked Case 24 retCheck = CheckBox25.Checked Case 25 retCheck = CheckBox26.Checked Case 26 retCheck = CheckBox27.Checked Case 27 retCheck = CheckBox28.Checked Case 28 retCheck = CheckBox29.Checked Case 29 retCheck = CheckBox30.Checked Case 30 retCheck = CheckBox31.Checked Case 31 retCheck = CheckBox32.Checked End Select Return retCheck End Function Private Sub SetGroupAddCheckBoxAll(ByVal isEn As Boolean) Dim i As Byte For i = 0 To 31 SetGroupAddrCheckBox(i, isEn) Next End Sub Private Sub Cbo_Port_DropDown(sender As Object, e As EventArgs) Handles Cbo_Port.DropDown Cbo_Port.Items.Clear() Cbo_Port.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames) End Sub Private Sub SetAddrControl(ByVal isEn As Boolean) chk_OneAddEn.Enabled = isEn chk_GroupAddEn.Enabled = isEn num_AddrStart.Enabled = isEn num_AddrEnd.Enabled = isEn End Sub Private Sub Btn_Search_Click(sender As Object, e As EventArgs) Handles Btn_Search.Click If g_SearchStart = False Then RichTextBox1.Clear() g_SearchStart = True Btn_Upgrade.Enabled = False Btn_Search.Text = "Stop" 'Btn_Search.BackColor = Color.Green SetAddrControl(False) SearchDevice() '搜索 SetAddrControl(True) Btn_Search.Text = "Serach" 'Btn_Search.BackColor = SystemColors.Control Btn_Upgrade.Enabled = True g_SearchStart = False Else g_SearchStart = False End If End Sub Private Sub JudgeGroupAddr() If g_DevType = DEV_TYPE.BLV_C1 Then g_ParamOffset = FMT_C1.PARAM + 1 Else If chk_OneAddEn.Checked Then g_GroupAddrFlag = False g_ParamOffset = FMT.PARAM + 1 Else g_GroupAddrFlag = True g_ParamOffset = FMT.PARAM + 4 End If End If End Sub Public Sub SetStatus(ByVal conStatus As ToolStripStatusLabel, ByVal status As String, ByVal clr As Color) conStatus.Text = status conStatus.ForeColor = clr Application.DoEvents() End Sub Public Sub SetStatus(ByVal status As String, ByVal clr As Color) tssl_Status.Text = status tssl_Status.ForeColor = clr Application.DoEvents() End Sub '搜索的时候要充分考虑 g_SearchStart 变量的问题,应有效防止中途停止搜索的情况 Private Sub SearchDevice() If Port.IsOpen = False Then MsgBox("Please Open Com Port!") : Exit Sub DataGridView1.Rows.Clear() Dim index As Integer = 0 Dim address As Integer = 0 Dim readValid As Boolean = False Dim addrStart = num_AddrStart.Value Dim addrEnd = num_AddrEnd.Value Dim isExist As Boolean = False Dim devId As String = "" Dim bootFlag As String = "" Dim devModel As String = "" Dim pRowItemInfo As New ROW_ITEM_INFO g_SearchCount = 0 g_SelectCount = 0 g_SuccessCount = 0 g_FailCount = 0 JudgeGroupAddr() '判定是单发还是群发 address = addrStart While g_SearchStart = True If Port.IsOpen = False Then MsgBox("Please Open Com Port!") : Exit Sub RichTextBox_Show("Serach by DevAdd:" & address, Color.Black) SetStatus("Serach by DevAdd:" & address, Color.Black) If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If 'Bootloder 区搜索 (地址, devID bootFlag devModel 重发次数,发命令后等待多久认为无回复) readValid = SearchDeviceCmd(address, devId, bootFlag, devModel, g_maxRetry, SEARCH_TIMEROUT) 'Boot 区搜索,采用2400bps If readValid = False Then SetPortBaud(Val(Cbo_Baud.Text)) '设置波特率 Delay(1) 'App 区域搜索 readValid = AllAppSearchDeviceCmd(address, devId, bootFlag, devModel, g_maxRetry, SEARCH_TIMEROUT) 'App区搜索,采用设定波特率 End If SetPortBaud(Val(Cbo_Baud.Text)) '设置波特率 If readValid = True Then isExist = False For Each pRow As DataGridViewRow In DataGridView1.Rows If pRow.Cells(COLS.ADDR).Value = address Then isExist = True Exit For End If Next If isExist = False Then pRowItemInfo.index = index + 1 If Chk_UpgradeAllSel.Checked Then pRowItemInfo.upgradeCheck = True g_SelectCount += 1 End If pRowItemInfo.address = address pRowItemInfo.devModel = devModel pRowItemInfo.devId = devId pRowItemInfo.runType = bootFlag pRowItemInfo.btnAllChip = "Read" pRowItemInfo.btnApp = "Read" pRowItemInfo.btnEEP = "Read" AddItem(pRowItemInfo) index += 1 g_SearchCount += 1 UpdateCountInfo() '更新搜索总数 End If End If address += 1 If address > addrEnd Then address = addrStart End If 'Application.DoEvents() Delay(10) End While SetStatus("Serach completed. Total devices: " & g_SearchCount, Color.Green) End Sub Public Sub UpdateCountInfo() ToolStripStatusLabel1.Text = "Total Devices:" & " " & g_SearchCount & " " & "Total Selected:" & " " & g_SelectCount & " " & "Upgrade Completed:" & " " & g_SuccessCount & " " & "Upgrade Fail:" & " " & g_FailCount End Sub Private Function AddItem(ByVal item As ROW_ITEM_INFO) As Boolean Dim pRow As New DataGridViewRow Dim pCell As DataGridViewCell pCell = New DataGridViewTextBoxCell pCell.Value = item.index pRow.Cells.Add(pCell) pCell = New DataGridViewCheckBoxCell pCell.Value = item.upgradeCheck pRow.Cells.Add(pCell) pCell = New DataGridViewTextBoxCell pCell.Value = item.address pRow.Cells.Add(pCell) pCell = New DataGridViewTextBoxCell pCell.Value = item.devModel pRow.Cells.Add(pCell) pCell = New DataGridViewTextBoxCell pCell.Value = item.devId pRow.Cells.Add(pCell) pCell = New DataGridViewTextBoxCell pCell.Value = item.runType pRow.Cells.Add(pCell) pCell = New DataGridViewTextBoxCell pCell.Value = item.status pRow.Cells.Add(pCell) pCell = New DataGridViewButtonCell pCell.Value = item.btnAllChip pRow.Cells.Add(pCell) pCell = New DataGridViewButtonCell pCell.Value = item.btnApp pRow.Cells.Add(pCell) pCell = New DataGridViewButtonCell pCell.Value = item.btnEEP pRow.Cells.Add(pCell) pRow.Tag = item DataGridView1.Rows.Add(pRow) Return True End Function Private Function HexCalcCheckSum(buf() As Byte, len As UInt16) As UInt64 Dim sum As Int64 Dim i As UInt16 For i = 0 To len - 1 sum += buf(i) sum = sum And &HFF Next sum = ((Not sum) + 1) And &HFF Return sum End Function Private Function CalcCheckSum(ByVal buf() As Byte, ByVal len As UInt16) As Byte Dim sum As Int16 = 0 Dim i As UInt16 = 0 Dim retByte As Byte For i = 0 To len - 1 sum += buf(i) sum = sum And &HFF Next retByte = (Not sum) And &HFF Return retByte End Function Private Sub CalcCRC16(ByVal buf() As Byte, ByVal len As UInt32, ByRef outBuf() As Byte, ByRef outLen As UInt16) Dim i As UInt32 = g_HexStartAdd_For_C1 '从起始地址开始校验 Dim j As UInt32 = 0 Dim crcVal As UInt16 = 0 Dim index As UInt16 = 0 Dim consstr As String = "" Do 'V60: BLV-C1 CRC计算长度由512Bytes改为2048Bytes If g_DevType = DEV_TYPE.BLV_C1 Then crcVal = CRC16.NetCRC16(buf, i, 2048, consstr) outBuf(index) = crcVal \ 256 index += 1 outBuf(index) = crcVal Mod 256 index += 1 i += 2048 Else crcVal = CRC16.NetCRC16(buf, i, 512, consstr) outBuf(index) = crcVal \ 256 index += 1 outBuf(index) = crcVal Mod 256 index += 1 i += 512 'RichTextBox_Show($"CRC 数据包{vbCrLf }{consstr}{vbCrLf }{Hex(outBuf(index - 2)).PadLeft(2, "0")} {Hex(outBuf(index - 1)).PadLeft(2, "0")}", Color.OrangeRed) End If Loop Until i >= len outLen = index RichTextBox_Show("CRC", outBuf, outLen, COLOR_ERROR) End Sub Private Sub CalcCheckSum(ByVal buf() As Byte, ByVal len As UInt32, ByRef resultBuf() As Byte) Dim sum As Int64 = 0 Dim i As UInt32 = 0 Dim j As UInt16 = 0 Dim retByte As Int64 Do For j = 0 To 127 sum += buf(i + j) sum = sum And &HFFFFFFFF Next i += 128 Loop Until i >= len 'retByte = (Not sum) And &HFFFFFFFF retByte = sum 'TextBox1.Text = Hex(retByte) resultBuf(0) = (retByte \ &H1000000) And &HFF resultBuf(1) = (retByte \ &H10000) And &HFF resultBuf(2) = (retByte \ &H100) And &HFF resultBuf(3) = retByte And &HFF End Sub Private Sub FillSendBuf(ByRef sendBuf() As Byte, cmd As Byte, paramLen As UInt16, Optional ByVal address As Integer = 0) Dim groupAddr(3) As Byte Dim tmpC1Len As UInt16 = 0 'For BLV-C1, LEN有两个字节 If g_DevType = DEV_TYPE.BLV_C1 Then sendBuf(FMT_C1.CMD) = cmd sendBuf(FMT_C1.LEN_H) = (g_ParamOffset + paramLen) \ 256 sendBuf(FMT_C1.LEN_L) = (g_ParamOffset + paramLen) Mod 256 sendBuf(FMT_C1.CHECK_SUM) = 0 sendBuf(FMT_C1.SN) = g_SendSn And &H3F If g_GroupAddrFlag Then sendBuf(FMT_C1.SN) = sendBuf(FMT_C1.SN) Or &H80 GetGroupAddr(groupAddr) Array.Copy(groupAddr, 0, sendBuf, FMT_C1.PARAM, 4) Else sendBuf(FMT_C1.PARAM) = address End If tmpC1Len = sendBuf(FMT_C1.LEN_H) * 256 + sendBuf(FMT_C1.LEN_L) sendBuf(FMT_C1.CHECK_SUM) = CalcCheckSum(sendBuf, tmpC1Len) Else sendBuf(FMT.CMD) = cmd sendBuf(FMT.LEN) = g_ParamOffset + paramLen sendBuf(FMT.CHECK_SUM) = 0 sendBuf(FMT.SN) = g_SendSn And &H3F If g_GroupAddrFlag Then sendBuf(FMT.SN) = sendBuf(FMT.SN) Or &H80 GetGroupAddr(groupAddr) Array.Copy(groupAddr, 0, sendBuf, FMT.PARAM, 4) Else sendBuf(FMT.PARAM) = address End If sendBuf(FMT.CHECK_SUM) = CalcCheckSum(sendBuf, sendBuf(FMT.LEN)) End If g_SendSn = g_SendSn + 1 If g_SendSn > &H3F Then g_SendSn = 0 End If End Sub ''' ''' 擦除FLASH命令 ''' ''' ''' ''' ''' Private Function EraseFlashCmd(ByVal address As Byte, ByVal maxRetry As UInt16, ByVal timeout As UInt16) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) If Chk_LogicFile.Checked = True Then '当前处于下发逻辑文件中,擦除逻辑文件 g_SendBuffer(g_ParamOffset) = &H2 ElseIf Chk_BackupUpgrade.Checked = True Then '当前处于下发备份APP中,擦除备份APP g_SendBuffer(g_ParamOffset) = &H1 Else g_SendBuffer(g_ParamOffset) = &H0 End If FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_ERASE_FLASH, 1, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Function Private Function WriteFlashCmd(ByVal address As Byte, ByVal flashAddr As UInt32, ByVal flashDataBuffer() As Byte, ByVal bufferIndex As UInt32, ByVal maxRetry As UInt16, ByVal timeout As UInt16) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) If g_DevType = DEV_TYPE.BLV_C1 Then 'g_SendBuffer(g_ParamOffset) = flashAddr Mod 65536 'g_SendBuffer(g_ParamOffset + 1) = g_SendBuffer(g_ParamOffset) \ 256 'g_SendBuffer(g_ParamOffset + 2) = g_SendBuffer(g_ParamOffset) Mod 256 g_SendBuffer(g_ParamOffset) = (flashAddr >> 16) And &HFF g_SendBuffer(g_ParamOffset + 1) = (flashAddr >> 8) And &HFF g_SendBuffer(g_ParamOffset + 2) = flashAddr And &HFF g_Download_ParamLenght_Pre_Package = g_Download_DataLenght_Pre_Package + 3 '往下发数据+地址总长度,C1的地址多一个byte Array.Copy(flashDataBuffer, bufferIndex, g_SendBuffer, g_ParamOffset + 3, g_Download_DataLenght_Pre_Package) Else g_SendBuffer(g_ParamOffset) = flashAddr \ 256 g_SendBuffer(g_ParamOffset + 1) = flashAddr Mod 256 g_Download_ParamLenght_Pre_Package = g_Download_DataLenght_Pre_Package + 2 '往下发数据+地址总长度 Array.Copy(flashDataBuffer, bufferIndex, g_SendBuffer, g_ParamOffset + 2, g_Download_DataLenght_Pre_Package) End If FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_WRITE_FLASH, g_Download_ParamLenght_Pre_Package, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Function Private Function ReadEeprom(readFlashDlg As ReadFlash, ByVal address As Byte) As Boolean Dim eepAddr As UInt16 = 0 Dim eepEndAddr As UInt16 = 1 * 1024 Dim loaderNum As UInt16 Do If ReadEEPROMCmd(address, eepAddr, 128) Then ShowFlashData(readFlashDlg.DataGridView1, eepAddr, g_RecvBuffer) loaderNum = (eepAddr * 100) / eepEndAddr If loaderNum > 100 Then loaderNum = 100 readFlashDlg.ToolStripProgressBar1.Value = loaderNum Application.DoEvents() '处理Windows消息的方法 Else Return False End If eepAddr += 128 If g_ReadEepBtnPressCnt <> 2 Then Return False Loop Until eepAddr >= eepEndAddr readFlashDlg.ToolStripProgressBar1.Value = 100 Return True End Function Private Function ReadFlash(readFlashDlg As ReadFlash, ByVal address As Byte, ByVal endAddr As UInt32) As Boolean Dim flashAddr As UInt32 = 0 Dim flashEndAddr As UInt16 = endAddr Dim loaderNum As UInt16 Do If ReadFlashCmd(address, flashAddr, 128) Then ShowFlashData(readFlashDlg.DataGridView1, flashAddr, g_RecvBuffer) loaderNum = (flashAddr * 100) / flashEndAddr If loaderNum > 100 Then loaderNum = 100 readFlashDlg.ToolStripProgressBar1.Value = loaderNum Application.DoEvents() '处理Windows消息的方法 Else Return False End If flashAddr += 128 If g_ReadBtnPressCnt <> 2 Then Return False Loop Until flashAddr >= flashEndAddr readFlashDlg.ToolStripProgressBar1.Value = 100 Return True End Function Private Sub ShowFlashData(ByRef ReadDlg_DataGridView1 As DataGridView, ByVal flashAddr As UInt32, ByVal dataBuf() As Byte) Dim i As UInt16 = 0 Dim rowsNum As UInt32 = flashAddr \ 16 Dim j As UInt16 Dim rowsDataBuf(15) As Byte ReadDlg_DataGridView1.Rows.Add() ReadDlg_DataGridView1.Rows(rowsNum).HeaderCell.Value = Hex(flashAddr).PadLeft(4, "0") For i = 0 To 127 If (i >= 16) AndAlso (i Mod 16 = 0) Then For j = 0 To 15 rowsDataBuf(j) = "&H" & ReadDlg_DataGridView1.Rows(rowsNum).Cells(j).Value If rowsDataBuf(j) < &H20 OrElse rowsDataBuf(j) > &H7E Then rowsDataBuf(j) = &H2E End If Next ReadDlg_DataGridView1.Rows(rowsNum).Cells(16).Value = System.Text.Encoding.ASCII.GetString(rowsDataBuf) ReadDlg_DataGridView1.Rows.Add() rowsNum += 1 ReadDlg_DataGridView1.Rows(rowsNum).HeaderCell.Value = Hex(rowsNum * 16).PadLeft(4, "0") ReadDlg_DataGridView1.FirstDisplayedScrollingRowIndex = ReadDlg_DataGridView1.Rows.Count - 1 '将内容滚动的作用 End If ReadDlg_DataGridView1.Rows(rowsNum).Cells(i Mod 16).Value = Hex(dataBuf(FMT.PARAM + 1 + i)).PadLeft(2, "0") 'Application.DoEvents() '处理Windows消息的方法 Next For j = 0 To 15 rowsDataBuf(j) = "&H" & ReadDlg_DataGridView1.Rows(rowsNum).Cells(j).Value If rowsDataBuf(j) < &H20 OrElse rowsDataBuf(j) > &H7E Then rowsDataBuf(j) = &H2E End If Next ReadDlg_DataGridView1.Rows(rowsNum).Cells(16).Value = System.Text.Encoding.ASCII.GetString(rowsDataBuf) End Sub Private Function ReadFlashCmd(ByVal address As Byte, ByVal flashAddr As UInt32, ByVal dataLen As UInt16) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) If g_DevType = DEV_TYPE.BLV_C1 Then g_SendBuffer(g_ParamOffset) = flashAddr \ 65536 g_SendBuffer(g_ParamOffset + 1) = (g_SendBuffer(g_ParamOffset) Mod 65536) \ 256 g_SendBuffer(g_ParamOffset + 2) = (g_SendBuffer(g_ParamOffset) Mod 65536) Mod 256 g_SendBuffer(g_ParamOffset + 3) = dataLen \ 256 g_SendBuffer(g_ParamOffset + 4) = dataLen Mod 256 Else g_SendBuffer(g_ParamOffset) = flashAddr \ 256 g_SendBuffer(g_ParamOffset + 1) = flashAddr Mod 256 g_SendBuffer(g_ParamOffset + 2) = dataLen \ 256 g_SendBuffer(g_ParamOffset + 3) = dataLen Mod 256 End If FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_READ_FLASH, 4, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, g_maxRetry, g_UpgradeTimerout) End Function Private Function ReadEEPROMCmd(ByVal address As Byte, ByVal eepAddr As UInt16, ByVal eepLen As UInt16) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) g_SendBuffer(g_ParamOffset) = eepAddr \ 256 g_SendBuffer(g_ParamOffset + 1) = eepAddr Mod 256 g_SendBuffer(g_ParamOffset + 2) = eepLen \ 256 g_SendBuffer(g_ParamOffset + 3) = eepLen Mod 256 FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_READ_EEPROM, 4, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, g_maxRetry, g_UpgradeTimerout) End Function Private Function SearchDeviceCmd(ByVal address As Byte, ByRef devId As String, ByRef bootFlag As String, ByRef devModel As String, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Dim devModelLen As Int16 Dim tmpLen As UInt16 = 0 Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) Dim bootTimerout As UInt32 = Val(Tb_Timeout.Text) If bootTimerout < BOOT_TIMEROUT_MIN Then bootTimerout = BOOT_TIMEROUT_MIN ElseIf bootTimerout > 65535 Then bootTimerout = 65535 End If g_SendBuffer(g_ParamOffset) = bootTimerout \ 256 g_SendBuffer(g_ParamOffset + 1) = bootTimerout Mod 256 FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_SEARCH, 2, address) If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) Then If g_DevType = DEV_TYPE.BLV_C1 Then devId = g_RecvBuffer(FMT_C1.PARAM + 1).ToString("X02") & " " & g_RecvBuffer(FMT_C1.PARAM + 2).ToString("X02") & " " & g_RecvBuffer(FMT_C1.PARAM + 3).ToString("X02") & " " & g_RecvBuffer(FMT_C1.PARAM + 4).ToString("X02") Else devId = g_RecvBuffer(FMT.PARAM + 1).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 2).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 3).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 4).ToString("X02") End If bootFlag = "BOOT" devModelLen = g_RecvLen - FMT.PARAM - 5 If devModelLen > 0 Then devModel = System.Text.Encoding.ASCII.GetString(g_RecvBuffer, FMT.PARAM + 5, devModelLen) Else devModel = "---" End If Return True End If Return False End Function Private g_RcvedString As String = "" Private Function AppSerachDeviceCmd_ByCustom_TextMode(ByVal address As Byte, ByRef devId As String, ByRef bootFlag As String, ByRef devModel As String, Optional ByVal maxRetry As Integer = 3, Optional ByVal timeout As Integer = 100) As Boolean '自定义TEXT 模式下的APP区搜索命令, Dim SentString = CreateSentTextString(tb_CustomeProtocol_Serach.Text, address) '发送搜索命令 If WriteToDevice_ByCustomProtocol_TextMode(SentString, g_RcvedString, maxRetry, timeout) Then devId = 0 bootFlag = "APP" 'V2.0 2020-8-26 Momo:APP搜索时,返回长度必须大于等于搜索命令,并且前面几个字节必须和搜索命令相同,后面部分分离出来默认为是机型编号 'V2.3 2020-10-3 Momo:Text模式下的protocol: 'sent:Searach:01 'recv: Searach:01=MD-485 If (g_RcvedString.Length >= SentString.Length + 1) Then devModel = Microsoft.VisualBasic.Right(g_RcvedString, g_RcvedString.Length - SentString.Length + 1) 'MsgBox(devModel) Else Return False devModel = "" End If Return True End If Return False End Function Private Function WriteToDevice_ByCustomProtocol_TextMode(ByVal SentString As String, ByRef RcvString As String, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Dim retryCount As Byte = 0 Dim retFlag As Boolean = False Dim timeTick As UInt32 Dim rLen As Integer = 0 Dim rLen_Last As Integer = 0 Dim readBuffNoDataTimeCount As Integer = 0 Dim tmpRcvString = "" Dim tmpIdx As Integer = 0 Do RichTextBox_Show("TX retry = " & retryCount & "," & SentString, COLOR_MESSAGE) retFlag = UartSentBuf_TextMode(SentString) '发送数据 rLen = 0 WaitSendComp(SentString.Length) '等待发送出去 If g_DevType = DEV_TYPE.PB_485 Then Delay(0.8 * SentString.Length) End If If retFlag Then 'RichTextBox_Show("retFlag = true", Color.DarkGreen) retFlag = False timeTick = My.Computer.Clock.TickCount Do Try rLen = Port.BytesToRead Catch ex As Exception rLen = 0 End Try If rLen > 0 Then If rLen <> rLen_Last Then '判断收到的数据长度有没有变化 rLen_Last = rLen timeTick = My.Computer.Clock.TickCount readBuffNoDataTimeCount = 0 Else readBuffNoDataTimeCount = readBuffNoDataTimeCount + 1 End If End If Delay(1) Loop Until (My.Computer.Clock.TickCount - timeTick) > timeout Or readBuffNoDataTimeCount >= 20 '退出循环条件:超时到达,或者连续20次缓冲区长度没有变化 'RichTextBox_Show("RecviedFinished: rLen=" & rLen & ", SentString.Length=" & SentString.Length, Color.DarkGreen) If rLen >= SentString.Length - 2 Then '缓冲区数据长度大于等于发送长度就认为接收正确 'RichTextBox_Show("RcvString", Color.DarkGreen) '2021-3-24 V3.0 用Port.ReadLine会导致没有换行符时死等在这里 ' RcvString = Port.ReadLine Dim bytes(rLen - 1) As Byte Port.Read(bytes, 0, rLen) RcvString = System.Text.UTF8Encoding.UTF8.GetString(bytes) '=================================================’ If Microsoft.VisualBasic.Left(RcvString, SentString.Length - 2) = Microsoft.VisualBasic.Left(SentString, SentString.Length - 2) Then If RcvString.Contains(vbCr) Then RichTextBox_Show("接受数据成功:" & RcvString, COLOR_NORMAL) Return True Else RichTextBox_Show("数据未含newline", COLOR_ERROR) retryCount = retryCount + 1 End If Else RichTextBox_Show("接收数据头部不匹配", COLOR_ERROR) retryCount = retryCount + 1 End If Else RichTextBox_Show("接收数据长度不正确", COLOR_ERROR) retryCount = retryCount + 1 End If Else retryCount = retryCount + 1 End If Loop Until retryCount > maxRetry Return False End Function Private Function UartSentBuf_TextMode(ByVal SentStringBuff As String) As Boolean Try Port.DiscardOutBuffer() Port.DiscardInBuffer() Catch ex As Exception Return False End Try Try Port.Write(SentStringBuff) Catch ex As Exception Return False End Try Return True End Function Private Function CreateSentTextString(txtString As String, address As Byte) As String Dim tmpString As String '找到 字符串并且用SN替换 tmpString = txtString.Replace("", address) '增加vbnewline tmpString = tmpString & vbNewLine Return tmpString End Function Private Function AppSerachDeviceCmd_ByCustom(ByVal address As Byte, ByRef devId As String, ByRef bootFlag As String, ByRef devModel As String, Optional ByVal maxRetry As Integer = 3, Optional ByVal timeout As Integer = 100) As Boolean '自定义写一下的APP区搜索命令,Nano485和NanoPB采用这个协议 Dim tmpSentBufLen = TextStringToByteArray(tb_CustomeProtocol_Serach.Text, address) Dim tmpIdx As Integer = 0 If WriteToDevice_ByCustomProtocol(g_SendBuffer, tmpSentBufLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) Then devId = 0 bootFlag = "APP" 'V2.0 2020-8-26 Momo:APP搜索时,返回必须大于等于搜索命令,并且前面几个字节必须和搜索命令相同,后面部分分离出来默认为是机型编号 If (g_RcvedPackageLen >= g_CustomProtocolPacketLen) And g_CustomProtocolPacketLen >= 1 Then For tmpIdx = 0 To g_CustomProtocolPacketLen - 1 If g_RecvBuffer(tmpIdx) <> g_SendBuffer(tmpIdx) Then devModel = "" Return False End If Next tmpIdx devModel = System.Text.Encoding.ASCII.GetString(g_RecvBuffer, g_CustomProtocolPacketLen, g_RcvedPackageLen - g_CustomProtocolPacketLen) 'MsgBox(devModel) Else Return False 'devModel = System.Text.Encoding.ASCII.GetString(g_RecvBuffer, 0, g_RcvedPackageLen) devModel = "" End If Return True End If Return False End Function Private Function AppSearchDeviceCmd(ByVal address As Byte, ByRef devId As String, ByRef bootFlag As String, ByRef devModel As String, Optional ByVal maxRetry As Integer = 3, Optional ByVal timeout As Integer = 100) As Boolean Dim devModelLen As Int16 Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_APP_SEARCH, 0, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) Then devId = g_RecvBuffer(FMT.PARAM + 1).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 2).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 3).ToString("X02") & " " & g_RecvBuffer(FMT.PARAM + 4).ToString("X02") bootFlag = "APP" devModelLen = g_RecvLen - FMT.PARAM - 5 If devModelLen > 0 Then devModel = System.Text.Encoding.ASCII.GetString(g_RecvBuffer, FMT.PARAM + 5, g_RecvLen - FMT.PARAM - 5) Else devModel = "---" End If Return True End If Return False End Function Private Function AllAppSearchDeviceCmd(ByVal address As Byte, ByRef devId As String, ByRef bootFlag As String, ByRef devModel As String, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean 'BLW Protocol 'Public Protocol 'Customize Protocol If Cbo_ProType.Text = "BLW Protocol" Then Return g_BlvBus.SearchDeviceCmd(Val(Tb_DevType.Text), Port, address, devId, bootFlag, devModel, g_GroupAddrFlag, g_DevType, maxRetry, timeout) ElseIf Cbo_ProType.Text = "Public Protocol" Then Return AppSearchDeviceCmd(address, devId, bootFlag, devModel, maxRetry, timeout) ElseIf Cbo_ProType.Text = "Customize Protocol" Then '用户自定义协议,Nano485采用这个协议 'V2.3 2020-10-3 Momo:自定义协议分Text和Hex两种 If Opt_ProtocolMode = OPT_PROTOCOL_MODE.HEX_MODE Then Return AppSerachDeviceCmd_ByCustom(address, devId, bootFlag, devModel, maxRetry, timeout) ElseIf Opt_ProtocolMode = OPT_PROTOCOL_MODE.TEXT_MODE Then Return AppSerachDeviceCmd_ByCustom_TextMode(address, devId, bootFlag, devModel, maxRetry, timeout) Else Return False End If End If Return False End Function Private Function AllAppJumpCmd(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean If Cbo_ProType.Text = "BLW Protocol" Then Return g_BlvBus.JumpBootCmd(Val(Tb_DevType.Text), Port, address, g_GroupAddrFlag, g_DevType, g_maxRetry, g_UpgradeTimerout) ElseIf Cbo_ProType.Text = "Public Protocol" Then Return AppJumpCmd(address, g_maxRetry, g_UpgradeTimerout) ElseIf Cbo_ProType.Text = "Customize Protocol" Then '用户自定义协议,Nano485采用这个协议 'V2.3 2020-10-3 Momo:自定义协议分Text和Hex两种 If Opt_ProtocolMode = OPT_PROTOCOL_MODE.HEX_MODE Then Return JumpToAppByCustomProtocol(address, g_maxRetry, g_UpgradeTimerout) ElseIf Opt_ProtocolMode = OPT_PROTOCOL_MODE.TEXT_MODE Then Return JumpToAppByCustomProtocol_TEXT_MODE(address, g_maxRetry, g_UpgradeTimerout) End If End If Return False End Function Private Function AppJumpCmdByCustomProtocol(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) 'FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_APP_JUMP, 0, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Function Private Function AppJumpCmd(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_APP_JUMP, 0, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Function Private Sub SearchDeviceCmd(ByVal maxRetry As Integer, ByVal timeout As Integer) Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) Dim bootTimerout As UInt32 = Val(Tb_Timeout.Text) If bootTimerout < BOOT_TIMEROUT_MIN Then bootTimerout = BOOT_TIMEROUT_MIN ElseIf bootTimerout > 65535 Then bootTimerout = 65535 End If g_SendBuffer(g_ParamOffset) = bootTimerout \ 256 g_SendBuffer(g_ParamOffset + 1) = bootTimerout Mod 256 FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_SEARCH, 2) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Sub Private Function SetParamCmd(ByVal address As Byte, ByVal baud As UInt32, ByVal timerout As UInt32) Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) g_SendBuffer(g_ParamOffset) = (baud \ 100) \ 256 g_SendBuffer(g_ParamOffset + 1) = (baud \ 100) Mod 256 g_SendBuffer(g_ParamOffset + 2) = timerout \ 256 g_SendBuffer(g_ParamOffset + 3) = timerout Mod 256 g_SendBuffer(g_ParamOffset + 4) = g_DevType FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_SET_PARAM, 5, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, g_maxRetry, g_UpgradeTimerout) End Function Private Sub SetParamCmd(ByVal baud As UInt32, ByVal timerout As UInt32, ByVal maxRetry As Integer, ByVal timeout As Integer) Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) g_SendBuffer(g_ParamOffset) = (baud \ 100) \ 256 g_SendBuffer(g_ParamOffset + 1) = (baud \ 100) Mod 256 g_SendBuffer(g_ParamOffset + 2) = timerout \ 256 g_SendBuffer(g_ParamOffset + 3) = timerout Mod 256 g_SendBuffer(g_ParamOffset + 4) = g_DevType FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_SET_PARAM, 5) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Sub '将文本框中的数值转换为hex数组,支持关键字 Private Function TextStringToByteArray(txtString As String, address As Byte) As UShort Dim tmp() As String Dim idx As Integer Dim idxOfCks As Integer Dim tmpStr As String Dim SendBufferCorrectIndex As Integer = 0 Dim tmpIfCksByteExist As Boolean = False Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) Try '分割文本框内的内容并生成hex数组 tmp = Split(txtString, Chr(32)) For idx = 0 To UBound(tmp) 'UBound()取数组内元素的个数 'MsgBox(tmp(idx)) tmpStr = tmp(idx) If tmpStr <> " " AndAlso tmpStr <> "" Then If UCase(tmpStr) = "" Then g_SendBuffer(SendBufferCorrectIndex) = address ElseIf UCase(tmpStr) = "" Then g_SendBuffer(SendBufferCorrectIndex) = Tb_DevType.Text ElseIf UCase(tmpStr) = "" Then tmpIfCksByteExist = True idxOfCks = SendBufferCorrectIndex g_SendBuffer(SendBufferCorrectIndex) = &H0 ElseIf UCase(tmpStr) = "" Then g_SendBuffer(SendBufferCorrectIndex) = g_SN_CustomProtocol Else g_SendBuffer(idx) = "&H" & tmpStr End If SendBufferCorrectIndex = SendBufferCorrectIndex + 1 End If Next idx '填写CheckSum字节 If tmpIfCksByteExist Then g_SendBuffer(idxOfCks) = CalcCheckSum(g_SendBuffer, SendBufferCorrectIndex) End If g_CustomProtocolPacketLen = SendBufferCorrectIndex '将自定义协议字节数保存在SendBufferCorrectIndex内,便于搜索时解析出正确机型信息 Return SendBufferCorrectIndex Catch ex As Exception Return SendBufferCorrectIndex End Try Return SendBufferCorrectIndex End Function Private Function JumpToAppByCustomProtocol_TEXT_MODE(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean '自定义TEXT 模式下的APP区跳转命令, Dim SentString = CreateSentTextString(tb_CustomeProtocol_JumpToBl.Text, address) '发送跳转命令 If WriteToDevice_ByCustomProtocol_TextMode(SentString, g_RcvedString, maxRetry, timeout) Then 'V2.3 2020-10-3 Momo:Text模式下的protocol: 'sent:Jump:01 'recv: Jump:01=OK Return True End If Return False End Function Private Function JumpToAppByCustomProtocol(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Dim tmpSentBufLen = TextStringToByteArray(tb_CustomeProtocol_JumpToBl.Text, address) Return WriteToDevice_ByCustomProtocol(g_SendBuffer, tmpSentBufLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Function Private Function JumpToApp(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_JUMP_TO_APP, 0, address) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If Return WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) End Function Private Sub JumpToApp() Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_JUMP_TO_APP, 0) Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, g_maxRetry, g_UpgradeTimerout) End Sub Private Function WriteToDevice_ByCustomProtocol(ByVal sendBuf() As Byte, ByVal sendLen As UInt16, ByRef recvBuf() As Byte, ByRef recvLen As UInt16, ByVal groupFlag As Boolean, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Dim retryCount As Byte = 0 Dim result As Boolean = False Dim retFlag As Boolean = False Dim timeTick As UInt32 Dim rLen As Integer = 0 Dim readIndex As UInt16 = 0 Dim readBuffNoDataTimeCount As Integer = 0 'Momo 2020-3-11 自定义协议中序列号累加 If g_SN_CustomProtocol < &HFF Then g_SN_CustomProtocol = g_SN_CustomProtocol + 1 Else g_SN_CustomProtocol = 0 End If Do RichTextBox_Show("TX retry = " & retryCount & ",", sendBuf, sendLen, COLOR_MESSAGE) readBuffNoDataTimeCount = 0 '发送前先把接受超时清零 retFlag = UartSendBuf(sendBuf, sendLen) '发送数据 readIndex = 0 WaitSendComp(sendLen) '等待发送出去 If g_DevType = DEV_TYPE.PB_485 Then Delay(0.8 * sendLen) End If If retFlag Then If groupFlag = False Then '对于 groupFlag = false 应该要做延时,不能一直不停的发 retFlag = False timeTick = My.Computer.Clock.TickCount Do Try rLen = Port.BytesToRead 'RichTextBox_Show("rLen = " & rLen & "...", sendBuf, sendLen, COLOR_MESSAGE) Catch ex As Exception rLen = 0 End Try If rLen > 0 Then '等待接收数据 timeTick = My.Computer.Clock.TickCount Port.Read(recvBuf, readIndex, rLen) readIndex += rLen readBuffNoDataTimeCount = 0 retFlag = True Else readBuffNoDataTimeCount = readBuffNoDataTimeCount + 1 If readBuffNoDataTimeCount >= 20 Then 'Momo 2020-3-11 对于自定义协议接收数据的判断:连续5次读到接收buffer为空 readBuffNoDataTimeCount = 0 Exit Do End If End If Delay(1) Loop Until (My.Computer.Clock.TickCount - timeTick) > timeout If retFlag Then RichTextBox_Show("RX", recvBuf, readIndex, COLOR_MESSAGE) recvLen = readIndex g_RcvedPackageLen = recvLen 'g_RcvedPackageLen 用于从回复包中提取机型编号 result = True Else RichTextBox_Show("No Data Received!", COLOR_ERROR) End If Else Delay(20) '如果是群发就不接收,直接延时20mS 'result = True 'Momo 2020-3-11:如果是群发,可能导致一直Do循环直到最大重试次数超出,然后返回错误,因此加这个值确保群发时默认发成功。 End If End If If result = True Then Exit Do retryCount += 1 Loop Until retryCount > maxRetry Return result End Function Private Function WriteToDevice(ByVal sendBuf() As Byte, ByVal sendLen As UInt16, ByRef recvBuf() As Byte, ByRef recvLen As UInt16, ByVal groupFlag As Boolean, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Dim retryCount As Byte = 0 Dim result As Boolean = False Dim retFlag As Boolean = False Dim timeTick As UInt32 Dim rLen As Integer = 0 Dim readIndex As UInt16 = 0 Do RichTextBox_Show("TX", sendBuf, sendLen, COLOR_MESSAGE) retFlag = UartSendBuf(sendBuf, sendLen) '发送数据 readIndex = 0 '重置接受缓存区指针 WaitSendComp(sendLen) '等待发送出去 If g_DevType = DEV_TYPE.PB_485 Then Delay(0.8 * sendLen) End If If retFlag Then If groupFlag = False Then '对于 groupFlag = false 应该要做延时,不能一直不停的发 retFlag = False timeTick = My.Computer.Clock.TickCount Do Try rLen = Port.BytesToRead Catch ex As Exception rLen = 0 End Try If rLen > 0 Then '等待接收数据 timeTick = My.Computer.Clock.TickCount Port.Read(recvBuf, readIndex, rLen) readIndex += rLen If g_DevType = DEV_TYPE.BLV_C1 Then If readIndex > FMT_C1.LEN_L AndAlso readIndex >= (recvBuf(FMT_C1.LEN_H) * 256 + recvBuf(FMT_C1.LEN_L)) Then retFlag = True Exit Do End If Else If readIndex > FMT.LEN AndAlso readIndex >= recvBuf(FMT.LEN) Then retFlag = True Exit Do End If End If End If Loop Until (My.Computer.Clock.TickCount - timeTick) > timeout Or (readIndex >= 255) If retFlag Then RichTextBox_Show("RX", recvBuf, readIndex, COLOR_MESSAGE) 'C1的Len是2bytes If g_DevType = DEV_TYPE.BLV_C1 Then If recvBuf(FMT_C1.CMD) = sendBuf(FMT_C1.CMD) + LOADER_CMD_OFFSET AndAlso recvBuf(FMT_C1.LEN_H) * 256 + recvBuf(FMT_C1.LEN_L) = readIndex AndAlso recvBuf(FMT_C1.PARAM) = sendBuf(FMT_C1.PARAM) AndAlso CalcCheckSum(recvBuf, readIndex) = 0 Then recvLen = readIndex result = True End If Else If recvBuf(FMT.CMD) = sendBuf(FMT.CMD) + LOADER_CMD_OFFSET AndAlso recvBuf(FMT.LEN) = readIndex AndAlso recvBuf(FMT.PARAM) = sendBuf(FMT.PARAM) AndAlso CalcCheckSum(recvBuf, readIndex) = 0 Then recvLen = readIndex result = True End If End If Else If readIndex > 0 Then RichTextBox_Show("RX", recvBuf, readIndex, COLOR_ERROR) Else RichTextBox_Show("No Data Received!", COLOR_ERROR) End If End If Else Delay(20) End If End If If result = True Then Exit Do retryCount += 1 Loop Until retryCount > maxRetry Return result End Function Private Sub WaitSendComp() Do 'Delay(1) Loop Until Port.BytesToWrite = 0 End Sub Private Sub WaitSendComp(ByVal count As Integer) Dim baudrate As Integer = Port.BaudRate Dim delayTime As Integer = 1000 * 10 * count / baudrate Dim timeEnd As Integer = My.Computer.Clock.TickCount + delayTime Do Application.DoEvents() Loop Until My.Computer.Clock.TickCount > timeEnd End Sub Private Function UartSendBuf(ByVal buf() As Byte, ByVal len As UInt16) As Boolean Try Port.DiscardOutBuffer() Port.DiscardInBuffer() Catch ex As Exception Return False End Try Try Port.Write(buf, 0, len) Catch ex As Exception Return False End Try Return True End Function Private Sub Delay(ByVal time As Integer) Dim timeEnd As Integer = My.Computer.Clock.TickCount + time Do Application.DoEvents() Loop Until My.Computer.Clock.TickCount > timeEnd End Sub Private Sub Btn_OpenPort_Click(sender As Object, e As EventArgs) Handles Btn_OpenPort.Click If Cbo_Port.Text = "" Then MsgBox("Please select a valid Com Port number!") : Exit Sub If Cbo_Baud.Text = "" Then MsgBox("Please select a properly Baud Rate!") : Exit Sub If Cbo_BusType.Text = "" Then MsgBox("Please select a Device Type!") : Exit Sub UpdateDevType() If Port.IsOpen = False Then SetSerialInfo(Val(Cbo_Baud.Text)) Try Port.Open() Catch ex As Exception MsgBox("Open Com Port fail:" & vbNewLine & ex.Message) : Exit Sub End Try Btn_OpenPort.Text = "Close Com Port" Cbo_Port.Enabled = False Cbo_Baud.Enabled = False Else Try Port.Close() Catch ex As Exception MsgBox("Close Com Port fail:" & vbNewLine & ex.Message) End Try Btn_OpenPort.Text = "Open Com Port" Cbo_Port.Enabled = True Cbo_Baud.Enabled = True End If If g_DevType = DEV_TYPE.PB_485 Then Select Case Cbo_Baud.Text Case 9600 Port.DtrEnable = False Case 2400 Port.DtrEnable = True Case Else 'MsgBox("The NanoPB just support baudrate for 2400bps or 9600bps!") Cbo_Baud.Text = 9600 Port.BaudRate = 9600 Port.DtrEnable = True End Select End If If Port.IsOpen Then UpdateDevType() Btn_OpenPort.ForeColor = Color.Green Else Btn_OpenPort.ForeColor = Color.Red End If UpdateDevType() End Sub Public Sub SetSerialInfo(ByVal baud As UInt32) With Port .PortName = Cbo_Port.Text .BaudRate = baud .DataBits = 8 .StopBits = IO.Ports.StopBits.One '停止位 .Parity = IO.Ports.Parity.None '奇偶校验位 '.DtrEnable = True End With End Sub Private Sub SetPortBaud(ByVal baud As UInt32) If Port.BaudRate = baud Then Console.WriteLine($"波特率:{baud}相同,不用设置") Return End If Select Case baud Case 9600 Port.BaudRate = 9600 If g_DevType = DEV_TYPE.PB_485 Then Port.DtrEnable = False Delay(1000) End If Case 2400 Port.BaudRate = 2400 If g_DevType = DEV_TYPE.PB_485 Then Port.DtrEnable = True Delay(1000) End If Case Else Port.BaudRate = baud End Select Delay(2) RichTextBox1.AppendText(vbCrLf & " *** 波特率设置成功:” & Port.BaudRate & vbCrLf) End Sub Dim g_SyncFlag As Boolean = False Private Sub Btn_Upgrade_Click(sender As Object, e As EventArgs) Handles Btn_Upgrade.Click JudgeGroupAddr() '更新群标志 If g_GroupAddrFlag Then '群升级标志 If g_UpgradeBtnPressCnt = 0 Then g_UpgradeBtnPressCnt += 1 g_UpgradeFlag = True Btn_Upgrade.Text = "正在同步中" g_SyncFlag = True Btn_Upgrade.BackColor = Color.Lime Btn_Search.Enabled = False GroupUpgradeDevice() '群升级’ g_UpgradeFlag = False g_UpgradeBtnPressCnt = 0 Btn_Upgrade.Text = "升级" Btn_Upgrade.BackColor = SystemColors.Control 'Btn_Search.Enabled = True ElseIf g_UpgradeBtnPressCnt = 1 Then g_UpgradeBtnPressCnt += 1 g_SyncFlag = False Btn_Upgrade.Text = "停止" Btn_Upgrade.BackColor = Color.Green Else g_UpgradeBtnPressCnt = 0 g_UpgradeFlag = False End If Else '单个升级,采用双向通讯 If g_UpgradeFlag = False Then RichTextBox1.Clear() g_UpgradeFlag = True Btn_Upgrade.Text = "Stop" Btn_Upgrade.BackColor = Color.Green Btn_Search.Enabled = False UpgradeDevice() '单对单升级 g_UpgradeFlag = False Btn_Upgrade.Text = "Upgrade" Btn_Upgrade.BackColor = SystemColors.Control Btn_Search.Enabled = True Else g_UpgradeFlag = False End If End If End Sub Private Sub GroupUpgradeDevice() If Port.IsOpen = False Then MsgBox("Please Open Com Port!") : Exit Sub DataGridView1.Rows.Clear() '清除表格 FillDataGridView() '填充表格 If g_SelectCount = 0 Then SetStatus("Please Select the device which you want to upgrade!", Color.Red) Return End If If Tb_HexFilePath.Text = "" Then SetStatus("Please Open Hex file!", Color.Red) Return End If If LoadDataFromFile(Tb_HexFilePath.Text) = False Then SetStatus("Hex file format error!", Color.Red) Return End If SetStatus("Handshaking...", COLOR_MESSAGE) showItemStatus("Handshaking", COLOR_MESSAGE) Dim devAddress As Byte = 0 '跳转指令和Boot搜索指令同时发5次 While g_SyncFlag If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If RichTextBox_Show("Handshak in bootloader", COLOR_ERROR) SearchDeviceCmd(0, SEARCH_TIMEROUT) SetPortBaud(Val(Cbo_Baud.Text)) RichTextBox_Show("Jump To Bootloader", COLOR_ERROR) AllAppJumpCmd(devAddress, 0, SEARCH_TIMEROUT) End While SetStatus("Set Parameter", COLOR_MESSAGE) showItemStatus("Set Parameter", COLOR_MESSAGE) If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If RichTextBox_Show("Set Parameter", COLOR_ERROR) SetParamCmd(Val(Cbo_Baud.Text), Val(Tb_Timeout.Text), g_maxRetry, g_UpgradeTimerout) SetPortBaud(Val(Cbo_Baud.Text)) SetStatus("Handshak again", COLOR_MESSAGE) showItemStatus("Handshak again", COLOR_MESSAGE) RichTextBox_Show("Handshak again", COLOR_ERROR) SearchDeviceCmd(g_maxRetry, g_UpgradeTimerout) SetStatus("Upgrading", COLOR_MESSAGE) showItemStatus("Upgrading", COLOR_MESSAGE) RichTextBox_Show("Upgrading", COLOR_ERROR) If DownloadData() Then SetStatus("Verfiy", COLOR_MESSAGE) showItemStatus("Verfiy", COLOR_MESSAGE) RichTextBox_Show("Verfiy", COLOR_ERROR) CheckCmd() SetStatus("Jump To App", COLOR_MESSAGE) showItemStatus("Jump To App", COLOR_MESSAGE) RichTextBox_Show("Jump To App", COLOR_ERROR) JumpToApp() SetStatus("Upgrade Completed", COLOR_NORMAL) showItemStatus("Upgrade Completed", COLOR_NORMAL) g_SuccessCount = g_SelectCount UpdateCountInfo() Else showItemStatus("Abort Upgrading", COLOR_ERROR) g_FailCount = g_SelectCount UpdateCountInfo() End If End Sub Private Sub FillDataGridView() Dim groupAddr(3) As Byte GetGroupAddr(groupAddr) Chk_UpgradeAllSel.Checked = True g_SearchCount = 0 g_SelectCount = 0 g_SuccessCount = 0 g_FailCount = 0 UpdateCountInfo() Dim index As UInt16 = 1 Dim address As Byte Dim pRowItemInfo As New ROW_ITEM_INFO Dim i As Byte Dim j As Byte Dim temp As UInt16 For i = 0 To 3 temp = &H1 For j = 0 To 7 If groupAddr(i) And temp Then address = i * 8 + j pRowItemInfo.index = index pRowItemInfo.upgradeCheck = True pRowItemInfo.address = address pRowItemInfo.devId = "" pRowItemInfo.runType = "" pRowItemInfo.btnAllChip = "Read" pRowItemInfo.btnEEP = "Read" AddItem(pRowItemInfo) index += 1 g_SelectCount += 1 UpdateCountInfo() End If temp *= 2 Next Next End Sub Private Sub UpgradeDevice() '确认端口是打开的 If Port.IsOpen = False Then MsgBox("Please open com port!") : Exit Sub Dim itemInfo As New ROW_ITEM_INFO Dim itemIndex As Integer = 0 Dim tmpLineCnt As Int16 = 0 SetStatus("", SystemColors.Control) '如果未选中设备’ If g_SelectCount = 0 Then SetStatus("Please select the device which you want to upgrade!", Color.Red) Return End If '如果没有打开Hex文件’ If Tb_HexFilePath.Text = "" Then SetStatus("Please open Hex file", Color.Red) Return End If '如果装载文件失败’ '装载后hex数据放在 g_LoaderDataBuffer 数组中 '最高地址放在 g_LoaderEndAddr 中 '有效数据长度 = g_LoaderEndAddr If LoadDataFromFile(Tb_HexFilePath.Text) = False Then SetStatus("Error to upgrade", Color.Red) Return End If Dim checkSum(3) As Byte CalcCheckSum(g_LoaderDataBuffer, g_LoaderEndAddr, checkSum) g_SuccessCount = 0 g_FailCount = 0 UpdateCountInfo() For Each pRow As DataGridViewRow In DataGridView1.Rows pRow.Cells(COLS.STATUS).Value = "" Next '遍历表格中的每一行 For Each pRow As DataGridViewRow In DataGridView1.Rows tmpLineCnt = tmpLineCnt + 1 If Port.IsOpen = False Then MsgBox("Please open com port!") : Exit Sub '跳出升级 If g_UpgradeFlag = False Then Exit For End If '如果该行勾选了升级’ If pRow.Cells(COLS.UPGRADE).Value Then '取出该行数据到 itemInfo UpdateRowItemInfo(pRow, itemInfo) Dim succFlag As Boolean = False Dim devAddress As Integer = itemInfo.address showItemStatus(itemIndex, "Operation...", COLOR_MESSAGE) Dim jumpFlag As Boolean = False Dim devId As String Dim bootFlag As String Dim devModel As String = "" Dim readValid As Boolean = False g_UpgradeRetryCnt = 0 '重试次数 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “开始握手!” & vbCrLf) lab_Upgrade_StartHandshaking: SetStatus("DevAdd: " & devAddress & ", Handshaking...", COLOR_MESSAGE) '先用2400bps在Bootloader区搜索设备 If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If readValid = SearchDeviceCmd(devAddress, devId, bootFlag, devModel, g_maxRetry, 100) '如果在Boot区未搜索到设备,则在App区再搜索’ If readValid = False Then 'App 搜索 SetPortBaud(Val(Cbo_Baud.Text)) '设置波特率 readValid = AllAppSearchDeviceCmd(devAddress, devId, bootFlag, devModel, g_maxRetry, 100) End If '握手成功 If readValid Then g_UpgradeRetryCnt = 0 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “握手成功!” & vbCrLf) RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “开始跳转到Bootloader!” & vbCrLf) lab_Upgrade_JumpToBootLoader: pRow.Cells(COLS.RUN_FLAG).Value = bootFlag If pRow.Cells(COLS.RUN_FLAG).Value = "APP" Then SetPortBaud(Val(Cbo_Baud.Text)) '设置波特率 SetStatus("DevAdd: " & devAddress & ", Jump to Bootloader", COLOR_MESSAGE) If AllAppJumpCmd(devAddress, g_maxRetry, g_UpgradeTimerout) Then Delay(1000) If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If '设置波特率 If SearchDeviceCmd(devAddress, devId, bootFlag, devModel, g_maxRetry, g_UpgradeTimerout) Then jumpFlag = True End If End If Else jumpFlag = True End If If jumpFlag Then g_UpgradeRetryCnt = 0 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “跳转到Bootloader成功,开始更新参数!” & vbCrLf) lab_Upgrade_SetParameter: SetStatus("DevAdd: " & devAddress & ", Set Baudrate...", COLOR_MESSAGE) If SetParamCmd(devAddress, Val(Cbo_Baud.Text), Val(Tb_Timeout.Text)) Then g_UpgradeRetryCnt = 0 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “更新参数成功,开始在boot区握手!” & vbCrLf) lab_Upgrade_HandshakInBootloader: SetPortBaud(Val(Cbo_Baud.Text)) SetStatus("DevAdd: " & devAddress & ",Handshaking...", COLOR_MESSAGE) If SearchDeviceCmd(devAddress, devId, bootFlag, devModel, g_maxRetry + 3, g_UpgradeTimerout) Then g_UpgradeRetryCnt = 0 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “在boot区握手成功,开始写入Flash!” & vbCrLf) lab_Upgrade_WriteFlash: SetStatus("DevAdd: " & devAddress & ",Load Hex Data...", COLOR_MESSAGE) SetStatus("DevAdd: " & devAddress & ",Upgrading...", COLOR_MESSAGE) If DownloadData(devAddress) Then g_UpgradeRetryCnt = 0 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “写入Flash成功,开始验证Flash!” & vbCrLf) lab_Upgrade_VerfiyFlash: SetStatus("DevAdd: " & devAddress & ",Verifying...", COLOR_MESSAGE) 'If CheckCmd(devAddress, g_maxRetry, g_UpgradeTimerout) Then If CheckCmd(devAddress, 0, 3000) Then g_UpgradeRetryCnt = 0 RichTextBox1.AppendText(vbCrLf & "行号:" & tmpLineCnt & “验证Flash成功,跳转到App!” & vbCrLf) lab_Upgrade_JumpToApp: SetStatus("DevAdd: " & devAddress & ",Reboot App...", COLOR_MESSAGE) If JumpToApp(devAddress, g_maxRetry, g_UpgradeTimerout) Then SetStatus("DevAdd: " & devAddress & ",Upgrade Completed!", COLOR_MESSAGE) showItemStatus(itemIndex, "Upgrade Complete", COLOR_NORMAL) succFlag = True Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_JumpToApp Else showItemStatus(itemIndex, "Jump to Bootloader fail", COLOR_ERROR) End If End If Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_VerfiyFlash Else showItemStatus(itemIndex, "Verify fail", COLOR_ERROR) End If End If Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_WriteFlash Else showItemStatus(itemIndex, "Write Flash fail", COLOR_ERROR) End If End If Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_HandshakInBootloader Else showItemStatus(itemIndex, "Handshak in Bootloader fail", COLOR_ERROR) End If End If Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_SetParameter Else showItemStatus(itemIndex, "Set Parameter fail", COLOR_ERROR) End If End If Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_JumpToBootLoader Else showItemStatus(itemIndex, "Jump to Bootloader fail", COLOR_ERROR) End If End If Else If (g_UpgradeRetryCnt < g_UpgradeMaxRetry) Then g_UpgradeRetryCnt = g_UpgradeRetryCnt + 1 GoTo lab_Upgrade_StartHandshaking Else showItemStatus(itemIndex, "Handshak fail", COLOR_ERROR) End If End If If succFlag Then g_SuccessCount += 1 Else g_FailCount += 1 End If UpdateCountInfo() End If itemIndex += 1 Next End Sub Private Sub UpdateRowItemInfo(ByVal pRow As DataGridViewRow, ByRef itemInfo As ROW_ITEM_INFO) itemInfo.index = pRow.Cells(COLS.INDEX).Value itemInfo.upgradeCheck = pRow.Cells(COLS.UPGRADE).Value itemInfo.address = pRow.Cells(COLS.ADDR).Value itemInfo.devId = pRow.Cells(COLS.DEVID).Value itemInfo.runType = pRow.Cells(COLS.RUN_FLAG).Value itemInfo.status = pRow.Cells(COLS.STATUS).Value itemInfo.btnAllChip = pRow.Cells(COLS.READ_ALL_CHIP).Value itemInfo.btnEEP = pRow.Cells(COLS.READ_EEPROM).Value End Sub Private Function DownloadData(ByVal address As Byte) As Boolean Dim flashAddr As UInt32 = g_HexStartAdd_For_C1 '如果hex文件首行是type 04 数据则将此数据作为起始地址 Dim flashData As UInt32 = g_HexStartAdd_For_C1 Dim flashEndAddr As UInt32 = g_LoaderEndAddr '结束地址 Dim loaderNum As Byte '下载进度 Dim tmpPackageCnt As UInt16 = 0 If Chk_BackupUpgrade.Checked = True Then '如果备份程序选中,便将该程序抄录FLASH备份区中,数据地址应该偏移 '备份区域偏移地址 - 0x040000 flashAddr += g_BLVCxBackupAppOffsetAddr flashEndAddr += g_BLVCxBackupAppOffsetAddr RichTextBox1.AppendText(vbCrLf & “ --------- 开始写入备份数据!” & vbCrLf) Do If WriteFlashCmd(address, flashAddr, g_LoaderDataBuffer, flashData, g_maxRetry, g_UpgradeTimerout) Then tmpPackageCnt = tmpPackageCnt + 1 RichTextBox1.AppendText(vbCrLf & “ --------- 写入备份Flash数据,包序号: ” & tmpPackageCnt & "写入地址:" & flashAddr & vbCrLf) flashAddr += g_Download_DataLenght_Pre_Package flashData += g_Download_DataLenght_Pre_Package loaderNum = (flashAddr * 100) / flashEndAddr If loaderNum > 100 Then loaderNum = 100 ToolStripProgressBar1.Value = loaderNum If g_UpgradeFlag = False Then Return False Else Return False End If Loop Until flashAddr >= flashEndAddr Else RichTextBox1.AppendText(vbCrLf & “ 开始擦除Flash!” & vbCrLf) If EraseFlashCmd(address, g_maxRetry, ERASE_CMD_TIMEROUT) Then '擦除Flash RichTextBox1.AppendText(vbCrLf & “ 擦除Flash成功,开始写入数据!” & vbCrLf) Do If WriteFlashCmd(address, flashAddr, g_LoaderDataBuffer, flashAddr, g_maxRetry, g_UpgradeTimerout) Then tmpPackageCnt = tmpPackageCnt + 1 RichTextBox1.AppendText(vbCrLf & “ --------- 写入Flash数据,包序号: ” & tmpPackageCnt & vbCrLf) flashAddr += g_Download_DataLenght_Pre_Package loaderNum = (flashAddr * 100) / flashEndAddr If loaderNum > 100 Then loaderNum = 100 ToolStripProgressBar1.Value = loaderNum If g_UpgradeFlag = False Then Return False Else Return False End If Loop Until flashAddr >= flashEndAddr Else RichTextBox1.AppendText(vbCrLf & “ 擦除Flash失败!” & vbCrLf) Return False End If End If ToolStripProgressBar1.Value = 100 Return True End Function Private Function CheckCmd(ByVal address As Byte, ByVal maxRetry As Integer, ByVal timeout As Integer) As Boolean Dim crcBuf(4096) As Byte Dim crcBufLen As UInt32 Dim tmpResultIdx As UInt16 = 0 Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) '2022-05-07 曹聪 修改 数据包整包校验有误 If g_DevType = DEV_TYPE.BLV_C1 Then If Chk_BackupUpgrade.Checked = True Then '如果备份程序选中,便将该程序抄录FLASH备份区中,数据地址应该偏移 Dim flashEndAddr As UInt32 = g_LoaderEndAddr flashEndAddr += g_BLVCxBackupAppOffsetAddr g_SendBuffer(g_ParamOffset) = (flashEndAddr >> 16) And &HFF g_SendBuffer(g_ParamOffset + 1) = (flashEndAddr >> 8) And &HFF g_SendBuffer(g_ParamOffset + 2) = flashEndAddr And &HFF Else g_SendBuffer(g_ParamOffset) = (g_LoaderEndAddr >> 16) And &HFF g_SendBuffer(g_ParamOffset + 1) = (g_LoaderEndAddr >> 8) And &HFF g_SendBuffer(g_ParamOffset + 2) = g_LoaderEndAddr And &HFF End If g_Download_ParamLenght_Pre_Package = g_Download_DataLenght_Pre_Package + 3 '往下发数据+地址总长度,C1的地址多一个byte Else g_SendBuffer(g_ParamOffset) = g_LoaderEndAddr \ 256 g_SendBuffer(g_ParamOffset + 1) = g_LoaderEndAddr Mod 256 g_Download_ParamLenght_Pre_Package = g_Download_DataLenght_Pre_Package + 2 '往下发数据+地址总长度,C1的地址多一个byte End If CalcCRC16(g_LoaderDataBuffer, g_LoaderEndAddr, crcBuf, crcBufLen) Array.Copy(crcBuf, 0, g_SendBuffer, g_ParamOffset + 3, crcBufLen) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_CHECK, crcBufLen + 3, address) If g_DevType = DEV_TYPE.BLV_C1 Then tmpResultIdx = FMT_C1.PARAM + 1 Else tmpResultIdx = FMT.PARAM + 1 End If Dim tmpLen As UInt16 = 0 If g_DevType = DEV_TYPE.BLV_C1 Then tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else tmpLen = g_SendBuffer(FMT.LEN) End If If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, maxRetry, timeout) Then If g_RecvBuffer(tmpResultIdx) = &H1 Then Return True Else RichTextBox1.AppendText(vbCrLf & " xxxx CRC 校验错误!") Return False End If Else Return False End If End Function Private Sub CheckCmd() Dim crcBuf(128) As Byte Dim crcBufLen As UInt16 Dim tmpLen As UInt16 = 0 Array.Clear(g_SendBuffer, 0, g_SendBuffer.Length) Array.Clear(g_RecvBuffer, 0, g_RecvBuffer.Length) If g_DevType = DEV_TYPE.BLV_C1 Then If Chk_BackupUpgrade.Checked = True Then '如果备份程序选中,便将该程序抄录FLASH备份区中,数据地址应该偏移 Dim flashEndAddr As UInt32 = g_LoaderEndAddr flashEndAddr += g_BLVCxBackupAppOffsetAddr g_SendBuffer(g_ParamOffset) = (flashEndAddr >> 16) And &HFF g_SendBuffer(g_ParamOffset + 1) = (flashEndAddr >> 8) And &HFF g_SendBuffer(g_ParamOffset + 2) = flashEndAddr And &HFF Else g_SendBuffer(g_ParamOffset) = (g_LoaderEndAddr >> 16) And &HFF g_SendBuffer(g_ParamOffset + 1) = (g_LoaderEndAddr >> 8) And &HFF g_SendBuffer(g_ParamOffset + 2) = g_LoaderEndAddr And &HFF End If CalcCRC16(g_LoaderDataBuffer, g_LoaderEndAddr, crcBuf, crcBufLen) Array.Copy(crcBuf, 0, g_SendBuffer, g_ParamOffset + 3, crcBufLen) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_CHECK, crcBufLen + 2) tmpLen = g_SendBuffer(FMT_C1.LEN_H) * 256 + g_SendBuffer(FMT_C1.LEN_L) Else g_SendBuffer(g_ParamOffset) = g_LoaderEndAddr \ 256 g_SendBuffer(g_ParamOffset + 1) = g_LoaderEndAddr Mod 256 CalcCRC16(g_LoaderDataBuffer, g_LoaderEndAddr, crcBuf, crcBufLen) Array.Copy(crcBuf, 0, g_SendBuffer, g_ParamOffset + 2, crcBufLen) FillSendBuf(g_SendBuffer, CMD.LOADER_CMD_CHECK, crcBufLen + 2) tmpLen = g_SendBuffer(FMT.LEN) End If WriteToDevice(g_SendBuffer, tmpLen, g_RecvBuffer, g_RecvLen, g_GroupAddrFlag, g_maxRetry, g_UpgradeTimerout) End Sub Private Function DownloadData() As Boolean Dim flashAddr As UInt16 = 0 Dim loaderNum As Byte '下载进度 Dim address As Byte Dim i As Byte For i = 0 To g_maxRetry EraseFlashCmd(address, 0, ERASE_CMD_TIMEROUT) '擦除Flash Delay(ERASE_CMD_TIMEROUT) Next Do WriteFlashCmd(address, flashAddr, g_LoaderDataBuffer, flashAddr, g_maxRetry, g_UpgradeTimerout) flashAddr += 128 loaderNum = (flashAddr * 100) / g_LoaderEndAddr If loaderNum > 100 Then loaderNum = 100 ToolStripProgressBar1.Value = loaderNum If g_UpgradeFlag = False Then Return False Loop Until flashAddr >= g_LoaderEndAddr Return True End Function ''' ''' 获取文件的MD5值 ''' 返回Byte数组值 ''' ''' 文件路径 ''' Public Function GetMd5(filepath As String) As Byte() Dim FileStr As FileStream = New FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read) Dim data(FileStr.Length - 1) As Byte FileStr.Read(data, 0, data.Length) Dim md5s As Byte() = MD5.Create().ComputeHash(data) Console.WriteLine("Get MD5 File:" & BitConverter.ToString(md5s).Replace("-", " ")) Return md5s End Function Private Function LoadDataFromFile(ByVal path As String) As Boolean Array.Clear(g_LoaderHexFileBuffer, 0, g_LoaderHexFileBuffer.Length) Dim fileLen As Int32 = 0 Try Dim fs As New System.IO.FileStream(path, IO.FileMode.Open, IO.FileAccess.Read) If fs.Length <= LOADER_FILE_SIZE_MAX Then fileLen = fs.Length fs.Read(g_LoaderHexFileBuffer, 0, fs.Length) 'Dim data(fs.Length - 1) As Byte 'fs.Read(data, 0, data.Length) 'Dim md5s As Byte() = MD5.Create().ComputeHash(data) 'Console.WriteLine("MD5 File:" & BitConverter.ToString(md5s).Replace("-", " ")) Else Return False End If fs.Close() Catch ex As Exception Return False End Try 'GetMd5(path) If Chk_LogicFile.Checked = True Then Return LogicFileToData(g_LoaderHexFileBuffer, fileLen, g_LoaderDataBuffer, g_HexStartAdd_For_C1, g_LoaderEndAddr) Else '起始这函数中有重新复制写入的起始地址和结束地址,下发配置版本可以改这个函数直接将起始地址和结束修改了,其他都可以不变 Return HexFileToData(g_LoaderHexFileBuffer, g_LoaderDataBuffer, g_LoaderEndAddr) End If End Function Private Function HexFileToData(ByVal hexBuffer() As Byte, ByVal dataBuffer() As Byte, ByRef endAddr As UInt32) As Boolean Dim i As UInt32 '行数 Dim LineCnt As UInt32 = 0 Dim DataType_00_Idx As UInt32 = 0 '清空数据缓存区域’ For i = 0 To dataBuffer.Length - 1 dataBuffer(i) = &HFF Next '本行数据缓存’ Dim dataStrBuf(31) As Byte Dim dataValBuf(15) As Byte '首地址标记’ Dim headAddrFlag As Boolean = True '本行Cks值’ '本行地址值’ Dim tmpLineAdd As Integer = 0 '偏移地址 0x04 数据类型指示偏移地址 Dim LineAddOffestBase As Integer = 0 '结束地址’ endAddr = 0 Dim flashAddressBuf(3) As Byte Dim flashAddress As UInt32 'Hex格式解析,每一行以0D 0A结束 '文本串::1000000000800020A500010061090100AF0001008F '分解为20 Bytes Hex数据 ' '--- | ----- | ---| ----------------------------------------------------------|---- 'Len | ADD |Type| Data | CKS '--- | ----- | ---| ----------------------------------------------------------|---- ' B0 | B1 B2 | B3 | B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 | B20 ':10 | 00 00 | 00 | 00 80 00 20 A5 00 01 00 61 09 01 00 AF 00 01 00 | 8F ' ---| -----| ---| ----------------------------------------------------------|---- '1: 每行固定以“:”开头 '2:B0 :数据长度 '3:B1~B2 :数据地址 B1为地址高位,B2为地址低位 '4:B3 :数据类型 ' 00' Data Record //数据记录 ' 01' End of File Record //文件结束记录 ' 02' Extended Segment Address Record //扩展段地址记录 ' 03' Start Segment Address Record //开始段地址记录 ' 04' Extended Linear Address Record //扩展线性地址记录 ' 05' Start Linear Address Record //开始线性地址记录 '5:B4~B19 :数据内容 '6:B20 :校验码 '’'''''''''''’'' 'Hex 数据首地址确认方式:将第一个00类型的数据的地址作为起始地址 '因此,最低地址必须出现在第一个00类型数据中 For i = 0 To hexBuffer.Length - 1 '首先找到冒号 If hexBuffer(i) = &H3A Then '&H3A = ":" LineCnt += 1 '----------------------------------------------------------------------------------------’ 'B0:数据长度 '----------------------------------------------------------------------------------------’ Dim dataLen As UInt32 = (StrToHex(hexBuffer(i + 1)) * 16 + StrToHex(hexBuffer(i + 2))) If dataLen > 0 Then '----------------------------------------------------------------------------------------’ 'By:CheckSum '----------------------------------------------------------------------------------------’ Dim checkSum As Byte = (StrToHex(hexBuffer(i + 9 + dataLen * 2)) * 16 + StrToHex(hexBuffer(i + 10 + dataLen * 2))) '取出整行数据 Dim rowDataStrBuf(41) As Byte Dim rowDataValBuf(20) As Byte Dim rowLen As UInt16 Array.Clear(rowDataStrBuf, 0, 42) Array.Clear(rowDataValBuf, 0, 21) rowLen = (dataLen * 2) + 10 Array.Copy(hexBuffer, i + 1, rowDataStrBuf, 0, rowLen) StrToHex(rowDataValBuf, rowDataStrBuf, rowLen / 2) Dim tempCheckSum As Byte = CalcCheckSum(rowDataValBuf, rowLen / 2) If tempCheckSum <> &HFF Then Return False 'CheckSum校验不通过,返回错误 End If '----------------------------------------------------------------------------------------’ 'B4~Bx:数据内容 '----------------------------------------------------------------------------------------’ Array.Clear(dataStrBuf, 0, 32) Array.Clear(dataValBuf, 0, 16) Array.Copy(hexBuffer, i + 9, dataStrBuf, 0, dataLen * 2) StrToHex(dataValBuf, dataStrBuf, dataLen) End If '----------------------------------------------------------------------------------------’ 'B1~B2:取出地址位的值 '----------------------------------------------------------------------------------------’ Array.Copy(hexBuffer, i + 3, flashAddressBuf, 0, 4) '本行地址取出来放在 flashAddress中’ StrToHex(tmpLineAdd, flashAddressBuf) flashAddress = LineAddOffestBase + tmpLineAdd ''第一行取得的地址必须是0,否则就返回错误’ 'If headAddrFlag Then ' headAddrFlag = False ' If flashAddress <> 0 Then Return False 'End If '----------------------------------------------------------------------------------------’ 'B3:数据类型 '----------------------------------------------------------------------------------------’ Dim dataType = StrToHex(hexBuffer(i + 8)) Select Case dataType Case 0 '数据记录 DataType_00_Idx = DataType_00_Idx + 1 '将第一个00类型数据的地址作为起始地址, 保存到 g_HexStartAdd_For_C1 If DataType_00_Idx = 1 Then g_HexStartAdd_For_C1 = flashAddress End If Array.Copy(dataValBuf, 0, dataBuffer, flashAddress, dataLen) endAddr = flashAddress + dataLen Console.WriteLine("包:" & DataType_00_Idx.ToString & "地址:" & flashAddress &" 长度:" & dataLen) Case 1 '文件结束 If endAddr = 0 Then Return False Else 'MsgBox(“数据装载成功,行数=” & LineCnt & “ , EndAdd = ” & endAddr) Return True End If Case 2 '扩展段地址’ 'MsgBox(“数据装载异常,第 " & LineCnt & " 行数据类型为 02,代码当前未对此类数据做处理!") Continue For Case 3 '开始段地址’ 'MsgBox(“数据装载异常,第 " & LineCnt & " 行数据类型为 03,代码当前未对此类数据做处理!") Continue For Case 4 '扩展线性地址’ If dataLen = 2 Then LineAddOffestBase = (dataValBuf(0) * 256 + dataValBuf(1)) * 65536 Else Return False '确认DataLen必须是2,否则报错’ End If Case 5 '开始线性地址’ 'MsgBox(“数据装载异常,第 " & LineCnt & " 行数据类型为 05,代码当前未对此类数据做处理!") Continue For Case Else Return False End Select 'If headAddrFlag Then ' headAddrFlag = False ' If flashAddress <> 0 Then Return False 'End If End If Next Return False End Function ''' ''' 逻辑文件转数据 ''' ''' 文件缓存 ''' 数据 ''' ''' False:文件打开失败、True:文件打开成功 Private Function LogicFileToData(ByVal logicBuffer() As Byte, fileLen As Int32, ByVal dataBuffer() As Byte, ByRef startAddr As UInt32, ByRef endAddr As UInt32) As Boolean '逻辑文件地址 0x090000~0x0FFFFF 文件最大为0x6FFFF - 458751Byte '#define LOGIC_DataFlag 0xCC060001 //逻辑标志 '#define FLASH_LOGIC_FILE_ADDRESS 0x090000 '#define FLASH_LOGIC_DataFlag_ADDRESS 0x090000 //文件标志位 - 4Byte '#define FLASH_LOGIC_DataSize_ADDRESS 0x090004 //文件长度 - 4Byte '#define FLASH_LOGIC_DataMD5_ADDRESS 0x090008 //文件MD5校验值 - 16Byte '#define FLASH_LOGIC_DataStart_ADDRESS 0x090200 //数据存放起始地址 '#define FLASH_LOGIC_DataEnd_ADDRESS 0x0FFFFF //数据存放结束地址 '将内容填充正确 'g_HexStartAdd_For_C1 - 文件写入起始地址 'endAddr - 文件写入结束地址 Dim flashAddress As Int32 = &H90000 Dim logicDataLen As Int32 = fileLen If logicDataLen > 458751 Then Return False End If g_HexStartAdd_For_C1 = flashAddress Dim temp_buff(28) As Byte temp_buff(0) = &H1 temp_buff(1) = &H0 temp_buff(2) = &H6 temp_buff(3) = &HCC temp_buff(4) = logicDataLen And &HFF temp_buff(5) = (logicDataLen >> 8) And &HFF temp_buff(6) = (logicDataLen >> 16) And &HFF temp_buff(7) = (logicDataLen >> 24) And &HFF Array.Copy(temp_buff, 0, dataBuffer, flashAddress, 8) flashAddress += 8 Console.WriteLine($"数据长度:{logicDataLen} - " & Hex(logicDataLen) & " BUFF:" & BitConverter.ToString(temp_buff).Replace("-", " ")) temp_buff = MD5.Create.ComputeHash(logicBuffer, 0, logicDataLen) Array.Copy(temp_buff, 0, dataBuffer, flashAddress, 16) Console.WriteLine("MD5:" & BitConverter.ToString(temp_buff).Replace("-", " ")) flashAddress = &H90200 Array.Copy(logicBuffer, 0, dataBuffer, flashAddress, logicDataLen) endAddr = flashAddress + logicDataLen Return True End Function Private Function toupper(val As Byte) As Byte If val >= &H61 AndAlso val <= &H7A Then Return (val - &H20) Else Return val End If End Function Private Sub StrToHex(pbDest() As Byte, pbSrc() As Byte, nLen As UInt16) Dim h1 As Byte Dim h2 As Byte Dim s1 As Byte Dim s2 As Byte Dim i As UInt16 For i = 0 To nLen - 1 h1 = pbSrc(2 * i) h2 = pbSrc(2 * i + 1) s1 = toupper(h1) - &H30 If s1 > 9 Then s1 -= 7 End If s2 = toupper(h2) - &H30 If s2 > 9 Then s2 -= 7 End If pbDest(i) = s1 * 16 + s2 Next End Sub Private Sub StrToHex(ByRef pbDest As UInt16, pbSrc() As Byte) Dim pBufDest(1) As Byte Dim h1 As Byte Dim h2 As Byte Dim s1 As Byte Dim s2 As Byte Dim i As UInt16 For i = 0 To 2 - 1 h1 = pbSrc(2 * i) h2 = pbSrc(2 * i + 1) s1 = toupper(h1) - &H30 If s1 > 9 Then s1 -= 7 End If s2 = toupper(h2) - &H30 If s2 > 9 Then s2 -= 7 End If pBufDest(i) = s1 * 16 + s2 Next 'pbDest = (pBufDest(0) << 8) + pBufDest(1) pbDest = pBufDest(0) * 256 + pBufDest(1) End Sub Private Function StrToHex(ByVal src) As Byte If src >= &H30 AndAlso src <= &H39 Then Return (src - &H30) ElseIf src >= &H41 AndAlso src <= &H46 Then Return (src - &H41 + 10) ElseIf src >= &H61 AndAlso src <= &H66 Then Return (src - &H61 + 10) Else Return 0 End If End Function Private Sub showItemStatus(ByVal rowIndex As Integer, ByVal status As String, ByVal clr As Color) DataGridView1.Rows.Item(rowIndex).Cells(COLS.STATUS).Value = status DataGridView1.Rows.Item(rowIndex).Cells(COLS.STATUS).Style.ForeColor = clr End Sub Private Sub showItemStatus(ByVal status As String, ByVal clr As Color) For Each pRow As DataGridViewRow In DataGridView1.Rows pRow.Cells(COLS.STATUS).Value = status pRow.Cells(COLS.STATUS).Style.ForeColor = clr Next End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click If Chk_LogicFile.Checked = True Then '选中当前是下发逻辑配置文件 Dim dlg As New OpenFileDialog dlg.InitialDirectory = Application.StartupPath dlg.Filter = "Logic File|*.dat;*.ihex" Dim oldPath As String = Tb_HexFilePath.Text If System.IO.File.Exists(oldPath) Then dlg.InitialDirectory = System.IO.Path.GetDirectoryName(oldPath) dlg.FileName = oldPath Else dlg.InitialDirectory = Application.StartupPath End If If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then Tb_HexFilePath.Text = dlg.FileName btn_Reload.PerformClick() End If Else Dim dlg As New OpenFileDialog dlg.InitialDirectory = Application.StartupPath dlg.Filter = "HEX File|*.hex;*.ihex" Dim oldPath As String = Tb_HexFilePath.Text If System.IO.File.Exists(oldPath) Then dlg.InitialDirectory = System.IO.Path.GetDirectoryName(oldPath) dlg.FileName = oldPath Else dlg.InitialDirectory = Application.StartupPath End If If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then Tb_HexFilePath.Text = dlg.FileName btn_Reload.PerformClick() End If End If 'lab_HexLastModifyDate.Text = IO.File.GetLastWriteTime(Tb_HexFilePath.Text) End Sub Private Sub Chk_UpgradeAllSel_CheckedChanged(sender As Object, e As EventArgs) Handles Chk_UpgradeAllSel.CheckedChanged If g_GroupAddrFlag = False Then If Chk_UpgradeAllSel.Checked Then For Each pRow As DataGridViewRow In DataGridView1.Rows pRow.Cells.Item(COLS.UPGRADE).Value = True Next g_SelectCount = DataGridView1.Rows.Count Else For Each pRow As DataGridViewRow In DataGridView1.Rows pRow.Cells.Item(COLS.UPGRADE).Value = False Next g_SelectCount = 0 End If UpdateCountInfo() End If End Sub Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick Try If e.ColumnIndex = COLS.READ_ALL_CHIP Then ShowReadFlash(32 * 1024) ElseIf e.ColumnIndex = COLS.READ_APP Then ShowReadFlash(BOOT_START_ADDR) ElseIf e.ColumnIndex = COLS.READ_EEPROM Then ShowReadEEPROM() ElseIf e.ColumnIndex = COLS.UPGRADE Then If DataGridView1.Rows(e.RowIndex).Cells(COLS.UPGRADE).EditedFormattedValue Then g_SelectCount += 1 Else If g_SelectCount > 0 Then g_SelectCount -= 1 End If End If UpdateCountInfo() End If Catch ex As Exception End Try End Sub Private Sub ShowReadEEPROM() Dim readFlashDlg As New ReadFlash Dim rowIndex As UInt16 = DataGridView1.CurrentCell.RowIndex Dim address As Byte = DataGridView1.Rows(rowIndex).Cells(COLS.ADDR).Value Dim devId As String Dim bootFlag As String Dim devModel As String If g_ReadEepBtnPressCnt = 0 Then g_ReadEepBtnPressCnt = 1 DataGridView1.Rows(rowIndex).Cells(COLS.READ_EEPROM).Value = "正在同步" While g_ReadEepBtnPressCnt = 1 If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If RichTextBox_Show("发送Boot搜索命令", COLOR_ERROR) If SearchDeviceCmd(address, devId, bootFlag, devModel, 0, SEARCH_TIMEROUT) Then DataGridView1.Rows(rowIndex).Cells(COLS.READ_EEPROM).Value = "BOOT区" End If SetPortBaud(Val(Cbo_Baud.Text)) RichTextBox_Show("发送APP跳转命令", COLOR_ERROR) AllAppJumpCmd(address, 0, SEARCH_TIMEROUT) Application.DoEvents() End While ElseIf g_ReadEepBtnPressCnt = 1 Then g_ReadEepBtnPressCnt = 2 If DataGridView1.Rows(rowIndex).Cells(COLS.READ_EEPROM).Value = "BOOT区" Then DataGridView1.Rows(rowIndex).Cells(COLS.READ_EEPROM).Value = "正在读取" readFlashDlg.Show() SetStatus(readFlashDlg.ToolStripStatusLabel1, "读取EEPROM:正在读取地址" & address, COLOR_MESSAGE) If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If If SetParamCmd(address, Val(Cbo_Baud.Text), Val(Tb_Timeout.Text)) Then SetPortBaud(Val(Cbo_Baud.Text)) If SearchDeviceCmd(address, devId, bootFlag, devModel, g_maxRetry, g_UpgradeTimerout) Then If ReadEeprom(readFlashDlg, address) Then SetStatus(readFlashDlg.ToolStripStatusLabel1, "地址" & address & "读取完成", COLOR_MESSAGE) g_ReadBtnPressCnt = 0 DataGridView1.Rows(rowIndex).Cells(COLS.READ_EEPROM).Value = "读取" End If End If End If Else SetStatus("还没有跳到BOOT区,读取失败", COLOR_ERROR) End If ElseIf g_ReadEepBtnPressCnt = 2 Then g_ReadEepBtnPressCnt = 0 End If End Sub 'ColumnIndex Private Sub ShowReadFlash(ByVal endAddr As UInt32) Dim readFlashDlg As New ReadFlash Dim rowIndex As UInt16 = DataGridView1.CurrentCell.RowIndex '行号 Dim columnIndex As UInt16 = DataGridView1.CurrentCell.ColumnIndex '列号 Dim address As Byte = DataGridView1.Rows(rowIndex).Cells(COLS.ADDR).Value Dim devId As String = "" Dim bootFlag As String = "" Dim devModel As String = "" If g_ReadBtnPressCnt = 0 Then g_ReadBtnPressCnt = 1 DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "正在同步" While g_ReadBtnPressCnt = 1 If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If RichTextBox_Show("发送Boot搜索命令", COLOR_ERROR) If SearchDeviceCmd(address, devId, bootFlag, devModel, 0, SEARCH_TIMEROUT) Then DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "BOOT区" End If SetPortBaud(Val(Cbo_Baud.Text)) RichTextBox_Show("发送APP跳转命令", COLOR_ERROR) AllAppJumpCmd(address, 0, SEARCH_TIMEROUT) Application.DoEvents() End While ElseIf g_ReadBtnPressCnt = 1 Then g_ReadBtnPressCnt = 2 If DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "BOOT区" Then DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "正在读取" readFlashDlg.Show() SetStatus(readFlashDlg.ToolStripStatusLabel1, "读取FLASH:正在读取地址" & address, COLOR_MESSAGE) If Not Cbo_BusType.Text = "BLV_C1" Then SetPortBaud(2400) '设置波特率 Else SetPortBaud(HANDSHAKE_BAUD) '设置波特率 End If If SetParamCmd(address, Val(Cbo_Baud.Text), Val(Tb_Timeout.Text)) Then SetPortBaud(Val(Cbo_Baud.Text)) If SearchDeviceCmd(address, devId, bootFlag, devModel, g_maxRetry, g_UpgradeTimerout) Then If ReadFlash(readFlashDlg, address, endAddr) Then SetStatus(readFlashDlg.ToolStripStatusLabel1, "地址" & address & "读取完成", COLOR_MESSAGE) g_ReadBtnPressCnt = 0 DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "读取" End If End If End If Else SetStatus("还没有跳到BOOT区,读取失败", COLOR_ERROR) g_ReadBtnPressCnt = 0 DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "读取" End If ElseIf g_ReadBtnPressCnt = 2 Then g_ReadBtnPressCnt = 0 DataGridView1.Rows(rowIndex).Cells(columnIndex).Value = "读取" End If End Sub Private Sub RichTextBox_AddTick() Dim str As String = "" Dim sp As TimeSpan Try str = "[" str += $"{Now.Year }{Now.Month.ToString.PadLeft(2, "0")}{Now.Day.ToString.PadLeft(2, "0")}{Now.Hour.ToString.PadLeft(2, "0")}{Now.Minute.ToString.PadLeft(2, "0")}{Now.Second.ToString.PadLeft(2, "0")}{Now.Millisecond.ToString.PadLeft(3, "0")}" str += "] [" sp = (Now - g_RichTextBoxLastTick) str += sp.TotalMilliseconds.ToString.PadLeft(5, " ") str += "]" RichTextBox1.AppendText(str) g_RichTextBoxLastTick = Now Catch ex As Exception End Try End Sub Public Sub RichTextBox_Show(ByVal str As String, ByVal cor As Color) Dim tempSelStart As Integer Dim tempSelLenght As Integer Try RichTextBox_AddTick() tempSelStart = RichTextBox1.TextLength RichTextBox1.AppendText(str) tempSelLenght = RichTextBox1.TextLength - tempSelStart RichTextBox1.Select(tempSelStart, tempSelLenght) '选中文本 RichTextBox1.SelectionColor = cor '当前选中的文本显示颜色 RichTextBox1.AppendText(vbNewLine) RichTextBox1.ScrollToCaret() '将内容滚动的作用 Catch ex As Exception End Try End Sub Public Sub RichTextBox_Show(ByVal str1 As String, ByVal buf() As Byte, ByVal len As UInt16, ByVal cor As Color) Dim tempSelStart As Integer Dim tempSelLenght As Integer Dim i As UInt16 Dim str As String = "" Try RichTextBox_AddTick() tempSelStart = RichTextBox1.TextLength RichTextBox1.AppendText(str1) RichTextBox1.AppendText("--") If len > 0 Then For i = 0 To len - 1 str += Hex(buf(i)).PadLeft(2, "0") str += " " Next End If RichTextBox1.AppendText(str) tempSelLenght = RichTextBox1.TextLength - tempSelStart RichTextBox1.Select(tempSelStart, tempSelLenght) '选中文本 RichTextBox1.SelectionColor = cor '当前选中的文本显示颜色 RichTextBox1.AppendText(vbNewLine) RichTextBox1.ScrollToCaret() '将内容滚动的作用 Catch ex As Exception End Try End Sub Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) If Tb_HexFilePath.Text = "" Then MsgBox("Please select a file!") Return End If Dim readFlashDlg As New ReadFlash readFlashDlg.Button1.Visible = False readFlashDlg.Show() ShowHexFileData(readFlashDlg.DataGridView1, Tb_HexFilePath.Text) End Sub Private Sub ShowHexFileData(showDataGridView1 As DataGridView, ByVal path As String) Dim i As UInt32 Dim dataLen As UInt32 Dim flashAddressBuf(3) As Byte Dim flashAddress As UInt16 Dim dataType As Byte Dim dataStrBuf(31) As Byte Dim dataValBuf(15) As Byte Dim checkSum As Byte Dim rowsNum As UInt16 Dim j As UInt16 Dim k As UInt16 Dim h As UInt16 Dim rowDataStrBuf(41) As Byte Dim rowDataValBuf(20) As Byte Dim rowLen As UInt16 Dim hexBuf(1000 * 1024 - 1) As Byte Dim hexLen As UInt32 Dim asciiDataValBuf(15) As Byte showDataGridView1.Rows.Clear() '清除表格 Try Dim fs As New System.IO.FileStream(path, IO.FileMode.Open, IO.FileAccess.Read) If fs.Length <= hexBuf.Length Then fs.Read(hexBuf, 0, fs.Length) hexLen = fs.Length End If fs.Close() Catch ex As Exception MsgBox("文件读取失败,可能的原因" & vbNewLine & ex.Message) End Try For i = 0 To hexLen If hexBuf(i) = &H3A Then dataLen = (StrToHex(hexBuf(i + 1)) * 16 + StrToHex(hexBuf(i + 2))) If dataLen = 0 Then Continue For '结束当次循环 End If Array.Copy(hexBuf, i + 3, flashAddressBuf, 0, 4) StrToHex(flashAddress, flashAddressBuf) dataType = StrToHex(hexBuf(i + 8)) Array.Clear(dataStrBuf, 0, 32) Array.Clear(dataValBuf, 0, 16) Array.Copy(hexBuf, i + 9, dataStrBuf, 0, dataLen * 2) StrToHex(dataValBuf, dataStrBuf, dataLen) checkSum = (StrToHex(hexBuf(i + 9 + dataLen * 2)) * 16 + StrToHex(hexBuf(i + 10 + dataLen * 2))) Array.Clear(rowDataStrBuf, 0, 42) Array.Clear(rowDataValBuf, 0, 21) rowLen = (dataLen * 2) + 10 '一整行的长度 Array.Copy(hexBuf, i + 1, rowDataStrBuf, 0, rowLen) StrToHex(rowDataValBuf, rowDataStrBuf, rowLen / 2) If HexCalcCheckSum(rowDataValBuf, rowLen / 2) = 0 Then '计算校验和 If dataType <> 0 Then Exit Sub Else rowsNum = flashAddress / 16 '得到行号 If rowsNum = showDataGridView1.Rows.Count Then showDataGridView1.Rows.Add() showDataGridView1.Rows(rowsNum).HeaderCell.Value = Hex(flashAddress).PadLeft(4, "0") For k = 0 To 15 showDataGridView1.Rows(rowsNum).Cells(k).Value = "--" Next ElseIf rowsNum > showDataGridView1.Rows.Count Then For h = 0 To rowsNum - DataGridView1.Rows.Count showDataGridView1.Rows.Add() showDataGridView1.Rows(DataGridView1.Rows.Count - 1).HeaderCell.Value = Hex((DataGridView1.Rows.Count - 1) * 16).PadLeft(4, "0") ' + " " + (DataGridView1.Rows.Count - 1).ToString For k = 0 To 15 showDataGridView1.Rows(DataGridView1.Rows.Count - 1).Cells(k).Value = "--" Next Next End If For j = 0 To dataLen - 1 showDataGridView1.Rows(rowsNum).Cells(j).Value = Hex(dataValBuf(j)).PadLeft(2, "0") Next Array.Copy(dataValBuf, 0, asciiDataValBuf, 0, dataLen) For j = 0 To dataLen - 1 If asciiDataValBuf(j) < &H20 OrElse asciiDataValBuf(j) > &H7E Then asciiDataValBuf(j) = &H2E End If Next showDataGridView1.Rows(rowsNum).Cells(16).Value = System.Text.Encoding.ASCII.GetString(asciiDataValBuf) End If Else MsgBox("文件的校验和不对") End If End If Next End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged SEARCH_TIMEROUT = Val(TextBox1.Text) End Sub Private Sub Cbo_BusType_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Cbo_BusType.SelectedIndexChanged UpdateDevType() End Sub Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged g_UpgradeTimerout = Val(TextBox2.Text) End Sub Private Sub NumericUpDown3_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown3.ValueChanged g_maxRetry = NumericUpDown3.Value End Sub Private Sub Btn_Help_Click(sender As Object, e As EventArgs) Dim dlg As New Help dlg.ShowDialog() End Sub Private Sub btn_Reload_Click(sender As Object, e As EventArgs) Handles btn_Reload.Click Dim tmpRet As Boolean = LoadDataFromFile(Tb_HexFilePath.Text) Dim checkSum(3) As Byte Dim tmpStrCks As String = "" Dim tmpIdx As UInt32 = 0 Dim tmpLineCnt As UInt32 = 1 Dim tmpStrBuffer As String = "" Dim tmpHexValidLenght As UInt32 = g_LoaderEndAddr - g_HexStartAdd_For_C1 If tmpRet Then MsgBox("Hex 装载成功!" & vbCrLf & "起始偏移地址 :" & g_HexStartAdd_For_C1 & vbCrLf & " 结束地址 :" & g_LoaderEndAddr & vbCrLf & " 文件长度 :" & tmpHexValidLenght & vbCrLf ) 'CalcCRC16 CalcCheckSum(g_LoaderDataBuffer, g_LoaderEndAddr, checkSum) tmpStrCks = HexByte2Str(checkSum(3)) tmpStrCks = tmpStrCks & " " & HexByte2Str(checkSum(2)) tmpStrCks = tmpStrCks & " " & HexByte2Str(checkSum(1)) tmpStrCks = tmpStrCks & " " & HexByte2Str(checkSum(0)) lab_HexLastModifyDate.Text = IO.File.GetLastWriteTime(Tb_HexFilePath.Text) lab_HexDataLenght.Text = Format(tmpHexValidLenght, "###,###") & " Bytes" lab_HexDataCks.Text = tmpStrCks Me.Text = "Massduino Nano485 Loader(" & Application.ProductVersion & ")" & " - " & Tb_HexFilePath.Text Else lab_HexDataLenght.Text = "" lab_HexDataCks.Text = "" End If End Sub Private Function HexByte2Str(hexByte As Byte) As String If hexByte < 16 Then Return "0" & Hex(hexByte) Else Return Hex(hexByte) End If End Function Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize 'Me.Width = 720 End Sub Private Sub RichTextBox1_TextChanged(sender As Object, e As EventArgs) If RichTextBox1.TextLength >= 65535 Then RichTextBox1.Clear() End Sub Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing 'V3.0 2020-10-3 Momno:在搜索和升级时关闭窗口,先关闭搜索和升级进程并关闭串口,避免报错 g_SearchStart = False g_UpgradeFlag = False If Port.IsOpen = True Then Port.Close() 'My.Settings.Reload() My.Settings.chk_UpgradeAllSelect = Chk_UpgradeAllSel.Checked My.Settings.CommPortNumber = Cbo_Port.Text My.Settings.CustomeProtocol_JumpToBootloader = tb_CustomeProtocol_JumpToBl.Text My.Settings.CustomeProtocol_Serach = tb_CustomeProtocol_Serach.Text My.Settings.HexFilePatch = Tb_HexFilePath.Text My.Settings.SerachAddStart = num_AddrStart.Value My.Settings.SerachAddEnd = num_AddrEnd.Value My.Settings.SerachTimeout = TextBox1.Text My.Settings.UpgradeTimeout = TextBox2.Text My.Settings.BootloaderTimeout = Tb_Timeout.Text My.Settings.CommBaudRate = Cbo_Baud.Text My.Settings.Opt_ProtocolMode = Opt_ProtocolMode My.Settings.BusType = Cbo_BusType.Text 'My.Settings.C1PackageLenght = tb_C1PackageLen.Text My.Settings.Windows_High = Me.Height My.Settings.Save() End Sub Private Sub opt_ProtocolHexMode_CheckedChanged(sender As Object, e As EventArgs) Handles opt_ProtocolHexMode.CheckedChanged Opt_ProtocolMode = OPT_PROTOCOL_MODE.HEX_MODE End Sub Private Sub opt_ProtocolTextMode_CheckedChanged(sender As Object, e As EventArgs) Handles opt_ProtocolTextMode.CheckedChanged Opt_ProtocolMode = OPT_PROTOCOL_MODE.TEXT_MODE End Sub Private Sub Chk_BackupUpgrade_CheckedChanged(sender As Object, e As EventArgs) Handles Chk_BackupUpgrade.CheckedChanged If Chk_BackupUpgrade.Checked = True Then Chk_LogicFile.Enabled = False Else Chk_LogicFile.Enabled = True End If Tb_HexFilePath.Text = Nothing '重新选择文件 End Sub Private Sub Chk_LogicFile_CheckedChanged(sender As Object, e As EventArgs) Handles Chk_LogicFile.CheckedChanged If Chk_LogicFile.Checked = True Then Chk_BackupUpgrade.Enabled = False Else Chk_BackupUpgrade.Enabled = True End If Tb_HexFilePath.Text = Nothing '重新选择文件 End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim nstrbuf As String = "0C 21 00 00 DE 32 00 00 CE 32 00 00 84 21 00 00 D6 32 00 00 94 32 00 00 84 21 00 00 C6 32 00 00 BE 32 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 B6 32 00 00 AE 32 00 00 A6 32 00 00 9E 32 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 84 21 00 00 96 32 00 00 64 41 00 00 68 29 00 00 60 2A 00 00 C8 2A 00 00 30 2B 00 00 84 21 00 00 D8 2C 00 00 78 30 00 00 A8 30 00 00 0C 2D 00 00 84 21 00 00 84 21 00 00 8C 2D 00 00 FC 2D 00 00 50 2E 00 00 B8 2E 00 00 84 21 00 00 EE 32 00 00 84 21 00 00 0C 2F 00 00 F4 2F 00 00 D8 30 00 00 20 31 00 00 7C 31 00 00 E6 32 00 00 5C 36 00 00 DC 31 00 00 84 21 00 00 10 32 00 00 4C 32 00 00 84 21 00 00 84 21 00 00 05 00 AA 55 00 00 00 00 00 00 00 00 00 30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 5B 10 02 C0 21 64 00 C0 22 60 A8 3A 02 C0 20 64 38 10 00 32 40 B1 F8 10 9F 6F CF 5F 04 33 8D 5F 00 35 03 24 A0 B4 18 65 FD 0B 14 10 C1 7B 03 6C 03 6C 8F EA 13 00 13 10 00 78 03 6C 03 6C 03 6C 03 6C 03 6C 90 10 43 6D A0 B4 00 C0 21 60 2F 10 01 C0 2B 64 2E 10 00 30 20 B0 2E 10 01 C0 2B 64 2D 10 00 30 20 B0 FA 07 F9 07 00 00 00 20 00 00 90 EF 00 E0 F8 0F 00 20 D8 22 00 00 60 21 00 00 3C 33 00 00 00 30 00 20 FF FF 00 00 FF 0F 00 00 EE EE 00 00 EE 0E 00 00 21 14 20 B8 7F 6C 40 60 20 81 21 41 C4 63 20 98 01 14 3C 78 C3 14 44 74 40 3A 1F 0C 43 6D 03 6D 03 36 18 69 40 3C 1A 0C 20 A5 00 2A 40 3A 15 0C 00 25 17 6D 03 36 18 69 40 3C 10 0C 20 A5 00 2A 40 3A 0B 0C 00 25 17 6D 03 36 18 69 " Dim li = StrToHexData(nstrbuf) Dim sintbuf() As Byte = li.ToArray Dim crcBuf(4096) As Byte Dim crcBufLen As UInt32 CalcCRC16(sintbuf, sintbuf.Length, crcBuf, crcBufLen) End Sub Public Function StrToHexData(HexFilePath As String) As List(Of Byte) Dim result As List(Of Byte) = New List(Of Byte) Dim strbuf() As String = HexFilePath.Trim.Split(" ") Dim index As Integer =0 For Each str As String In strbuf str = str.Trim index = (HexStrToInt(str(0)) * 16) + HexStrToInt(str(1)) result.Add(CByte(index)) Next Return result End Function Public Function HexStrToInt(onestr As String) As Integer Dim result As Integer = 0 If Integer.TryParse(onestr, result) Then Return result Else Select Case onestr.Trim .ToUpper Case "A" Return 10 Case "B" Return 11 Case "C" Return 12 Case "D" Return 13 Case "E" Return 14 Case "F" Return 15 Case Else Return 0 End Select End If Return result End Function End Class