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));
        }
Example #2
0
        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));
        }
Example #5
0
        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));
        }
Example #7
0
        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));
        }