public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { var settings = (RISCVOpenOCDSettings)context.Configuration; OpenOCDCommandLine cmdLine = OpenOCDCommandLine.Parse(settings.CommandLine, startService.CommandLineHelper); if (context.ResolvedDevices?.Interface != null) { if (context.ResolvedDevices.AllCompatibleDevices.Length > 1 || settings.AlwaysPassSerialNumber) { var db = new QuickSetupDatabase(false, context.Method.Directory); var matchingIface = db.AllInterfaces.FirstOrDefault(i => i.ID == context.ResolvedDevices.Interface.ID); if (matchingIface?.SerialNumberCommand != null) { cmdLine.InsertAfterInterfaceScript(new OpenOCDCommandLine.CommandItem { Command = $"{matchingIface.SerialNumberCommand} {EscapeSerialNumber(context.ResolvedDevices.BestMatch.Device.SerialNumber)}" }); } } } if (startService.Mode == EmbeddedDebugMode.Attach) { for (; ;) { var item = cmdLine.Items.OfType <OpenOCDCommandLine.CommandItem>().FirstOrDefault(c => c.Command.StartsWith("reset")); if (item == null) { break; } cmdLine.Items.Remove(item); } } int gdbPort, telnetPort; using (var allocator = startService.BeginAllocatingTCPPorts()) { gdbPort = PortAllocationHelper.AllocateUnusedTCPPort(allocator, "SYS:GDB_PORT", settings.PreferredGDBPort); telnetPort = PortAllocationHelper.AllocateUnusedTCPPort(allocator, "com.sysprogs.openocd.telnet_port", settings.PreferredTelnetPort); } cmdLine.Items.Insert(0, new OpenOCDCommandLine.CommandItem { Command = "gdb_port " + gdbPort }); cmdLine.Items.Insert(1, new OpenOCDCommandLine.CommandItem { Command = "telnet_port " + telnetPort }); cmdLine.Items.Add(new OpenOCDCommandLine.CommandItem { Command = "echo VisualGDB_OpenOCD_Ready" }); var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = Path.Combine(GetOpenOCDDirectory(context.Method.Directory), "bin\\openocd.exe"), Arguments = cmdLine.ToString(), WorkingDirectory = Path.Combine(GetOpenOCDDirectory(context.Method.Directory), "share\\openocd\\scripts") }); return(CreateStub(context, settings, cmdLine, gdbPort, telnetPort, null, tool)); }
public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { var settings = context.Configuration as TiXDSDebugSettings ?? throw new Exception("Missing debug method settings"); var exe = new TiXDSSettingsEditor(settings).GDBAgentExecutable; if (string.IsNullOrEmpty(exe) || !File.Exists(exe)) { throw new Exception("Missing TI XDS stub: " + exe); } var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = exe, WorkingDirectory = Path.GetDirectoryName(exe), Arguments = "cc3220s.dat" }); return(new StubInstance(context.Method.Directory, settings, tool)); }
public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { var settings = context.Configuration as ESP32GDBStubSettings; if (settings == null) { throw new Exception("Missing ESP32 stub settings"); } int comPort; if (context.ResolvedDevices?.BestMatch.COMPortNumber.HasValue == true) { comPort = context.ResolvedDevices.BestMatch.COMPortNumber ?? 1; } else { if (settings.COMPort?.StartsWith("COM", StringComparison.InvariantCultureIgnoreCase) != true) { throw new Exception("Invalid COM port specifier: " + settings.COMPort); } comPort = int.Parse(settings.COMPort.Substring(3)); } var regions = ESP32StartupSequence.BuildFLASHImages(startService.TargetPath, startService.SystemDictionary, settings.FLASHSettings, settings.PatchBootloader); if (settings.FLASHResources != null) { foreach (var r in settings.FLASHResources) { if (r.Valid) { regions.Add(r.ToProgrammableRegion(startService)); } } } foreach (var r in regions) { var pythonExe = Path.GetFullPath(context.Method.Directory + @"\..\..\..\..\bin\bash.exe"); string args = $"python /esp32-bsp/esp-idf/components/esptool_py/esptool/esptool.py --port /dev/ttyS{comPort - 1} {settings.AdditionalToolArguments} write_flash"; foreach (var region in regions) { if (region.FileName.Contains(" ")) { throw new Exception($"{region.FileName} contains spaces in path. Cannot program it using esptool.py. Please move your project to a directory without spaces."); } args += $" 0x{region.Offset:x} " + region.FileName.Replace('\\', '/'); } var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = pythonExe, Arguments = $"--login -c \"{args}\"", }); return(new GDBStubInstance(context, regions) { Tool = tool }); } throw new OperationCanceledException(); }
public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { var settings = (RedLinkDebugSettings)context.Configuration ?? new RedLinkDebugSettings(); var cmdLine = new RedLinkServerCommandLine(settings.CommandLineArguments); int gdbPort; using (var allocator = startService.BeginAllocatingTCPPorts()) { gdbPort = allocator.AllocateUnusedTCPPort("SYS:GDB_PORT"); } var ideRoot = RegistrySettings.MCUXpressoPath ?? throw new Exception("Please specify the MCUXpresso directory via Debug Settings"); bool programNow; switch (settings.ProgramMode) { case ProgramMode.Disabled: programNow = false; break; case ProgramMode.Auto: programNow = !startService.IsCurrentFirmwareAlreadyProgrammed(); break; default: programNow = true; break; } var gdbServer = Path.Combine(ideRoot, @"binaries\crt_emu_cm_redlink.exe"); if (!File.Exists(gdbServer)) { throw new Exception("Could not find " + gdbServer); } var cmdLineText = cmdLine.CommandLine; if (cmdLineText.Contains(DeviceDirectoryVariableReference)) { var db = new RedLinkDeviceDatabase(); var device = cmdLine.Device ?? throw new Exception("RedLink command line does not specify the device (-pXXX)"); var vendor = cmdLine.Vendor ?? throw new Exception("RedLink command line does not specify the vendor (-vendor)"); device = startService.ExpandProjectVariables(device, true, false); vendor = startService.ExpandProjectVariables(vendor, true, false); var dev = db.ProvideDeviceDefinition(vendor, device) ?? throw new Exception($"Unknown vendor/device: {vendor}/{device}. Please use VisualGDB Project Properties -> Debug Settings to configure."); cmdLineText = cmdLineText.Replace(DeviceDirectoryVariableReference, TranslatePath(dev.DefinitionDirectory)); } if (cmdLineText.Contains(FLASHDriverDirectoryVariableReference)) { var pluginDir = Path.Combine(ideRoot, "plugins"); if (Directory.Exists(pluginDir)) { var toolsPlugin = Directory.GetDirectories(pluginDir, "com.nxp.mcuxpresso.tools.bin.win32*").FirstOrDefault(); if (toolsPlugin != null) { cmdLineText = cmdLineText.Replace(FLASHDriverDirectoryVariableReference, TranslatePath(Path.Combine(toolsPlugin, @"binaries\Flash"))); } } } string explicitSerialNumber = null; if (context.ResolvedDevices?.BestMatch.Device.SerialNumber != null) { if ((context.ResolvedDevices.AllCompatibleDevices?.Length ?? 0) > 1 || settings.AlwaysUseProbeSerialNumber) { explicitSerialNumber = context.ResolvedDevices.BestMatch.Device.SerialNumber; cmdLineText += " --probeserial " + explicitSerialNumber; } } int coreIndex = 0; if (cmdLine.Core is string core) { core = startService.ExpandProjectVariables(core, true, false); int.TryParse(core, out coreIndex); } var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = gdbServer, Arguments = cmdLineText, WorkingDirectory = Path.GetDirectoryName(gdbServer) }); return(new RedLinkGDBStub(context, settings, cmdLine, gdbPort, tool, programNow, explicitSerialNumber, coreIndex)); }
public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { var settings = context.Configuration as TiXDSDebugSettings ?? throw new Exception("Missing debug method settings"); var exe = new TiXDSSettingsEditor(settings).GDBAgentExecutable; if (string.IsNullOrEmpty(exe) || !File.Exists(exe)) { throw new Exception("Missing TI XDS stub: " + exe); } string configFile = null; switch (settings.FLASHDriver) { case TiXDSFLASHDriver.CC3220: configFile = "cc3220s.dat"; break; case TiXDSFLASHDriver.UniFLASH: configFile = Path.Combine(context.Method.Directory, "rm57x.dat"); break; } if (settings.FLASHDriver == TiXDSFLASHDriver.UniFLASH && startService.Mode != EmbeddedDebugMode.ConnectionTest && startService.Mode != EmbeddedDebugMode.Attach) { bool skipLoad = false; switch (settings.ProgramMode) { case ProgramMode.Disabled: skipLoad = true; break; case ProgramMode.Auto: if (startService.IsCurrentFirmwareAlreadyProgrammed()) { skipLoad = true; } break; } if (!skipLoad) { string uniFLASHDir = Path.Combine(context.Method.Directory, "UniFLASH"); var programTool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = Path.Combine(uniFLASHDir, "dslite.bat"), Arguments = $@"--config={uniFLASHDir}\user_files\configs\rm57l8xx.ccxml {startService.TargetPath} --verbose", ShowInGDBStubWindow = true }); using (var logFile = new FileStream(Path.Combine(Path.GetDirectoryName(startService.TargetPath), "UniFLASH.log"), FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { programTool.LineReceived += (s, e) => { try { byte[] data = Encoding.UTF8.GetBytes(e.Line + "\r\n"); logFile.Write(data, 0, data.Length); logFile.Flush(); } catch { }; }; while (programTool.IsRunning) { Thread.Sleep(100); } if (programTool.ExitCode != 0) { throw new Exception($"UniFLASH exited with code {programTool.ExitCode}. Please check UniFLASH.log."); } } startService.OnFirmwareProgrammedSuccessfully(); } } if (!string.IsNullOrEmpty(settings.CustomConfigFile)) { configFile = settings.CustomConfigFile; } var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = exe, WorkingDirectory = Path.GetDirectoryName(exe), Arguments = configFile }); return(new StubInstance(context.Method.Directory, settings, tool)); }
public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { int gdbPort; using (var allocator = startService.BeginAllocatingTCPPorts()) gdbPort = allocator.AllocateUnusedTCPPort("SYS:GDB_PORT"); var settings = context.Configuration as AVaRICEDebugSettings ?? throw new Exception("Invalid AVaRICE debug settings"); var exe = Path.Combine(context.Method.Directory, "avarice.exe"); if (!File.Exists(exe)) { exe = Path.GetFullPath(Path.Combine(context.Method.Directory, @"..\..\..\bin\avarice.exe")); } List <string> args = new List <string>(); if (!string.IsNullOrEmpty(settings.DebugInterface)) { args.Add(settings.DebugInterface); } if (!string.IsNullOrEmpty(settings.DebugBitrate)) { args.Add("-B " + settings.DebugBitrate); } if (context.ResolvedDevices?.Interface?.ID != null) { args.Add("-j usb"); int idx = context.ResolvedDevices.Interface.ID.IndexOf(':'); if (idx != -1) { args.Add(context.ResolvedDevices.Interface.ID.Substring(idx + 1)); } } else { if (!string.IsNullOrEmpty(settings.DebugAdapterType)) { args.Add(settings.DebugAdapterType); } if (!string.IsNullOrEmpty(settings.DebugPort)) { args.Add("-j " + settings.DebugPort.ToLower()); } } if (startService.Mode != EmbeddedDebugMode.Attach && startService.Mode != EmbeddedDebugMode.ConnectionTest && startService.TargetPath != null && (settings.EraseFLASH || settings.ProgramFLASH || settings.VerifyFLASH)) { args.Insert(0, $"--file \"{startService.TargetPath}\""); if (settings.EraseFLASH) { args.Add("--erase"); } if (settings.ProgramFLASH) { args.Add("--program"); } if (settings.VerifyFLASH) { args.Add("--verify"); } } if (!string.IsNullOrEmpty(settings.ExtraArguments)) { args.Add(settings.ExtraArguments); } args.Add(":" + gdbPort); var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = exe, Arguments = string.Join(" ", args.ToArray()) }); return(new StubInstance(context, tool, gdbPort, settings)); }
bool LoadFLASH(DebugStartContext context, IDebugStartService service, ISimpleGDBSession session, ESP32OpenOCDSettings settings, ESP32GDBStub stub) { string val; if (!service.SystemDictionary.TryGetValue("com.sysprogs.esp32.load_flash", out val) || val != "1") { //This is a RAM-only configuration return(session.RunGDBCommand("load").IsDone); } else { if (settings.ProgramUsingIDF) { string bash, bashArgs; if (!service.SystemDictionary.TryGetValue("com.sysprogs.esp32.esptool.bash", out bash) || !service.SystemDictionary.TryGetValue("com.sysprogs.esp32.esptool.bash_args", out bashArgs)) { throw new Exception("ESP-IDF did not report esptool arguments"); } if (service.SystemDictionary.TryGetValue("com.sysprogs.esp32.esptool.script", out var script) && File.Exists(script)) { var lines = File.ReadAllLines(script).ToList(); int idx = Enumerable.Range(0, lines.Count).FirstOrDefault(i => lines[i].Contains("def hard_reset(self):")); if (idx > 0 && idx < (lines.Count - 1)) { if (!lines[idx + 1].Contains("self._port.setDTR(False)")) { if (service.GUIService.Prompt("The esptool.py binary used in the current ESP-IDF contains known compatibility issue with Cygwin. Do you want to patch it automatically?")) { Regex rgIndent = new Regex("^([ \t]*)[^ \t]"); var m = rgIndent.Match(lines[idx + 1]); lines.Insert(idx + 1, m.Groups[1].Value + "self._port.setDTR(False) # IO0=HIGH"); File.WriteAllLines(script, lines.ToArray()); } } } } var tool = service.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = bash, Arguments = bashArgs }); ESP32StubDebugController.GDBStubInstance.ReportFLASHProgrammingProgress(tool, service, session); string text = tool.AllText; int validLines = text.Split('\n').Count(l => l.Trim() == "Hash of data verified."); int binCount = 0; if (service.MCU.Configuration.TryGetValue("com.sysprogs.esp32.esptool.binaries.count", out var tmp)) { int.TryParse(tmp, out binCount); } binCount = 0; if (validLines < binCount) { service.GUIService.Report("Warning: some of the FLASH regions could not be programmed. Please examine the stub output for details.", System.Windows.Forms.MessageBoxIcon.Warning); } } else { List <ProgrammableRegion> blocks; if (service.MCU.Configuration.TryGetValue("com.sysprogs.esp32.esptool.binaries.count", out var tmp) && int.TryParse(tmp, out var binaryCount) && binaryCount > 0) { blocks = new List <ProgrammableRegion>(); for (int i = 0; i < binaryCount; i++) { string fn = service.MCU.Configuration[$"com.sysprogs.esp32.esptool.binaries[{i}].path"]; blocks.Add(new ProgrammableRegion { FileName = fn, Size = File.ReadAllBytes(fn).Length, Offset = int.Parse(service.MCU.Configuration[$"com.sysprogs.esp32.esptool.binaries[{i}].address"]) }); } } else { bool patchBootloader = (settings as IESP32Settings)?.PatchBootloader ?? false; blocks = ESP32StartupSequence.BuildFLASHImages(service.TargetPath, service.SystemDictionary, settings.FLASHSettings, patchBootloader); } if (settings.FLASHResources != null) { foreach (var r in settings.FLASHResources) { if (r.Valid) { blocks.Add(r.ToProgrammableRegion(service)); } } } Regex rgFLASHSize = new Regex("Auto-detected flash size ([0-9]+) KB"); if (settings.CheckFLASHSize) { var match = stub.Tool.AllText.Split('\n').Select(s => rgFLASHSize.Match(s)).FirstOrDefault(m => m.Success); if (match != null) { int detectedSizeKB = int.Parse(match.Groups[1].Value); int specifiedSizeMB = 0; switch (settings.FLASHSettings.Size) { case ESP8266BinaryImage.ESP32FLASHSize.size1MB: specifiedSizeMB = 1; break; case ESP8266BinaryImage.ESP32FLASHSize.size2MB: specifiedSizeMB = 2; break; case ESP8266BinaryImage.ESP32FLASHSize.size4MB: specifiedSizeMB = 4; break; case ESP8266BinaryImage.ESP32FLASHSize.size8MB: specifiedSizeMB = 8; break; case ESP8266BinaryImage.ESP32FLASHSize.size16MB: specifiedSizeMB = 16; break; } if (detectedSizeKB < (specifiedSizeMB * 1024) && detectedSizeKB >= 1024) { if (service.GUIService.Prompt($"The FLASH size specified via Project Properties is greater than the actual SPI FLASH size on your device. Please switch FLASH size to {detectedSizeKB / 1024}MB or less.\nDo you want to cancel FLASH programming?", System.Windows.Forms.MessageBoxIcon.Warning)) { throw new OperationCanceledException(); } } } } using (var ctx = session.CreateScopedProgressReporter("Programming FLASH...", new[] { "Programming FLASH memory" })) { int blkNum = 0; Regex rgWriteXBytes = new Regex("wrote ([0-9]+) bytes from file"); foreach (var blk in blocks) { ctx.ReportTaskProgress(blkNum++, blocks.Count); string path = blk.FileName.Replace('\\', '/'); var result = session.RunGDBCommand($"mon program_esp32 \"{path}\" 0x{blk.Offset:x}"); bool succeeded = result.StubOutput?.FirstOrDefault(l => l.Contains("** Programming Finished **")) != null; if (!succeeded) { throw new Exception("FLASH programming failed. Please review the gdb/OpenOCD logs for details."); } var m = result.StubOutput.Select(l => rgWriteXBytes.Match(l)).FirstOrDefault(m2 => m2.Success); if (m == null) { throw new Exception("FLASH programming did not report the amount of written bytes. Please review the gdb/OpenOCD logs for details."); } int bytesWritten = int.Parse(m.Groups[1].Value); if (bytesWritten == 0 && blk.Size > 0) { throw new Exception("FLASH programming did not write any data. This is a known bug of ESP32 OpenOCD. Please restart your device and JTAG programmer and try again."); } } } } } if (!session.RunGDBCommand("mon reset halt").IsDone) { throw new Exception("Failed to reset target after programming"); } return(true); }
public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context) { var settings = (RenesasDebugSettings)context.Configuration ?? new RenesasDebugSettings(); var cmdLine = new RenesasGDBServerCommandLine(settings.CommandLineArguments); int gdbPort; using (var allocator = startService.BeginAllocatingTCPPorts()) { cmdLine.GDBPort = gdbPort = allocator.AllocateUnusedTCPPort("SYS:GDB_PORT"); cmdLine.AuxiliaryPort = allocator.AllocateUnusedTCPPort("com.sysprogs.renesas.auxiliary_port"); } string debugComponentLinkFile = Path.Combine(GetOpenOCDDirectory(context.Method.Directory), "DebugCompLink.txt"); if (!File.Exists(debugComponentLinkFile)) { throw new Exception($"{debugComponentLinkFile} does not exist"); } cmdLine.DeviceID = startService.MCU.ExpandedMCU.ID; if (cmdLine.DebugInterface == null) { cmdLine.DebugInterface = "EZ"; } bool programNow; switch (settings.ProgramMode) { case ProgramMode.Disabled: programNow = false; break; case ProgramMode.Auto: programNow = !startService.IsCurrentFirmwareAlreadyProgrammed(); break; default: programNow = true; break; } cmdLine.SetSeparatedValue("-ueraseRom=", programNow ? "1" : "0"); string debugComponentDir = File.ReadAllText(debugComponentLinkFile); string e2gdbServer = Path.Combine(debugComponentDir, "e2-server-gdb.exe"); if (!File.Exists(e2gdbServer)) { throw new Exception("Could not find " + e2gdbServer); } var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo { Command = e2gdbServer, Arguments = cmdLine.CommandLine, WorkingDirectory = Path.GetDirectoryName(e2gdbServer) }); return(new RenesasGDBStub(context, settings, cmdLine, gdbPort, tool, $@"{debugComponentDir}\IoFiles\{startService.MCU.ExpandedMCU.ID}.sfrx", programNow)); }