示例#1
0
        public static List <ProgrammableRegion> BuildProgrammableBlocksFromSettings(IDebugStartService service, IESP32Settings settings)
        {
            List <ProgrammableRegion> blocks;

            if (BuildProgrammableBlocksFromSynthesizedESPIDFVariables(service, out blocks))
            {
                //Nothing to do. Successfully built the block list.
            }
            else
            {
                bool patchBootloader = settings.PatchBootloader;
                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));
                    }
                }
            }
            return(blocks);
        }
        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)
        {
            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));
        }
            public ILiveMemoryEvaluator CreateLiveMemoryEvaluator(IDebugStartService service)
            {
                if (_TelnetPort == 0)
                {
                    return(null);
                }

                return(new LiveMemoryEvaluator(_TelnetPort));
            }
示例#5
0
            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);
                    }
                }
            }
示例#6
0
            public void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session)
            {
                using (var r = session.CreateScopedProgressReporter("Programming FLASH memory", new string[] { "Loading FLASH memory" }))
                {
                    Regex rgPercentage = new Regex(@"(.*)\( *([0-9]+) *% *\)");

                    EventHandler <LineReceivedEventArgs> handler = (s, e) =>
                    {
                        session.SendInformationalOutput(e.Line);
                        r.AppendLogLine(e.Line);
                        var m = rgPercentage.Match(e.Line);
                        if (m.Success)
                        {
                            int value = int.Parse(m.Groups[2].Value);
                            r.ReportTaskProgress(value, 100, m.Groups[1].ToString());
                        }
                    };

                    try
                    {
                        Tool.LineReceived += handler;
                        while (Tool.IsRunning && !r.IsAborted)
                        {
                            Thread.Sleep(100);
                        }

                        if (r.IsAborted)
                        {
                            Tool.TerminateProgram();
                            throw new OperationCanceledException();
                        }
                    }
                    finally
                    {
                        Tool.LineReceived -= handler;
                    }
                }

                string text       = Tool.AllText;
                int    validLines = text.Split('\n').Count(l => l.Trim() == "Hash of data verified.");

                if (validLines >= _RegionCount.Count)
                {
                    service.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.");
                }
                else
                {
                    throw new Exception("Warning: some of the FLASH regions could not be programmed. Please examine the stub output for details.");
                }

                throw new OperationCanceledException();
            }
示例#7
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();
        }
示例#8
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 void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session)
            {
                ReportFLASHProgrammingProgress(Tool, service, session);
                string text       = Tool.AllText;
                int    validLines = text.Split('\n').Count(l => l.Trim() == "Hash of data verified.");

                if (validLines >= _RegionCount.Count)
                {
                    service.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.");
                }
                else
                {
                    throw new Exception("Warning: some of the FLASH regions could not be programmed. Please examine the stub output for details.");
                }

                throw new OperationCanceledException();
            }
            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;
                }
            }
示例#11
0
            public void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session)
            {
                //We may need to wait for the AVaRICE to complete programming the FLASH memory.
                int timeout = _Settings.GDBTimeout;

                if (timeout != 0)
                {
                    session.RunGDBCommand($"set remotetimeout {timeout}");
                    session.RunGDBCommand($"set tcp connect-timeout {timeout}");
                    session.RunGDBCommand($"set tcp auto-retry on");
                }

                var result = session.RunGDBCommand($"target remote :{_GDBPort}");

                if (!result.IsDone)
                {
                    throw new Exception("Failed to connect to AVaRICE");
                }
            }
示例#12
0
        public static bool BuildProgrammableBlocksFromSynthesizedESPIDFVariables(IDebugStartService service, out 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"])
                    });
                }
                return(true);
            }

            blocks = null;
            return(false);
        }
示例#13
0
        public static List <ProgrammableRegion> BuildProgrammableBlocksFromSettings(IDebugStartService service, IESP32Settings settings)
        {
            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.PatchBootloader;
                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));
                    }
                }
            }
            return(blocks);
        }
示例#14
0
            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();
                }
            }
示例#15
0
 protected override bool RunLoadCommand(IDebugStartService service, ISimpleGDBSession session, string cmd) => throw new NotSupportedException();
示例#16
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);
        }
示例#17
0
 protected override bool RunLoadCommand(IDebugStartService service, ISimpleGDBSession session, string cmd) => _Controller.LoadFLASH(_Context, service, session, (ESP32OpenOCDSettings)_Settings, this);
            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 ILiveMemoryEvaluator CreateLiveMemoryEvaluator(IDebugStartService service) => null;
            public static void ReportFLASHProgrammingProgress(IExternalToolInstance tool, IDebugStartService service, ISimpleGDBSession session)
            {
                using (var r = session.CreateScopedProgressReporter("Programming FLASH memory", new string[] { "Loading FLASH memory" }))
                {
                    Regex rgPercentage = new Regex(@"(.*)\( *([0-9]+) *% *\)");

                    EventHandler <LineReceivedEventArgs> handler = (s, e) =>
                    {
                        session.SendInformationalOutput(e.Line);
                        r.AppendLogLine(e.Line);
                        var m = rgPercentage.Match(e.Line);
                        if (m.Success)
                        {
                            int value = int.Parse(m.Groups[2].Value);
                            r.ReportTaskProgress(value, 100, m.Groups[1].ToString());
                        }
                    };

                    try
                    {
                        tool.LineReceived += handler;
                        while (tool.IsRunning && !r.IsAborted)
                        {
                            Thread.Sleep(100);
                        }

                        if (r.IsAborted)
                        {
                            tool.TerminateProgram();
                            throw new OperationCanceledException();
                        }
                    }
                    finally
                    {
                        tool.LineReceived -= handler;
                    }
                }
            }
示例#21
0
        public static bool RunSequence(ILoadProgressReporter reporter, IDebugStartService service, ISimpleGDBSession session, CustomStartupSequence sequence)
        {
            var espCmds = sequence.Steps;

            if (espCmds != null)
            {
                DateTime startTime = DateTime.Now;

                int total = 0, done = 0;
                foreach (var s in espCmds)
                {
                    total += s.ProgressWeight;
                }

                for (int retry = 0; ; retry++)
                {
                    try
                    {
                        foreach (var s in espCmds)
                        {
                            SimpleGDBCommandResult r = default(SimpleGDBCommandResult);

                            foreach (var scmd in s.Commands)
                            {
                                r = session.RunGDBCommand(scmd);
                            }

                            bool failed = false;
                            if (s.ResultVariable != null)
                            {
                                string val = session.EvaluateExpression(s.ResultVariable);
                                if (val != "0")
                                {
                                    failed = true;
                                }
                            }
                            if (s.CheckResult && !failed)
                            {
                                failed = r.MainStatus != "^done";
                            }

                            if (failed)
                            {
                                string msg = s.ErrorMessage ?? "Custom FLASH programming step failed";
                                if (s.CanRetry)
                                {
                                    throw new RetriableException(msg);
                                }
                                else
                                {
                                    throw new Exception(msg);
                                }
                            }

                            done += s.ProgressWeight;
                            reporter.ReportTaskProgress(done, total);
                        }
                        break;
                    }
                    catch (RetriableException)
                    {
                        if (retry < 2)
                        {
                            continue;
                        }
                        throw;
                    }
                }

                reporter.ReportTaskCompletion(true);
                session.SendInformationalOutput("Loaded image in " + (int)(DateTime.Now - startTime).TotalMilliseconds + " ms");
            }

            if (!string.IsNullOrEmpty(sequence.InitialHardBreakpointExpression))
            {
                session.RequestInitialBreakpoint(service.ExpandProjectVariables(sequence.InitialHardBreakpointExpression, true, false));
            }

            return(true);
        }
示例#22
0
            static void DoConnect(IDebugStartService service, ISimpleGDBSession session, ESP8266GDBStubSettings settings, string comPort, bool programFLASH)
            {
                var targetPath = service.TargetPath;

                if (targetPath != null) //When doing connection test without an active project, the targetPath will be NULL
                {
                    if (!File.Exists(targetPath))
                    {
                        throw new Exception(targetPath + " not found. Debugging will not be possible.");
                    }

                    bool stubFound = false;
                    using (var elf = new ELFFile(targetPath))
                    {
                        foreach (var sym in elf.LoadAllSymbols())
                        {
                            if (sym.Name == "gdbstub_init")
                            {
                                stubFound = true;
                                break;
                            }
                        }
                    }


                    if (!stubFound)
                    {
                        if (service.GUIService.Prompt("The programmed image does not contain the GDB stub. Do you want to open instructions on debugging with ESP8266 GDB stub?", MessageBoxIcon.Warning))
                        {
                            Process.Start("http://visualgdb.com/KB/esp8266gdbstub");
                            throw new OperationCanceledException();
                        }
                    }
                }

                List <string> steps = new List <string>();

                if (programFLASH)
                {
                    steps.Add("Connecting to bootloader");
                    steps.Add("Programming FLASH memory");
                }
                if (service.Mode != EmbeddedDebugMode.ProgramWithoutDebugging)
                {
                    steps.Add("Connecting to GDB stub");
                }

                using (var ctx = session.CreateScopedProgressReporter("Connecting to target device", steps.ToArray()))
                {
                    if (programFLASH)
                    {
                        if (!settings.SuppressResetConfirmation)
                        {
                            service.GUIService.Report("Please reboot your ESP8266 into the bootloader mode and press OK.");
                        }

                        using (var serialPort = new SerialPortStream(comPort, settings.BootloaderBaudRate, System.IO.Ports.Handshake.None))
                        {
                            serialPort.AllowTimingOutWithZeroBytes = true;

                            ESP8266BootloaderClient client = new ESP8266BootloaderClient(serialPort, settings.BootloaderResetDelay, settings.BootloaderActivationSequence);
                            client.Sync();
                            var regions = ESP8266StartupSequence.BuildFLASHImages(service, settings, (l, t) => session.SendInformationalOutput(l));

                            ctx.ReportTaskCompletion(true);

                            int totalSize = 0, writtenSize = 0;
                            foreach (var r in regions)
                            {
                                totalSize += r.Size;
                            }

                            ESP8266BootloaderClient.BlockWrittenHandler handler = (s, addr, len) => ctx.ReportTaskProgress(writtenSize += len, totalSize, $"Writing FLASH at 0x{addr:x8}...");
                            bool useDIO = false;

                            try
                            {
                                client.BlockWritten += handler;
                                foreach (var r in regions)
                                {
                                    var data = File.ReadAllBytes(r.FileName);
                                    if (r.Offset == 0 && data.Length >= 4)
                                    {
                                        useDIO = (data[2] == 2);
                                    }

                                    client.ProgramFLASH((uint)r.Offset, data);
                                }
                            }
                            finally
                            {
                                client.BlockWritten -= handler;
                            }

                            client.RunProgram(useDIO, false);
                        }
                    }

                    ctx.ReportTaskCompletion(true);

                    if (service.Mode != EmbeddedDebugMode.ProgramWithoutDebugging)
                    {
                        ctx.ReportTaskCompletion(true);
                        session.RunGDBCommand("set serial baud " + settings.StubBaudRate);
                        var result = session.RunGDBCommand(@"target remote \\.\" + comPort);
                        if (!result.IsDone)
                        {
                            throw new Exception("Failed to connect to the gdb stub. Please check your settings.");
                        }
                    }
                }
            }
示例#23
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));
        }
示例#24
0
 public ILiveMemoryEvaluator CreateLiveMemoryEvaluator(IDebugStartService service)
 {
     return(null);
 }
示例#25
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));
        }
示例#26
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));
        }
示例#27
0
            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);
                    }
                }
            }
示例#28
0
 public ILiveMemoryEvaluator CreateLiveMemoryEvaluator(IDebugStartService service)
 {
     throw new NotImplementedException();
 }
        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();
        }
 protected virtual bool RunLoadCommand(IDebugStartService service, ISimpleGDBSession session, string cmd)
 {
     return(session.RunGDBCommand(cmd).IsDone);
 }