Esempio n. 1
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);
                    }
                }
            }
            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();
                }
            }
Esempio n. 3
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);
                    }
                }
            }
Esempio n. 4
0
        public IGDBStubInstance StartGDBStub(IDebugStartService startService, DebugStartContext context)
        {
            var settings = context.Configuration as TiXDSDebugSettings ?? throw new Exception("Missing debug method settings");

            var exe = new TiXDSSettingsEditor(settings).GDBAgentExecutable;

            if (string.IsNullOrEmpty(exe) || !File.Exists(exe))
            {
                throw new Exception("Missing TI XDS stub: " + exe);
            }

            string configFile = null;

            switch (settings.FLASHDriver)
            {
            case TiXDSFLASHDriver.CC3220:
                configFile = "cc3220s.dat";
                break;

            case TiXDSFLASHDriver.UniFLASH:
                configFile = Path.Combine(context.Method.Directory, "rm57x.dat");
                break;
            }

            if (settings.FLASHDriver == TiXDSFLASHDriver.UniFLASH && startService.Mode != EmbeddedDebugMode.ConnectionTest && startService.Mode != EmbeddedDebugMode.Attach)
            {
                bool skipLoad = false;

                switch (settings.ProgramMode)
                {
                case ProgramMode.Disabled:
                    skipLoad = true;
                    break;

                case ProgramMode.Auto:
                    if (startService.IsCurrentFirmwareAlreadyProgrammed())
                    {
                        skipLoad = true;
                    }
                    break;
                }

                if (!skipLoad)
                {
                    string uniFLASHDir = Path.Combine(context.Method.Directory, "UniFLASH");
                    var    programTool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo {
                        Command = Path.Combine(uniFLASHDir, "dslite.bat"), Arguments = $@"--config={uniFLASHDir}\user_files\configs\rm57l8xx.ccxml {startService.TargetPath} --verbose", ShowInGDBStubWindow = true
                    });
                    using (var logFile = new FileStream(Path.Combine(Path.GetDirectoryName(startService.TargetPath), "UniFLASH.log"), FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                    {
                        programTool.LineReceived += (s, e) =>
                        {
                            try
                            {
                                byte[] data = Encoding.UTF8.GetBytes(e.Line + "\r\n");
                                logFile.Write(data, 0, data.Length);
                                logFile.Flush();
                            } catch { };
                        };

                        while (programTool.IsRunning)
                        {
                            Thread.Sleep(100);
                        }

                        if (programTool.ExitCode != 0)
                        {
                            throw new Exception($"UniFLASH exited with code {programTool.ExitCode}. Please check UniFLASH.log.");
                        }
                    }

                    startService.OnFirmwareProgrammedSuccessfully();
                }
            }

            if (!string.IsNullOrEmpty(settings.CustomConfigFile))
            {
                configFile = settings.CustomConfigFile;
            }

            var tool = startService.LaunchCommandLineTool(new CommandLineToolLaunchInfo {
                Command = exe, WorkingDirectory = Path.GetDirectoryName(exe), Arguments = configFile
            });

            return(new StubInstance(context.Method.Directory, settings, tool));
        }
            public 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);
                        }
                    }
                }
            }
Esempio n. 6
0
            public virtual void ConnectGDBToStub(IDebugStartService service, ISimpleGDBSession session)
            {
                string[] regularStartupCommands = new[]
                {
                    "-gdb-set breakpoint pending on",
                    "-gdb-set detach-on-fork on",
                    "-gdb-set python print-stack none",
                    "-gdb-set print object on",
                    "-gdb-set print sevenbit-strings on",
                    "-gdb-set host-charset UTF-8",
                    "-gdb-set target-charset WINDOWS-1252",
                    "-gdb-set target-wide-charset UTF-16",
                    "-gdb-set pagination off",
                    "-gdb-set auto-solib-add on",
                    "inferior 1",
                    "set remotetimeout 10",
                    "set tcp connect-timeout 30",
                };

                SimpleGDBCommandResult result;

                foreach (var cmd in regularStartupCommands)
                {
                    result = session.RunGDBCommand(cmd);
                    if (!result.IsDone)
                    {
                        throw new Exception("GDB command failed: " + cmd);
                    }
                }

                session.EnableAsyncMode(GDBAsyncMode.AsyncWithTemporaryBreaks, true, true);
                session.ConnectToExtendedRemote(null, _GDBPort, true);

                result = session.RunGDBCommand("mon is_target_connected");
                if (!result.IsDone)
                {
                    throw new Exception("The target did not report connection state");
                }

                if (result.StubOutput?.FirstOrDefault(l => l.Trim() == "Connection status=connected.") == null)
                {
                    throw new Exception("The Renesas gdb stub is not connected to the target.");
                }

                result = ParseAndApplyIOAccessWidths(service, session, result);

                result = session.RunGDBCommand("monitor get_no_hw_bkpts_available");
                if (result.IsDone && result.StubOutput != null)
                {
                    foreach (var line in result.StubOutput)
                    {
                        if (int.TryParse(line.Trim(), out var tmp))
                        {
                            session.RunGDBCommand($"set remote hardware-breakpoint-limit " + tmp);
                            break;
                        }
                    }
                }

                result = session.RunGDBCommand("monitor get_target_max_address");
                if (result.IsDone && result.StubOutput != null)
                {
                    foreach (var line in result.StubOutput)
                    {
                        string trimmedLine = line.Trim();
                        if (trimmedLine.StartsWith("0x") && int.TryParse(trimmedLine.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out var tmp))
                        {
                            session.RunGDBCommand($"mem 0x0 0x{tmp + 1:x} rw 8 nocache");
                            break;
                        }
                    }
                }

                result = session.RunGDBCommand("monitor configuration_complete");

                if (_LoadFLASH)
                {
                    result = session.RunGDBCommand("monitor prg_download_start_on_connect");

                    result = session.RunGDBCommand("load");
                    if (!result.IsDone)
                    {
                        throw new Exception("Failed to program FLASH memory");
                    }

                    service.OnFirmwareProgrammedSuccessfully();

                    result = session.RunGDBCommand("monitor prg_download_end");
                }

                string[] finalCommands = new[]
                {
                    "monitor reset",
                    "monitor enable_stopped_notify_on_connect",
                    "monitor enable_execute_on_connect",
                };

                using (var awaiter = session.InterceptFirstStoppedEvent())
                {
                    foreach (var cmd in finalCommands)
                    {
                        result = session.RunGDBCommand(cmd);
                        if (!result.IsDone)
                        {
                            throw new Exception("GDB command failed: " + cmd);
                        }
                    }

                    while (!awaiter.WaitForStop(100))
                    {
                        session.RunGDBCommand("monitor do_nothing");
                    }
                }
            }