Esempio n. 1
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));
        }
Esempio n. 2
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. 3
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);
        }
Esempio n. 4
0
 public ProgrammableRegion ToProgrammableRegion(IDebugStartService service)
 {
     return(new ProgrammableRegion {
         FileName = service.ExpandProjectVariables(Path, true, true), Offset = ParseAddress(Offset)
     });
 }