public void FirmwareValidate(TestData.Fw fw_paths) { foreach (TestData.Fw fw in fw_paths.GetFlags()) { FwTools.FwInfo ret = FwTools.Validate(TestData.GetFwPath(fw)); Assert.NotNull(ret); Assert.True(ret.SizeCode > 0); } }
private Status ParseFirmware(string firmware_path, out List <Rx_Block> rx_blocks, out FwTools.FwInfo fw_info) { fw_info = null; rx_blocks = new List <Rx_Block>(); FwTools.Firmware code_to_upload = null; FwTools.Firmware code_full_for_crc = null; bool fill_FF = false; if (protocol == Protocol.USB_5_6) { fill_FF = true; } try { code_to_upload = FwTools.Parse(firmware_path, FillFF: fill_FF); code_full_for_crc = FwTools.Parse(firmware_path, FillFF: true); // slice data to bigger blocks that fit buffer size int buff_size = GetBufferSize(protocol); if (fill_FF) { for (int i = 0; i < code_to_upload.Nodes.Count; i += buff_size) { rx_blocks.Add(new Rx_Block { addr = (int)code_to_upload.Nodes[i].Addr, data = code_to_upload.Nodes.Skip(i).Take(buff_size).Select(nod => nod.Data).ToArray() }); } } else { for (int i = 0, j = 0; i < code_to_upload.Nodes.Count; i++) { if (i == code_to_upload.Nodes.Count - 1 || code_to_upload.Nodes[i + 1].Addr - code_to_upload.Nodes[i].Addr > 1 || j + 1 >= buff_size) { rx_blocks.Add(new Rx_Block { addr = (int)code_to_upload.Nodes[i - j].Addr, data = code_to_upload.Nodes.Skip(i - j).Take(j + 1).Select(nod => nod.Data).ToArray() }); j = 0; } else { j++; } } } code_to_upload.Info.Crc16 = code_full_for_crc.Info.Crc16; fw_info = code_to_upload.Info; if (rx_blocks == null || rx_blocks.Count < 1) { throw new Bsl430NetException(445); } else { return(Utils.StatusCreate(0)); } } catch (Exception ex) { if (ex is Bsl430NetException) { return(Utils.StatusCreate(450, ((Bsl430NetException)ex).Status)); } else if (ex is FirmwareToolsException) { Status fw_ex = new Status() { Error = ((FirmwareToolsException)ex).Error, Msg = ((FirmwareToolsException)ex).Msg }; return(Utils.StatusCreate(450, fw_ex)); } else { return(Utils.StatusCreate(450, ex.Message)); } } }
private StatusEx LoadEx(Bsl430NetDevice device, Command cmd, byte[] password, string firmware_path, int?addr_start, int?data_size, out List <byte> output) { output = new List <byte>(); byte[] bsl_version = new byte[0]; Debug.Assert(cmd == Command.Upload || cmd == Command.Download || cmd == Command.MassErase); List <Rx_Block> rx_blocks = new List <Rx_Block>(); FwTools.FwInfo fw_info = new FwTools.FwInfo(); bool baud_rate_fail = false; block_pending = false; progress_pending = 0.0; byte[] pw; try { string dev_name = (device != null) ? device.Name : CommGetDefaultDevice().Name; pw = ValidatePassword(password, out bool pw_overide); UpdateProgress(5, $"INIT '{mode}'"); if (cmd == Command.Upload) { BlockStart("FW READ", 10); Status parsed_fw = ParseFirmware(firmware_path, out rx_blocks, out fw_info); if (!parsed_fw.OK) { BlockEnd(ReportResult.FAILED); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(180, parsed_fw, reports, report, bsl_version, (fw_info == null) ? 0 : fw_info.SizeFull)); } BlockEnd($"FW {fw_info.Format.ToString().Replace('_', '-')} x{fw_info.AddrFirst.ToString("X4")} " + $"{(fw_info.SizeFull / 1024.0).ToString("F1", CultureInfo.InvariantCulture)}K"); } else if (cmd == Command.Download) { BlockStart("PREPARE FW DATA", 10); fw_info = new FwTools.FwInfo(addr_start ?? 0, (addr_start ?? 0) + (data_size ?? 0), data_size ?? 0, GetBufferSize(protocol)); BlockEnd(); } if (fw_info != null && fw_info.AddrLast > int.MaxValue) { return(Utils.StatusCreateEx(100, reports, report, bsl_version, fw_info.SizeFull)); } // --- BlockStart($"OPEN '{dev_name}'", 15); CommOpen(device); CommSet(Utility.Utility.GetEnumDefaultValue <BaudRate>()); BlockEnd(); // --- BlockStart($"INVOKE '{invoke}'", 20, true); if (mode != Mode.USB_HID && invoke != InvokeMechanism.MANUAL) { skipped = false; InvokeBSL(invoke); Task.Delay(100).Wait(); } BlockEnd(); // -- CommClrBuff(); BlockStart($"#BAUD RATE '{(int)baud_rate}'", 25, true); if (mode != Mode.USB_HID && baud_rate != BaudRate.BAUD_9600) { skipped = false; Result <Data_Void> result_baudrate = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.BaudRate))); if (!result_baudrate.ok) { baud_rate_fail = true; } Task.Delay(5).Wait(); if (baud_rate_fail) { BlockEnd(ReportResult.FAILED); if (result_baudrate.status.ToString().Contains("timeout")) { CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(100, result_baudrate.status, reports, report, bsl_version, fw_info.SizeFull)); } #if BREAK_ON_BAUD_CHANGE_ERROR CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(100, result_baudrate.status, reports, report, bsl_version, fw_info.SizeFull)); #endif } else { BlockEnd(ReportResult.SUCCESS); CommSet(baud_rate); } Task.Delay(10).Wait(); } else { BlockEnd(); } // -- if ((pw_overide || protocol == Protocol.USB_5_6 || cmd == Command.Download) && cmd != Command.MassErase) { BlockStart("#PASSWORD (CUSTOM)", 35); if (pw_overide && ((protocol == Protocol.UART_1_2_4 && pw.Length == 20) || ((mcu == MCU.MSP430_F543x_NON_A && pw.Length == 16) || pw.Length == 32))) { Result <Data_Void> result_password = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.Password, pw))); if (!result_password.ok) { BlockEnd(ReportResult.FAILED); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(120, result_password.status, reports, report, bsl_version, fw_info.SizeFull)); } else { pw_overide = true; } } else { return(Utils.StatusCreateEx(470, reports, report, bsl_version, fw_info.SizeFull)); } Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait(); BlockEnd(); } else // if (!pw_overide && protocol != Protocol.USB_5_6) { BlockStart("#MASS ERASE", 30); Result <Data_Void> result_masserase = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.MassErase))); if (!result_masserase.ok) { BlockEnd(ReportResult.FAILED); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(110, result_masserase.status, reports, report, bsl_version, fw_info.SizeFull)); } BlockEnd(); Task.Delay(100).Wait(); // -- BlockStart("#PASSWORD (DEFAULT)", 35); Result <Data_Void> result_password = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.Password, pw))); if (!result_password.ok) { BlockEnd(ReportResult.FAILED); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(120, result_password.status, reports, report, bsl_version, fw_info.SizeFull)); } Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait(); BlockEnd(); } // -- BlockStart("#BSL VERSION", 40, true); if (mode != Mode.USB_HID) { skipped = false; Result <Data_BSLVersion> result_ver = ParseResp <Data_BSLVersion>(ProcessMsg(BuildMsg(Command.BSLVersion))); if (!result_ver.ok) { BlockEnd(ReportResult.FAILED); } else { BlockEnd(ReportResult.SUCCESS, $"#BSL VERSION {BitConverter.ToString(result_ver.data.version).Replace("-", ".")}"); bsl_version = result_ver.data.version.ToArray(); } Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait(); } else { BlockEnd(); } // -- if (mode == Mode.USB_HID) { // TODO Upload RAM BSL // TODO Load PC } // -- if (cmd == Command.Upload) { double quantum = 50.0 / (double)rx_blocks.Count; double _prg = 40; Result <Data_Void> result_rx; for (int x = 0; x < rx_blocks.Count; x++) { BlockStart($"#UPLOADING ({x + 1}/{rx_blocks.Count})", _prg); result_rx = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.Upload, rx_blocks[x].addr, rx_blocks[x].data))); if (!result_rx.ok) { BlockEnd(ReportResult.FAILED); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(140, result_rx.status, (x + 1) + "/" + rx_blocks.Count, reports, report, bsl_version, fw_info.SizeFull)); } _prg += quantum; Task.Delay(5).Wait(); if (x == rx_blocks.Count - 1) { BlockEnd($"#UPLOADED ({x + 1}/{rx_blocks.Count})"); } else { BlockEnd(); } } Task.Delay(5).Wait(); } else if (cmd == Command.Download) { int _data_size = (data_size ?? 0); int total = (_data_size + fw_info.SizeBuffer - 1) / fw_info.SizeBuffer; double quantum = 50.0 / (double)total; double _prg = 40; Result <Data_Download> result_tx; for (int x = 0; x < total; x++) { BlockStart($"#DOWNLOADING ({x + 1}/{total})", _prg); int len = data_size ?? 0; if (len > fw_info.SizeBuffer) { len = fw_info.SizeBuffer; } result_tx = ParseResp <Data_Download>(ProcessMsg(BuildMsg(Command.Download, addr_start, new byte[2] { (byte)(len & 0x00FF), (byte)(len >> 8) }))); if (!result_tx.ok) { BlockEnd(ReportResult.FAILED); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(150, result_tx.status, x + "/" + rx_blocks.Count, reports, report, bsl_version, fw_info.SizeFull)); } output.AddRange(result_tx.data.bytes.ToList()); _prg += quantum; addr_start += fw_info.SizeBuffer; data_size -= fw_info.SizeBuffer; Task.Delay(5).Wait(); if (x == total - 1) { BlockEnd($"#DOWNLOADED ({x + 1}/{total})"); } else { BlockEnd(); } } fw_info.Crc16 = output.Crc16Ccitt(); Task.Delay(5).Wait(); } // -- if (cmd != Command.MassErase) { BlockStart($"#CRC CHECK ({fw_info.Crc16.ToString("X4")})", 95, true); if (protocol != Protocol.UART_1_2_4 && fw_info != null && !(pw_overide && cmd == Command.Upload)) { skipped = false; Result <Data_CRC> result_crc = ParseResp <Data_CRC>(ProcessMsg(BuildMsg(Command.CRC, (int)fw_info.AddrFirst, new byte[2] { (byte)(fw_info.SizeFull & 0x00FF), (byte)(fw_info.SizeFull >> 8) }))); if (!result_crc.ok) { BlockEnd(ReportResult.FAILED); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(160, result_crc.status, reports, report, bsl_version, fw_info.SizeFull)); } if (result_crc.data.crc != fw_info.Crc16) { BlockEnd(ReportResult.FAILED, $"#CRC CHECK ({fw_info.Crc16.ToString("X4")}!={result_crc.data.crc.ToString("X4")})"); CommClose(true); Task.Delay(Const.DELAY_ERR_RET).Wait(); return(Utils.StatusCreateEx(161, reports, report, bsl_version, fw_info.SizeFull)); } Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait(); BlockEnd($"#CRC CHECK ({fw_info.Crc16.ToString("X4")}=={result_crc.data.crc.ToString("X4")})"); } else { BlockEnd(); } } // -- if (cmd != Command.MassErase) { BlockStart("#LOAD USER PROGRAM", 98, true); if (fw_info.ResetVector != null) { skipped = false; Result <Data_Void> result_load = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.LoadPC, (int)fw_info.ResetVector))); if (result_load.ok) { BlockEnd(ReportResult.SUCCESS); } else { BlockEnd(ReportResult.FAILED); //Task.Delay(Const.DELAY_ERR_RET).Wait(); //return Utils.StatusCreateEx(170); } } else { BlockEnd(); } } // -- BlockStart($"RESET '{mcu}'", 99, true); if (mode != Mode.USB_HID) { skipped = false; ResetMCU(invoke); } BlockEnd(); // -- BlockStart($"FINISH", 100); CommClose(); BlockEnd(); Task.Delay(Const.DELAY_OK_RET).Wait(); return(Utils.StatusCreateEx(0, reports, null, bsl_version, fw_info.SizeFull)); } catch (Exception ex) { CommClose(true); if (block_pending) { BlockEnd(ReportResult.FAILED); Task.Delay(Const.DELAY_ERR_RET).Wait(); } if (ex is Bsl430NetException) { return(Utils.StatusCreateEx((ex as Bsl430NetException).Status.Error, (ex as Bsl430NetException).Status, reports, report, bsl_version, fw_info.SizeFull)); } else { return(Utils.StatusCreateEx( Utils.StatusCreate(467, ex.Message + ((Const.IS_DEBUG) ? ex.StackTrace : "")), reports, report, bsl_version, fw_info.SizeFull)); } } }