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));
        }
예제 #2
0
        public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context)
        {
            if (startService.Mode == EmbeddedDebugMode.ConnectionTest)
            {
                startService.GUIService.Report("Please ensure the firmware with the gdb stub is running on your board, then reset it and connect the COM port to your computer.");
            }

            return(new GDBStubInstance(context));
        }
예제 #3
0
 public RenesasGDBStub(DebugStartContext context, RenesasDebugSettings settings, RenesasGDBServerCommandLine cmdLine, int gdbPort, IExternalToolInstance tool, string peripheralFile, bool loadFLASH)
 {
     Tool            = tool;
     _CmdLine        = cmdLine;
     _GDBPort        = gdbPort;
     _Settings       = settings;
     _PeripheralFile = peripheralFile;
     _LoadFLASH      = loadFLASH;
 }
예제 #4
0
            public GDBStubInstance(DebugStartContext context)
            {
                _Context  = context;
                _Settings = (ESP8266GDBStubSettings)_Context.Configuration;

                if (context.ResolvedDevices?.BestMatch.COMPortNumber.HasValue == true)
                {
                    _COMPort = "COM" + context.ResolvedDevices.BestMatch.COMPortNumber;
                }
                else
                {
                    _COMPort = _Settings.COMPort;
                }
            }
예제 #5
0
        public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context)
        {
            var settings = context.Configuration as ESP32GDBStubSettings;

            if (settings == null)
            {
                throw new Exception("Missing ESP32 stub settings");
            }

            var svc = startService.AdvancedDebugService as IExternallyProgrammedProjectDebugService ?? throw new Exception("This project type does not support external FLASH memory programming");

            svc.ProgramFLASHMemoryUsingExternalTool(settings.ProgramMode);

            startService.GUIService.Report("The FLASH memory has been programmed, however the ESP32 GDB stub does not support live debugging yet. Please use JTAG if you want to debug your program or reset your board to run the program without debugging.");
            throw new OperationCanceledException();
        }
예제 #6
0
 public RedLinkGDBStub(
     DebugStartContext context,
     RedLinkDebugSettings settings,
     RedLinkServerCommandLine cmdLine,
     int gdbPort,
     IExternalToolInstance tool,
     bool programNow,
     string explicitSerialNumber,
     int coreIndex)
 {
     Tool                  = tool;
     _GDBPort              = gdbPort;
     _Settings             = settings;
     _LoadFLASH            = programNow;
     _ExplicitSerialNumber = explicitSerialNumber;
     _CoreIndex            = coreIndex;
 }
예제 #7
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));
        }
예제 #8
0
            public GDBStubInstance(DebugStartContext context, IDebugStartService startService)
            {
                _Context  = context;
                _Settings = (ESP8266GDBStubSettings)_Context.Configuration;

                if (startService.AdvancedDebugService is IExternallyProgrammedProjectDebugService eps)
                {
                    _COMPort = eps.TryGetProgrammingCOMPortIfKnown(true) ?? _COMPort;
                }
                else if (context.ResolvedDevices?.BestMatch.COMPortNumber.HasValue == true)
                {
                    _COMPort = "COM" + context.ResolvedDevices.BestMatch.COMPortNumber;
                }
                else
                {
                    _COMPort = _Settings.COMPort;
                }
            }
예제 #9
0
        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));
        }
예제 #10
0
 public ESP8266GDBStub(ESP8266DebugController controller, DebugStartContext context, OpenOCDCommandLine cmdLine, IExternalToolInstance tool, ESPxxOpenOCDSettings settings, int gdbPort, int telnetPort, string temporaryScript)
     : base(cmdLine, tool, settings, gdbPort, telnetPort, temporaryScript)
 {
     _Controller = controller;
     _Context    = context;
 }
예제 #11
0
 protected override IGDBStubInstance CreateStub(DebugStartContext context, OpenOCDSettings settings, OpenOCDCommandLine cmdLine, int gdbPort, int telnetPort, string temporaryScript, IExternalToolInstance tool)
 {
     return(new ESP8266GDBStub(this, context, cmdLine, tool, (ESP8266OpenOCDSettings)settings, gdbPort, telnetPort, temporaryScript));
 }
예제 #12
0
 protected override abstract IGDBStubInstance CreateStub(DebugStartContext context, OpenOCDSettings settings, OpenOCDCommandLine cmdLine, int gdbPort, int telnetPort, string temporaryScript, IExternalToolInstance tool);
예제 #13
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.ProgramFLASHUsingExternalTool)
                {
                    var svc = service.AdvancedDebugService as IExternallyProgrammedProjectDebugService ?? throw new Exception("This project type does not support external FLASH memory programming");
                    svc.ProgramFLASHMemoryUsingExternalTool(settings.ProgramMode);
                }
                else
                {
                    List <ProgrammableRegion> blocks = BuildProgrammableBlocksFromSettings(service, settings);

                    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('\\', '/');
                            if (path.Contains(" "))
                            {
                                throw new Exception($"ESP32 OpenOCD does not support spaces in paths. Please relocate {path} to a location without spaces");
                            }
                            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);
        }
예제 #14
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));
        }
예제 #15
0
        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));
        }
예제 #16
0
        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));
        }
예제 #17
0
 public GDBStubInstance(DebugStartContext context, List <ProgrammableRegion> regions)
 {
     _Context     = context;
     _RegionCount = regions;
 }
예제 #18
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);
        }
예제 #19
0
 protected virtual IGDBStubInstance CreateStub(DebugStartContext context, RISCVOpenOCDSettings settings, OpenOCDCommandLine cmdLine, int gdbPort, int telnetPort, string temporaryScript, IExternalToolInstance tool)
 {
     return(new OpenOCDGDBStub(cmdLine, tool, settings, gdbPort, telnetPort, temporaryScript));
 }
예제 #20
0
        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();
        }
예제 #21
0
 public StubInstance(DebugStartContext context, IExternalToolInstance tool, int GDBPort, AVaRICEDebugSettings settings)
 {
     Tool      = tool;
     _GDBPort  = GDBPort;
     _Settings = settings;
 }