public override void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session) { bool programNow; if (_Settings.ProgramFLASHUsingExternalTool) { programNow = false; } else { switch (_Settings.ProgramMode) { case ProgramMode.Disabled: programNow = false; break; case ProgramMode.Auto: programNow = !service.IsCurrentFirmwareAlreadyProgrammed(); break; default: programNow = true; break; } } foreach (var cmd in _Settings.StartupCommands) { bool isLoad = cmd.Trim() == "load"; if (isLoad) { if (service.Mode == EmbeddedDebugMode.Attach) { session.RunGDBCommand("mon halt"); } else { var sequence = ESP8266StartupSequence.BuildSequence(service, (ESP8266OpenOCDSettings)_Settings, (l, i) => session.SendInformationalOutput(l), programNow, _Context.Method?.Directory); using (var ctx = session.CreateScopedProgressReporter("Programming FLASH", new string[] { "Programming FLASH..." })) { if (RunSequence(ctx, service, session, sequence)) { service.OnFirmwareProgrammedSuccessfully(); } } } } else { session.RunGDBCommand(cmd); } } }
public void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session) { bool programFLASH = false; if (service.Mode != EmbeddedDebugMode.Attach && service.Mode != EmbeddedDebugMode.ConnectionTest) { switch (_Settings.ProgramMode) { case ProgramMode.Auto: programFLASH = !service.IsCurrentFirmwareAlreadyProgrammed(); break; case ProgramMode.Enabled: programFLASH = true; break; } } DoConnect(service, session, _Settings, _COMPort, programFLASH); if (_Settings.ProgramMode == ProgramMode.Auto) { service.OnFirmwareProgrammedSuccessfully(); } }
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 void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session) { var info = service.TargetFileInfo; var result = session.RunGDBCommand($"-target-select remote :{LocalGDBEndpoint}"); if (result.MainStatus != "^connected") { throw new Exception("Failed to connect to gdb stub"); } result = session.RunGDBCommand("mon reset"); if (!result.IsDone) { throw new Exception("Failed to reset target"); } if (_Settings.FLASHDriver == TiXDSFLASHDriver.CC3220) { var sections = info.GetLoadableSections() .Where(section => section.LoadAddress.HasValue && section.LoadAddress.Value >= FLASHBase && section.LoadAddress.Value < (FLASHBase + MaximumFLASHSize)) .ToArray(); if (sections.Length == 0) { if (service.Mode != EmbeddedDebugMode.ConnectionTest) { session.SendInformationalOutput("No FLASH sections found in " + info.Path); result = session.RunGDBCommand("load"); if (!result.IsDone) { throw new Exception("Failed to reset target"); } } } else { bool skipLoad = false; switch (_Settings.ProgramMode) { case ProgramMode.Disabled: skipLoad = true; break; case ProgramMode.Auto: if (service.IsCurrentFirmwareAlreadyProgrammed()) { skipLoad = true; } break; } if (service.Mode == EmbeddedDebugMode.Attach || service.Mode == EmbeddedDebugMode.ConnectionTest) { skipLoad = true; } if (!skipLoad) { var resources = _Settings.FLASHResources ?? new FLASHResource[0]; using (var progr = session.CreateScopedProgressReporter("Programming FLASH...", new[] { "Erasing FLASH", "Programing FLASH" })) { var stub = new LoadedProgrammingStub(service.GetPathWithoutSpaces(Path.Combine(_BaseDir, "CC3220SF.bin")), session, _Settings); uint totalSize = 0; int totalItems = sections.Length + resources.Length; int itemsDone = 0; foreach (var sec in sections) { stub.EraseMemory((uint)sec.LoadAddress.Value, (uint)sec.Size); totalSize += (uint)sec.Size; progr.ReportTaskProgress(itemsDone, totalItems, $"Erasing {sec.Name}..."); } foreach (var r in resources) { r.ExpandedPath = service.ExpandProjectVariables(r.Path, true, true); r.Data = File.ReadAllBytes(r.ExpandedPath); stub.EraseMemory(FLASHBase + (uint)r.ParsedOffset, (uint)r.Data.Length); totalSize += (uint)r.Data.Length; progr.ReportTaskProgress(itemsDone, totalItems, $"Erasing area for {Path.GetFileName(r.ExpandedPath)}..."); } progr.ReportTaskCompletion(true); var path = service.GetPathWithoutSpaces(info.Path); uint doneTotal = 0; foreach (var sec in sections) { for (uint done = 0; done < (uint)sec.Size; done++) { uint todo = Math.Min(stub.ProgramBufferSize, (uint)sec.Size - done); progr.ReportTaskProgress(doneTotal, totalSize, $"Programming {sec.Name}..."); stub.ProgramMemory((uint)sec.LoadAddress.Value + done, path, (uint)sec.OffsetInFile + done, todo, sec.Name); doneTotal += todo; done += todo; } } foreach (var r in resources) { var imgName = Path.GetFileName(r.ExpandedPath); for (uint done = 0; done < (uint)r.Data.Length; done++) { uint todo = Math.Min(stub.ProgramBufferSize, (uint)r.Data.Length - done); progr.ReportTaskProgress(doneTotal, totalSize, $"Programming {imgName}..."); stub.ProgramMemory((uint)FLASHBase + (uint)r.ParsedOffset + done, path, done, todo, imgName); doneTotal += todo; done += todo; } } } } service.OnFirmwareProgrammedSuccessfully(); session.RunGDBCommand("set $pc=resetISR", false); } } }
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 virtual void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session) { foreach (var cmd in _Settings.StartupCommands) { if (service.Mode == EmbeddedDebugMode.Attach) { if (SkipCommandOnAttach(cmd)) { continue; } } bool isLoad = cmd.Trim() == "load"; if (isLoad) { switch (_Settings.ProgramMode) { case ProgramMode.Disabled: continue; case ProgramMode.Auto: if (service.IsCurrentFirmwareAlreadyProgrammed()) { continue; } break; } } if (isLoad) { if (isLoad && RunLoadCommand(service, session, cmd)) { service.OnFirmwareProgrammedSuccessfully(); } } else { session.RunGDBCommand(cmd); } } if (service.Mode != EmbeddedDebugMode.Attach && RISCVOpenOCDSettingsEditor.IsE300CPU(service.MCU)) { bool autoReset = _Settings.ResetMode == RISCVResetMode.nSRST; if (autoReset) { //Issuing the reset signal will only trigger the 'software reset' interrupt that causes a halt by default. //Resetting it and then setting $pc to _start does the trick, but results in strange chip resets later. //Resetting the target via nSRST and reconnecting afterwards seems to do the trick session.RunGDBCommand("mon hifive_reset"); //Manually manipulating nSRST with a gdb session active wreaks havoc in the internal gdb/gdbserver state machine, //so we simply reconnect gdb to OpenOCD. session.RunGDBCommand("-target-disconnect"); } else { service.GUIService.Report("Please reset the board by pressing the 'reset' button and wait 1-2 seconds for the reset to complete. Then press 'OK'.", System.Windows.Forms.MessageBoxIcon.Information); session.RunGDBCommand("mon halt"); session.RunGDBCommand("-target-disconnect"); } session.RunGDBCommand("-target-select remote :$$SYS:GDB_PORT$$"); var expr = session.EvaluateExpression("(void *)$pc == _start"); if (expr?.TrimStart('0', 'x') != "1") { session.SendInformationalOutput("Warning: unexpected value of $pc after a reset"); session.RunGDBCommand("set $pc = _start"); } //After resetting the CPU seems to be stuck in some state where resuming it will effectively keep it stalled, but //resuming, halting and then finally resuming again does the job. The line below does the first resume-halt pair. try { session.ResumeAndWaitForStop(200); } catch { //VisualGDB will throw a 'timed out' exception. } //If this step is skipped, subsequent break-in requests will fail using (var r = session.CreateScopedProgressReporter("Waiting for the board to initialize", new[] { "Waiting for board..." })) { int delayInTenthsOfSecond = 10; for (int i = 0; i < delayInTenthsOfSecond; i++) { Thread.Sleep(100); r.ReportTaskProgress(i, delayInTenthsOfSecond); } } } }
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)); }