/// <summary> /// 扫描节点 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void scanNode(FormProgress sender, DoWorkEventArgs e) { for (int i = ScanStartAddr; i <= ScanEndAddr; i++) { int ret; UInt32[] appVersion = new UInt32[1], appType = new UInt32[1]; ret = USB2CAN.CAN_BL_NodeCheck(DeviceIndex, CANIndex, (UInt16)i, appVersion, appType, 10); if (ret == USB2CAN.CAN_SUCCESS) { this.listViewNodeList.BeginUpdate(); //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度 ListViewItem lvi = new ListViewItem(); lvi.Text = i.ToString(); if (appType[0] == USB2CAN.CAN_BL_BOOT) { lvi.SubItems.Add("ROOT"); } else { lvi.SubItems.Add("APP"); } lvi.SubItems.Add(String.Format("v{0}.{1}", (((appVersion[0] >> 24) & 0xFF) * 10) + (appVersion[0] >> 16) & 0xFF, (((appVersion[0] >> 8) & 0xFF) * 10) + appVersion[0] & 0xFF)); this.listViewNodeList.Items.Add(lvi); this.listViewNodeList.EndUpdate(); //结束数据处理,UI界面一次性绘制。 } sender.SetProgress(i - ScanStartAddr + 1, "正在检测节点:" + i.ToString()); if (sender.CancellationPending) { e.Cancel = true; return; } } }
/// <summary> /// 扫描节点 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void scanNode(FormProgress sender, DoWorkEventArgs e) { bool GotNode = false; for (int i = ScanStartAddr; i <= ScanEndAddr; i++) { int ret; UInt32[] appVersion = new UInt32[1]; Byte[] FWType = new Byte[1]; ret = CAN_Bootloader.CAN_BOOT_GetFWInfo(DevHandles[DeviceIndex], CANIndex, (Byte)i, FWType, appVersion, 100); if (ret == CAN_Bootloader.CAN_SUCCESS) { GotNode = true; //Ctrl+F5启动程序这里运行正常,F5启动程序运行不正常,能扫描到节点,但是无法在界面上显示出来,原因不明 this.listViewNodeList.BeginUpdate(); //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度 ListViewItem lvi = new ListViewItem(); lvi.Text = i.ToString(); //节点地址 if (FWType[0] == CAN_Bootloader.FW_TYPE_BOOT) { lvi.SubItems.Add("BOOT"); } else { lvi.SubItems.Add("APP"); } lvi.SubItems.Add(String.Format("v{0}.{1}.{2}.{3}", (((appVersion[0] >> 24) & 0xFF)), (appVersion[0] >> 16) & 0xFF, ((appVersion[0] >> 8) & 0xFF), appVersion[0] & 0xFF)); lvi.SubItems.Add("等待更新"); this.listViewNodeList.Items.Add(lvi); this.listViewNodeList.EndUpdate(); //结束数据处理,UI界面一次性绘制。 } else if (ret == CAN_Bootloader.CAN_BOOT_ERR_SEND) { e.Cancel = true; String msg = "发送CAN数据失败!\r\n"; msg += "1,检查CAN总线波特率是否匹配?\r\n"; msg += "2,检查总线终端电阻是否接好?\r\n"; msg += "3,检查总线接线是否正确?\r\n"; msg += "4,请确定固件中CAN总线引脚配置跟硬件匹配!"; MessageBox.Show(this, msg, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } sender.SetProgress(i - ScanStartAddr + 1, "正在检测节点:" + i.ToString()); if (sender.CancellationPending) { e.Cancel = true; return; } } if (!GotNode) { e.Cancel = true; String msg = "没有扫描到节点!\r\n"; msg += "1,请确定节点地址是在设置的节点地址范围?\r\n"; msg += "2,请确定从节点是否按照协议要求格式返回节点信息?\r\n"; msg += "3,请确定软件上数据收发ID设置跟节点固件数据收发ID设置一致?\r\n"; msg += "4,请确定软件上数据收发ID类型跟节点固件数据收发ID类型一致?"; MessageBox.Show(this, msg, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } }
void upgrateFirmware(FormProgress sender, DoWorkEventArgs e) { int FirmwareFileSize; UInt16 NodeAddr; int ret; //如果文件不存在,就提示错误 if (File.Exists(this.textBoxFilePath.Text)) { BinaryReader br; FirmwareFileSize = (int)new FileInfo(this.textBoxFilePath.Text).Length; try { //将固件文件读取到数据缓冲区中 br = new BinaryReader(new FileStream(this.textBoxFilePath.Text, FileMode.Open)); //判断当前所选择的节点 if (this.listViewNodeList.Items.Count <= 0) { //当前节点列表中没有节点 MessageBox.Show(this, "节点列表中无节点,请先扫描节点!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } else { if (this.checkBoxAllNode.Checked) { NodeAddr = 0; } else { if (this.listViewNodeList.SelectedIndices[0] < 0) { //没有选择任何节点 MessageBox.Show(this, "请先选择节点!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } else { NodeAddr = UInt16.Parse(this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[0].Text); } } } //MessageBox.Show(this, "NodeAddr = " + NodeAddr, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); //发送跳转到Bootloader的命令 sender.SetProgress(0, "跳转到Bootloader..."); ret = USB2CAN.CAN_BL_Excute(DeviceIndex, CANIndex, NodeAddr, USB2CAN.CAN_BL_BOOT); if (ret != USB2CAN.CAN_SUCCESS) { MessageBox.Show(this, "执行固件跳转命令失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } //延时 System.Threading.Thread.Sleep(500); //检测当前节点是否为Bootloader if (!this.checkBoxAllNode.Checked) { UInt32[] appVersion = new UInt32[1], appType = new UInt32[1]; ret = USB2CAN.CAN_BL_NodeCheck(DeviceIndex, CANIndex, NodeAddr, appVersion, appType, 10); if (ret != USB2CAN.CAN_SUCCESS) { MessageBox.Show(this, "节点检测失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } else { if (appType[0] != USB2CAN.CAN_BL_BOOT) { MessageBox.Show(this, "当前节点固件类型不是Bootloader,请重新点击升级固件!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } } } //发送擦出固件命令 sender.SetProgress(0, "擦出固件..."); ret = USB2CAN.CAN_BL_Erase(DeviceIndex, CANIndex, NodeAddr, (UInt32)FirmwareFileSize, 10000); if (ret != USB2CAN.CAN_SUCCESS) { MessageBox.Show(this, "擦出固件失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } if (this.checkBoxAllNode.Checked) { System.Threading.Thread.Sleep(1000); } //循环发送数据 UInt32 AddrOffset = 0; UInt32 PackSize = 512; byte[] DataBuffer = new byte[PackSize]; for (AddrOffset = 0; AddrOffset < FirmwareFileSize; AddrOffset += PackSize) { UInt32 read_data_num = (UInt32)br.Read(DataBuffer, 0, (int)PackSize); ret = USB2CAN.CAN_BL_Write(DeviceIndex, CANIndex, NodeAddr, AddrOffset, DataBuffer, read_data_num, 1000); if (ret != USB2CAN.CAN_SUCCESS) { MessageBox.Show(this, "写数据失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } if (this.checkBoxAllNode.Checked) { System.Threading.Thread.Sleep(20); } sender.SetProgress((int)(AddrOffset + read_data_num), "正在发送固件数据..."); } //执行固件 ret = USB2CAN.CAN_BL_Excute(DeviceIndex, CANIndex, NodeAddr, USB2CAN.CAN_BL_APP); if (ret != USB2CAN.CAN_SUCCESS) { MessageBox.Show(this, "执行固件跳转命令失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } System.Threading.Thread.Sleep(100); //获取固件信息 if (!this.checkBoxAllNode.Checked) { UInt32[] appVersion = new UInt32[1], appType = new UInt32[1]; ret = USB2CAN.CAN_BL_NodeCheck(DeviceIndex, CANIndex, NodeAddr, appVersion, appType, 10); if (ret == USB2CAN.CAN_SUCCESS) { string AppTypeStr; if (appType[0] == USB2CAN.CAN_BL_BOOT) { AppTypeStr = "BOOT"; } else { AppTypeStr = "APP"; } this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[1].Text = AppTypeStr; string AppVersionStr; AppVersionStr = String.Format("v{0}.{1}", (((appVersion[0] >> 24) & 0xFF) * 10) + (appVersion[0] >> 16) & 0xFF, (((appVersion[0] >> 8) & 0xFF) * 10) + appVersion[0] & 0xFF); this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[2].Text = AppVersionStr; } } br.Close(); } catch (IOException ep) { MessageBox.Show(this, ep.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } else { MessageBox.Show(this, "无法打开固件文件,是否选择了固件文件?", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
void upgrateFirmware(FormProgress sender, DoWorkEventArgs e) { int FirmwareFileSize; Byte NodeAddr; int ret; //如果文件不存在,就提示错误 if (File.Exists(this.textBoxFilePath.Text)) { BinaryReader br; FirmwareFileSize = (int)new FileInfo(this.textBoxFilePath.Text).Length; try { //将固件文件读取到数据缓冲区中 br = new BinaryReader(new FileStream(this.textBoxFilePath.Text, FileMode.Open)); //判断当前所选择的节点 if (this.listViewNodeList.Items.Count <= 0) { //当前节点列表中没有节点 MessageBox.Show(this, "节点列表中无节点,请先扫描节点!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } else { if (this.listViewNodeList.SelectedIndices[0] < 0) { //没有选择任何节点 MessageBox.Show(this, "请先选择节点!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } else { NodeAddr = Byte.Parse(this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[0].Text); } } //检测当前固件信息 sender.SetProgress(0, "跳转到Bootloader..."); UInt32[] FWVersion = new UInt32[1]; Byte[] FWType = new Byte[1]; ret = CAN_Bootloader.CAN_BOOT_GetFWInfo(DevHandles[DeviceIndex], CANIndex, NodeAddr, FWType, FWVersion, 50); if (ret == CAN_Bootloader.CAN_SUCCESS) { if (FWType[0] != CAN_Bootloader.FW_TYPE_BOOT) { //跳转到Bootloader ret = CAN_Bootloader.CAN_BOOT_EnterBootMode(DevHandles[DeviceIndex], CANIndex, NodeAddr); if (ret != CAN_Bootloader.CAN_SUCCESS) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "进入BOOT模式失败!"; return; } else { //延时一段时间,保证设备成功进入BOOT模式 System.Threading.Thread.Sleep(300); //再次确认固件信息 ret = CAN_Bootloader.CAN_BOOT_GetFWInfo(DevHandles[DeviceIndex], CANIndex, NodeAddr, FWType, FWVersion, 50); if (ret != CAN_Bootloader.CAN_SUCCESS) { MessageBox.Show(this, "获取固件信息失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } else if (FWType[0] != CAN_Bootloader.FW_TYPE_BOOT) { MessageBox.Show(this, "进入BOOT模式失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } } } } else { MessageBox.Show(this, "获取固件信息失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); br.Close(); return; } //成功进入BOOT模式,开始升级固件 this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "开始擦除固件,该操作可能比较耗时..."; ret = CAN_Bootloader.CAN_BOOT_EraseApp(DevHandles[DeviceIndex], CANIndex, NodeAddr, (UInt32)FirmwareFileSize, 10000); if (ret != CAN_Bootloader.CAN_SUCCESS) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "执行固件擦除指令失败!\r\n" + GetErrorString(ret); br.Close(); return; } else { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "固件擦除成功!"; } //循环发送固件数据 UInt32 AddrOffset = 0; byte[] DataBuffer; UInt16[] BufferSize = new UInt16[1]; for (AddrOffset = 0; AddrOffset < FirmwareFileSize;) { //设置写数据偏移地址 ret = CAN_Bootloader.CAN_BOOT_SetAddrOffset(DevHandles[DeviceIndex], CANIndex, NodeAddr, AddrOffset, BufferSize, 50); if (ret != CAN_Bootloader.CAN_SUCCESS) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "设置地址偏移失败!\r\n" + GetErrorString(ret); br.Close(); return; } if (BufferSize[0] <= 0) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "获取数据缓冲区大小为0!"; } DataBuffer = new Byte[BufferSize[0]]; UInt16[] CRC16 = new UInt16[1]; UInt32 read_data_num = (UInt32)br.Read(DataBuffer, 0, (int)BufferSize[0]); //发送数据 ret = CAN_Bootloader.CAN_BOOT_SendAppData(DevHandles[DeviceIndex], CANIndex, NodeAddr, DataBuffer, (UInt16)read_data_num, CRC16); if (ret != CAN_Bootloader.CAN_SUCCESS) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "发送数据失败!\r\n" + GetErrorString(ret); br.Close(); return; } //将数据写入内部程序存储器 ret = CAN_Bootloader.CAN_BOOT_WriteAppData(DevHandles[DeviceIndex], CANIndex, NodeAddr, CRC16[0], 1000); if (ret != CAN_Bootloader.CAN_SUCCESS) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "写数据失败!\r\n" + GetErrorString(ret); br.Close(); return; } sender.SetProgress((int)(AddrOffset + read_data_num), "正在发送固件数据..."); AddrOffset += read_data_num; } //执行固件 ret = CAN_Bootloader.CAN_BOOT_ExecuteApp(DevHandles[DeviceIndex], CANIndex, NodeAddr); if (ret != CAN_Bootloader.CAN_SUCCESS) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "发送执行固件指令失败!\r\n" + GetErrorString(ret); br.Close(); return; } System.Threading.Thread.Sleep(300); //再次获取固件信息,判断固件是否更新成功 ret = CAN_Bootloader.CAN_BOOT_GetFWInfo(DevHandles[DeviceIndex], CANIndex, NodeAddr, FWType, FWVersion, 100); if (ret == CAN_Bootloader.CAN_SUCCESS) { //Ctrl+F5启动程序这里运行正常,F5启动程序运行不正常,能扫描到节点,但是无法在界面上显示出来,原因不明 this.listViewNodeList.BeginUpdate(); //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度 if (FWType[0] == CAN_Bootloader.FW_TYPE_BOOT) { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[1].Text = "BOOT"; } else { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[1].Text = "APP"; } this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[2].Text = String.Format("v{0}.{1}.{2}.{3}", (((FWVersion[0] >> 24) & 0xFF)), (FWVersion[0] >> 16) & 0xFF, ((FWVersion[0] >> 8) & 0xFF), FWVersion[0] & 0xFF); this.listViewNodeList.EndUpdate(); //结束数据处理,UI界面一次性绘制。 this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "固件更新成功!"; } else { this.listViewNodeList.Items[this.listViewNodeList.SelectedIndices[0]].SubItems[3].Text = "固件执行失败!"; } br.Close(); } catch (IOException ep) { MessageBox.Show(this, ep.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } else { MessageBox.Show(this, "无法打开固件文件,是否选择了固件文件?", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }