public static List <ProgrammableRegion> BuildFLASHImages(BSPEngine.IDebugStartService service, IESP8266Settings settings, BSPEngine.LiveMemoryLineHandler lineHandler) { var bspDict = service.SystemDictionary; var targetPath = service.TargetPath; string bspPath = bspDict["SYS:BSP_ROOT"]; string toolchainPath = bspDict["SYS:TOOLCHAIN_ROOT"]; Regex rgBinFile = new Regex("^" + Path.GetFileName(targetPath) + "-0x([0-9a-fA-F]+)\\.bin$", RegexOptions.IgnoreCase); foreach (var fn in Directory.GetFiles(Path.GetDirectoryName(targetPath))) { if (rgBinFile.IsMatch(Path.GetFileName(fn))) { File.Delete(fn); } } int initDataAddress = 0; if (!string.IsNullOrEmpty(settings.InitDataAddress)) { initDataAddress = (int)(ESP32StartupSequence.TryParseNumber(settings.InitDataAddress) ?? 0); } else { switch (settings.FLASHSettings.Size) { case ESP8266BinaryImage.FLASHSize.size4M: initDataAddress = 0x7c000; break; case ESP8266BinaryImage.FLASHSize.size8M: initDataAddress = 0xfc000; break; case ESP8266BinaryImage.FLASHSize.size16M: case ESP8266BinaryImage.FLASHSize.size16M_c1: initDataAddress = 0x1fc000; break; case ESP8266BinaryImage.FLASHSize.size32M: case ESP8266BinaryImage.FLASHSize.size32M_c1: case ESP8266BinaryImage.FLASHSize.size32M_c2: initDataAddress = 0x3fc000; break; } } List <ProgrammableRegion> regions = new List <ProgrammableRegion>(); if (initDataAddress != 0) { string initFile = settings.InitDataFile; if (initFile != "") { if (initFile == null) { initFile = ESPxxOpenOCDSettingsEditor.DefaultInitDataFile; } if (initFile.StartsWith("$$SYS:BSP_ROOT$$")) { initFile = bspDict["SYS:BSP_ROOT"] + initFile.Substring("$$SYS:BSP_ROOT$$".Length); } if (!Path.IsPathRooted(initFile)) { initFile = Path.Combine(bspDict["SYS:PROJECT_DIR"], initFile); } if (!File.Exists(initFile)) { throw new Exception("Missing initialization data file: " + initFile); } regions.Add(new ProgrammableRegion { FileName = initFile, Offset = initDataAddress, Size = File.ReadAllBytes(initFile).Length }); } } if (settings.FLASHResources != null) { foreach (var r in settings.FLASHResources) { if (r.Valid) { regions.Add(r.ToProgrammableRegion(service)); } } } using (var elfFile = new ELFFile(targetPath)) { string pathBase = Path.Combine(Path.GetDirectoryName(targetPath), Path.GetFileName(targetPath)); string status; int appMode = ESP8266BinaryImage.DetectAppMode(elfFile, out status); if (status != null && lineHandler != null) { lineHandler(status, true); } if (appMode == 0) { var img = ESP8266BinaryImage.MakeNonBootloaderImageFromELFFile(elfFile, settings.FLASHSettings); string fn = pathBase + "-0x00000.bin"; using (var fs = new FileStream(fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { img.Save(fs); regions.Add(new ProgrammableRegion { FileName = fn, Offset = 0, Size = (int)fs.Length }); } foreach (var sec in ESP8266BinaryImage.GetFLASHSections(elfFile)) { fn = string.Format("{0}-0x{1:x5}.bin", pathBase, sec.OffsetInFLASH); using (var fs = new FileStream(fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { fs.Write(sec.Data, 0, sec.Data.Length); regions.Add(new ProgrammableRegion { FileName = fn, Offset = (int)sec.OffsetInFLASH, Size = sec.Data.Length }); } } } else { var img = ESP8266BinaryImage.MakeBootloaderBasedImageFromELFFile(elfFile, settings.FLASHSettings, appMode); var header = settings.FLASHSettings; string bspRoot, bootloader; if (!bspDict.TryGetValue("SYS:BSP_ROOT", out bspRoot) || !bspDict.TryGetValue("com.sysprogs.esp8266.bootloader", out bootloader)) { throw new Exception("Cannot determine bootloader image path. Please check your BSP consistency."); } string fn = Path.Combine(bspRoot, bootloader); if (!File.Exists(fn)) { throw new Exception(fn + " not found. Cannot program OTA images."); } byte[] data = File.ReadAllBytes(fn); data[2] = (byte)header.Mode; data[3] = (byte)(((byte)header.Size << 4) | (byte)header.Frequency); fn = string.Format("{0}-0x00000.bin", pathBase); File.WriteAllBytes(fn, data); regions.Add(new ProgrammableRegion { FileName = fn, Offset = 0, Size = File.ReadAllBytes(fn).Length }); fn = string.Format("{0}-0x{1:x5}.bin", pathBase, img.BootloaderImageOffset); using (var fs = new FileStream(fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { img.Save(fs); regions.Add(new ProgrammableRegion { FileName = fn, Offset = (int)img.BootloaderImageOffset, Size = (int)fs.Length }); } } } return(regions); }
public static List <ProgrammableRegion> BuildFLASHImages(string targetPath, Dictionary <string, string> bspDict, Dictionary <string, string> debugMethodConfig, LiveMemoryLineHandler lineHandler) { string bspPath = bspDict["SYS:BSP_ROOT"]; string toolchainPath = bspDict["SYS:TOOLCHAIN_ROOT"]; Regex rgBinFile = new Regex("^" + Path.GetFileName(targetPath) + "-0x([0-9a-fA-F]+)\\.bin$", RegexOptions.IgnoreCase); foreach (var fn in Directory.GetFiles(Path.GetDirectoryName(targetPath))) { if (rgBinFile.IsMatch(Path.GetFileName(fn))) { File.Delete(fn); } } string freq, mode, size; debugMethodConfig.TryGetValue("com.sysprogs.esp8266.xt-ocd.flash_freq", out freq); debugMethodConfig.TryGetValue("com.sysprogs.esp8266.xt-ocd.flash_mode", out mode); debugMethodConfig.TryGetValue("com.sysprogs.esp8266.xt-ocd.flash_size", out size); List <ProgrammableRegion> regions = new List <ProgrammableRegion>(); using (var elfFile = new ELFFile(targetPath)) { string pathBase = Path.Combine(Path.GetDirectoryName(targetPath), Path.GetFileName(targetPath)); string status; int appMode = ESP8266BinaryImage.DetectAppMode(elfFile, out status); if (status != null && lineHandler != null) { lineHandler(status, true); } if (appMode == 0) { var img = ESP8266BinaryImage.MakeNonBootloaderImageFromELFFile(elfFile, new ESP8266BinaryImage.ParsedHeader(freq, mode, size)); string fn = pathBase + "-0x00000.bin"; using (var fs = new FileStream(fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { img.Save(fs); regions.Add(new ProgrammableRegion { FileName = fn, Offset = 0, Size = (int)fs.Length }); } foreach (var sec in ESP8266BinaryImage.GetFLASHSections(elfFile)) { fn = string.Format("{0}-0x{1:x5}.bin", pathBase, sec.OffsetInFLASH); using (var fs = new FileStream(fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { fs.Write(sec.Data, 0, sec.Data.Length); regions.Add(new ProgrammableRegion { FileName = fn, Offset = (int)sec.OffsetInFLASH, Size = sec.Data.Length }); } } } else { var img = ESP8266BinaryImage.MakeBootloaderBasedImageFromELFFile(elfFile, new ESP8266BinaryImage.ParsedHeader(freq, mode, size), appMode); string bspRoot, bootloader; if (!bspDict.TryGetValue("SYS:BSP_ROOT", out bspRoot) || !bspDict.TryGetValue("com.sysprogs.esp8266.bootloader", out bootloader)) { throw new Exception("Cannot determine bootloader image path. Please check your BSP consistency."); } string fn = Path.Combine(bspRoot, bootloader); if (!File.Exists(fn)) { throw new Exception(fn + " not found. Cannot program OTA images."); } byte[] data = File.ReadAllBytes(fn); data[2] = (byte)img.Header.Mode; data[3] = (byte)(((byte)img.Header.Size << 4) | (byte)img.Header.Frequency); fn = string.Format("{0}-0x00000.bin", pathBase); File.WriteAllBytes(fn, data); regions.Add(new ProgrammableRegion { FileName = fn, Offset = 0, Size = File.ReadAllBytes(fn).Length }); fn = string.Format("{0}-0x{1:x5}.bin", pathBase, img.BootloaderImageOffset); using (var fs = new FileStream(fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { img.Save(fs); regions.Add(new ProgrammableRegion { FileName = fn, Offset = (int)img.BootloaderImageOffset, Size = (int)fs.Length }); } } } return(regions); }