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); } } }