/// <summary> /// Convert firmware TI-TXT, Intel-HEX, ELF or SREC format (auto detected) to firmware in TI-TXT, Intel-HEX /// or SREC format. Returned Fw is firmware and Format is useful for auto-detect feedback, indicates input format. /// <para/>FillFF is optional parameter forcing to fill missing addr nodes with 0xFF /// and return monolithic piece of code, which is usefull for crc calc or overwriting whole memory in mcu. /// <para/>LineLength defines amount of data bytes per one text row. When = 0, default values are set /// (TI-TXT = 16, Intel-HEX = 32, SREC = 32). /// </summary> /// <exception cref="FirmwareToolsException"></exception> public static (string Fw, FwFormat Format) Convert(string FirmwarePath, FwFormat Format, bool FillFF = false, int LineLength = 0) { switch (Format) { default: case FwFormat.AUTO: case FwFormat.TI_TXT: { Firmware ret = ParseAutoDetect(FirmwarePath, FillFF); return(Create(ret, FwFormat.TI_TXT, LineLength), ret.Info.Format); } case FwFormat.INTEL_HEX: { Firmware ret = ParseAutoDetect(FirmwarePath, FillFF); return(Create(ret, FwFormat.INTEL_HEX, LineLength), ret.Info.Format); } case FwFormat.SREC: { Firmware ret = ParseAutoDetect(FirmwarePath, FillFF); return(Create(ret, FwFormat.SREC, LineLength), ret.Info.Format); } case FwFormat.ELF: throw new FirmwareToolsException(472, ERR_472); } }
/// <summary> /// Init Firmware with simple data Nodes and new FwInfo class based on valid input data. /// </summary> public Firmware(List <FwNode> Data, FwFormat Format, int SizeBuffer = 0, long ResetVectorAddr = -1, ICollection <long> FilledFFAddr = null) { Nodes = Data.OrderBy(o => o.Addr).ToList(); Info = new FwInfo(Data, Format, SizeBuffer, ResetVectorAddr, FilledFFAddr); }
/// <summary> /// Combines two firmware files into single one with format specified. Usually, main firmware /// and EEPROM file is done this way, or main firmware and Info A flash content is merged. /// Returned Fw is firmware and Format1 with Format2 are useful for auto-detect feedback, indicates input formats. /// <para/>FillFF is optional parameter forcing to fill missing addr nodes with 0xFF /// and return monolithic piece of code, which is usefull for crc calc or overwriting whole memory in mcu. /// <para/>LineLength defines amount of data bytes per one text row. When = 0, default values are set /// (TI-TXT = 16, Intel-HEX = 32, SREC = 32). /// </summary> /// <exception cref="FirmwareToolsException"></exception> public static (string Fw, FwFormat Format1, FwFormat Format2) Combine(string FirmwarePath1, string FirmwarePath2, FwFormat Format, bool FillFF = false, int LineLength = 0) { Firmware fw1 = ParseAutoDetect(FirmwarePath1, FillFF); Firmware fw2 = ParseAutoDetect(FirmwarePath2, FillFF); return(Create(CombineFw(fw1, fw2, FillFF), Format, LineLength), fw1.Info.Format, fw2.Info.Format); }
/// <summary> /// Create firmware multi-line string in TI-TXT, Intel-HEX or SREC format. ELF is not supported yet. /// AUTO format will force TI-TXT format. AddrStart is address of first byte in data collection. /// <para/>LineLength defines amount of data bytes per one text row. When = 0, default values are set /// (TI-TXT = 16, Intel-HEX = 32, SREC = 32). /// </summary> /// <exception cref="FirmwareToolsException"></exception> public static string Create(IEnumerable <byte> Data, int AddrStart, FwFormat Format = FwFormat.AUTO, int LineLength = 0) { return(Create(Data.Select(x => new FwNode { Data = x, Addr = AddrStart++ }).ToList(), Format, LineLength)); }
/// <summary> /// Create firmware multi-line string in TI-TXT, Intel-HEX or SREC format. ELF is not supported yet. /// AUTO format will force TI-TXT format. /// <para/>LineLength defines amount of data bytes per one text row. When = 0, default values are set /// (TI-TXT = 16, Intel-HEX = 32, SREC = 32). /// </summary> /// <exception cref="FirmwareToolsException"></exception> public static string Create(ICollection <FwNode> Data, FwFormat Format = FwFormat.AUTO, int LineLength = 0) { switch (Format) { default: case FwFormat.AUTO: case FwFormat.TI_TXT: return(CreateTiTxt(Data, LineLength)); case FwFormat.INTEL_HEX: return(CreateIntelHex(Data, LineLength)); case FwFormat.SREC: return(CreateSrec(Data, LineLength)); case FwFormat.ELF: throw new FirmwareToolsException(472, ERR_472); } }
/// <summary> /// Parse firmware file from FirmwarePath in TI-TXT, Intel-HEX, ELF or SREC format and returns List of FwNode /// (Data+Addr) and Info. Auto Mode reads data and based on some particular characters determine /// what firmare format it should be. /// <para/>FillFF is optional parameter forcing to fill missing addr nodes with 0xFF /// and return monolithic piece of code, which is usefull for crc calc or overwriting whole memory in mcu. /// <para/>Log writes text (new line formatted) output only when parsing ELF firmware file. /// </summary> /// <exception cref="FirmwareToolsException"></exception> public static Firmware Parse(string FirmwarePath, FwFormat Format = FwFormat.AUTO, bool FillFF = false, StringWriter Log = null) { switch (Format) { default: case FwFormat.AUTO: return(ParseAutoDetect(FirmwarePath, FillFF, log: Log)); case FwFormat.TI_TXT: return(ParseTiTxt(FirmwarePath, FillFF)); case FwFormat.INTEL_HEX: return(ParseIntelHex(FirmwarePath, FillFF)); case FwFormat.SREC: return(ParseSrec(FirmwarePath, FillFF)); case FwFormat.ELF: return(ParseElf32(FirmwarePath, FillFF, log: Log)); } }
/// <summary> /// Init Firmware with raw memory stream bytes and new FwInfo class based on valid input data. /// </summary> public Firmware(Stream Data, FwFormat Format, long FirstAddress, int SizeBuffer = 0, long ResetVectorAddr = -1, ICollection <long> FilledFFAddr = null) { byte[] nodes; Data.Position = 0; using (MemoryStream ms = new MemoryStream()) { Data.CopyTo(ms); nodes = ms.ToArray(); } Nodes = nodes.Select(n => new FwNode() { Data = n, Addr = FirstAddress++ }).ToList(); Info = new FwInfo(Nodes, Format, SizeBuffer, ResetVectorAddr, FilledFFAddr); }
/// <summary> /// Init info class to values calculated from valid firmware data. size_buffer is optional flag and /// ResetVectorAddr is usually 0xFFFE, address where reset vector is, and its also optional. /// </summary> public FwInfo(ICollection <FwNode> Nodes, FwFormat Format, int SizeBuffer = 0, long ResetVectorAddr = -1, ICollection <long> FilledFFAddr = null) { this.Valid = true; this.Format = Format; this.Crc16 = Nodes.Select(nod => nod.Data).ToList().Crc16Ccitt(); this.AddrFirst = Nodes.ElementAt(0).Addr; this.AddrLast = Nodes.ElementAt(Nodes.Count - 1).Addr; this.SizeBuffer = SizeBuffer; this.SizeFull = (int)(AddrLast - AddrFirst) + 1; this.SizeCode = Nodes.Count; if (FilledFFAddr != null) { this.FilledFFAddr = FilledFFAddr.ToList(); } if (ResetVectorAddr >= 0) { SetResetVector(Nodes, ResetVectorAddr); } }
/// <summary> /// Create firmware multi-line string in TI-TXT, Intel-HEX or SREC format. ELF is not supported yet. /// AUTO format will force TI-TXT format. /// <para/>LineLength defines amount of data bytes per one text row. When = 0, default values are set /// (TI-TXT = 16, Intel-HEX = 32, SREC = 32). /// </summary> /// <exception cref="FirmwareToolsException"></exception> public static string Create(Firmware Firmware, FwFormat Format = FwFormat.AUTO, int LineLength = 0) { return(Create(Firmware.Nodes, Format, LineLength)); }