Skip to content

Commit c43e39f

Browse files
authored
[projmgr] Add telnet handling
1 parent 1119d51 commit c43e39f

File tree

13 files changed

+369
-14
lines changed

13 files changed

+369
-14
lines changed

tools/projmgr/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ include(FetchContent)
1212
FetchContent_Declare(
1313
debug-adapter-registry
1414
DOWNLOAD_EXTRACT_TIMESTAMP ON
15-
URL https://github.com/Open-CMSIS-Pack/debug-adapter-registry/releases/download/v2.12.0/debug-adapter-registry.zip
16-
URL_HASH SHA256=bb372b97264496bbcb483d2e6d746427974ccdb8a9b91f42f5f8f2ee274742b0
15+
URL https://github.com/Open-CMSIS-Pack/debug-adapter-registry/releases/download/v2.12.1/debug-adapter-registry.zip
16+
URL_HASH SHA256=cdba4704cbc8f0d8815508e733b9eb2180c87f749312a6b6938ad5dbe3ace3fa
1717
)
1818
FetchContent_MakeAvailable(debug-adapter-registry)
1919
file(COPY ${debug-adapter-registry_SOURCE_DIR}/schemas/debug-adapters.schema.json DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/schemas)
@@ -52,6 +52,10 @@ SET(PROJMGR_HEADER_FILES ProjMgr.h ProjMgrKernel.h ProjMgrCallback.h
5252
list(TRANSFORM PROJMGR_SOURCE_FILES PREPEND src/)
5353
list(TRANSFORM PROJMGR_HEADER_FILES PREPEND include/)
5454

55+
if(MSVC)
56+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
57+
endif()
58+
5559
add_library(projmgrlib OBJECT
5660
${PROJMGR_SOURCE_FILES}
5761
${PROJMGR_HEADER_FILES}

tools/projmgr/include/ProjMgrParser.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ struct MemoryItem {
128128
std::string algorithm;
129129
};
130130

131+
/**
132+
* @brief telnet item containing
133+
* mode
134+
* port
135+
* file
136+
* pname
137+
*/
138+
struct TelnetItem {
139+
std::string mode;
140+
std::string port;
141+
std::string file;
142+
std::string pname;
143+
};
144+
131145
/**
132146
* @brief custom item containing
133147
* scalar
@@ -147,6 +161,7 @@ struct CustomItem {
147161
* debug clock speed
148162
* debug configuration file
149163
* start pname
164+
* telnet options
150165
* custom properties
151166
*/
152167
struct DebuggerItem {
@@ -155,6 +170,7 @@ struct DebuggerItem {
155170
std::string clock;
156171
std::string dbgconf;
157172
std::string startPname;
173+
std::vector<TelnetItem> telnet;
158174
CustomItem custom;
159175
};
160176

@@ -634,14 +650,38 @@ struct CbuildSetItem {
634650
std::string compiler;
635651
};
636652

653+
/**
654+
* @brief gdbserver defaults item containing
655+
* gdbserver port
656+
* active flag
657+
*/
658+
struct GdbServerDefaults {
659+
std::string port;
660+
bool active = false;
661+
};
662+
663+
/**
664+
* @brief telnet defaults item containing
665+
* telnet port
666+
* telnet mode
667+
* active flag
668+
*/
669+
struct TelnetDefaults {
670+
std::string port;
671+
std::string mode;
672+
bool active = false;
673+
};
674+
637675
/**
638676
* @brief debug-adapter defaults item containing
639-
* port number of processor
677+
* gdbserver defaults
678+
* telnet defaults
640679
* debug protocol(jtag or swd)
641680
* debug clock speed
642681
*/
643682
struct DebugAdapterDefaultsItem {
644-
std::string port;
683+
GdbServerDefaults gdbserver;
684+
TelnetDefaults telnet;
645685
std::string protocol;
646686
std::string clock;
647687
CustomItem custom;
@@ -659,7 +699,6 @@ struct DebugAdapterItem {
659699
std::string name;
660700
std::vector<std::string> alias;
661701
std::string templateFile;
662-
bool gdbserver = false;
663702
DebugAdapterDefaultsItem defaults;
664703
};
665704

tools/projmgr/include/ProjMgrRunDebug.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ class ProjMgrRunDebug {
225225
const std::map<std::string, RteDeviceProperty*>& pnames);
226226
void CollectDebugTopology(const ContextItem& context, std::vector<std::pair<const RteItem*, std::vector<std::string>>> debugs,
227227
const std::map<std::string, RteDeviceProperty*>& pnames);
228+
void CollectTelnetOptions(const ContextItem& context, DebugAdapterItem& adapter,
229+
const std::map<std::string, RteDeviceProperty*>& pnames);
228230
CustomItem& CustomMapFind(std::vector<std::pair<std::string, CustomItem>>& customMap, const std::string& key);
229231
void MergeCustomItems(const CustomItem& src, CustomItem& dst);
230232
};

tools/projmgr/include/ProjMgrWorker.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@ struct GdbServerItem {
283283
std::string pname;
284284
};
285285

286+
/**
287+
* @brief telnet port item extends TelnetItem containing
288+
resolved port number
289+
*/
290+
struct TelnetOptionsItem : TelnetItem {
291+
unsigned long long ullPort;
292+
};
293+
286294
/**
287295
* @brief example environment item containing
288296
* project file with extension
@@ -355,6 +363,7 @@ struct TemplateItem {
355363
* debug configuration file
356364
* start pname
357365
* list of gdbserver items
366+
* list of telnet options items
358367
* custom options
359368
*/
360369
struct DebuggerType {
@@ -365,6 +374,7 @@ struct DebuggerType {
365374
std::string dbgconf;
366375
std::string startPname;
367376
std::vector<GdbServerItem> gdbserver;
377+
std::map<std::string, TelnetOptionsItem> telnet;
368378
CustomItem custom;
369379
};
370380

tools/projmgr/include/ProjMgrYamlParser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
static constexpr const char* YAML_ACCESS = "access";
1717
static constexpr const char* YAML_ACCESSPORTS = "accessports";
18+
static constexpr const char* YAML_ACTIVE = "active";
1819
static constexpr const char* YAML_ALGORITHM = "algorithm";
1920
static constexpr const char* YAML_ALIAS = "alias";
2021
static constexpr const char* YAML_ALIAS_NAME = "alias-name";
@@ -164,6 +165,7 @@ static constexpr const char* YAML_MISC_LIBRARY = "Library";
164165
static constexpr const char* YAML_MISC_LINK = "Link";
165166
static constexpr const char* YAML_MISC_LINK_C = "Link-C";
166167
static constexpr const char* YAML_MISC_LINK_CPP = "Link-CPP";
168+
static constexpr const char* YAML_MODE = "mode";
167169
static constexpr const char* YAML_MVE = "mve";
168170
static constexpr const char* YAML_NAME = "name";
169171
static constexpr const char* YAML_NOTFORCONTEXT = "not-for-context";
@@ -234,6 +236,7 @@ static constexpr const char* YAML_TARGET_SET = "target-set";
234236
static constexpr const char* YAML_TARGETTYPE = "target-type";
235237
static constexpr const char* YAML_TARGETTYPES = "target-types";
236238
static constexpr const char* YAML_TEMPLATE = "template";
239+
static constexpr const char* YAML_TELNET = "telnet";
237240
static constexpr const char* YAML_TIMEOUT = "timeout";
238241
static constexpr const char* YAML_TRUSTZONE = "trustzone";
239242
static constexpr const char* YAML_TITLE = "title";
@@ -359,6 +362,7 @@ class ProjMgrYamlParser {
359362
bool ParseLinker(const YAML::Node& parent, const std::string& file, std::vector<LinkerItem>& linker);
360363
void ParseRte(const YAML::Node& parent, std::string& rteBaseDir);
361364
void ParseDebugDefaults(const YAML::Node& parent, const std::string& file, DebugAdapterDefaultsItem& defaults);
365+
void ParseTelnet(const YAML::Node& parent, const std::string& file, std::vector<TelnetItem>& telnet);
362366
void ParseCustom(const YAML::Node& parent, const std::vector<std::string>& skip, CustomItem& custom);
363367
bool GetTypes(const std::string& type, std::string& buildType, std::string& targetType, std::string& pattern);
364368
bool ValidateCdefault(const std::string& input, const YAML::Node& root);

tools/projmgr/schemas/common.schema.json

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,11 +2217,30 @@
22172217
"clock": { "type": "number", "description": "Selected debug clock speed (in Hz)." },
22182218
"dbgconf": { "type": "string", "description": "Debugger configuration file (pinout, trace)." },
22192219
"start-pname": { "type": "string", "description": "Debugger connects at start to this processor." },
2220-
"gdbserver": { "$ref": "#/definitions/GdbServersType" }
2220+
"gdbserver": { "$ref": "#/definitions/GdbServersType" },
2221+
"telnet": { "$ref": "#/definitions/TelnetOptionsType" }
22212222
},
22222223
"additionalProperties": true,
22232224
"required": ["name"]
22242225
},
2226+
"TelnetOptionsType": {
2227+
"title": "telnet:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-Input-Format/#telnet-for-pyocd",
2228+
"description": "Telnet port for connecting remote tools.",
2229+
"type": "array",
2230+
"uniqueItems": true,
2231+
"items": { "$ref": "#/definitions/TelnetOptionType" }
2232+
},
2233+
"TelnetOptionType": {
2234+
"type": "object",
2235+
"properties": {
2236+
"mode": { "enum": [ "off", "server", "file", "console", "monitor" ], "description": "Redirect output mode." },
2237+
"pname": { "type": "string", "description": "Processor name of the processor (only required for multi-core systems)." },
2238+
"port": { "type": "number", "description": "Set TCP/IP port number of Telnet Server." },
2239+
"file": { "type": "string", "description": "Base path and name of the telnet output file (without extension)."}
2240+
},
2241+
"additionalProperties": false,
2242+
"required": ["mode"]
2243+
},
22252244
"GdbServersType": {
22262245
"title": "gdbserver:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-CBuild-Format/#gdbserver",
22272246
"description": "Information for GDB server option of debugger.",
@@ -2431,7 +2450,8 @@
24312450
"protocol": { "enum": [ "jtag", "swd" ], "description": "Selected debug protocol (jtag or swd)." },
24322451
"clock": { "type": "number", "description": "Selected debug clock speed (in Hz)." },
24332452
"dbgconf": { "type": "string", "description": "Debugger configuration file (pinout, trace)." },
2434-
"start-pname": { "type": "string", "description": "Debugger connects at start to this processor." }
2453+
"start-pname": { "type": "string", "description": "Debugger connects at start to this processor." },
2454+
"telnet": { "$ref": "#/definitions/TelnetOptionsType" }
24352455
},
24362456
"additionalProperties": true,
24372457
"required": ["name"]

tools/projmgr/src/ProjMgrCbuildRun.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ProjMgrCbuildRun : public ProjMgrCbuildBase {
3232
void SetAccessPortsNode(YAML::Node node, const std::vector<AccessPortType>& accessPorts);
3333
void SetDatapatchNode(YAML::Node node, const std::vector<DatapatchType>& datapatch);
3434
void SetGdbServerNode(YAML::Node node, const std::vector<GdbServerItem>& gdbserver);
35+
void SetTelnetNode(YAML::Node node, const std::map<std::string, TelnetOptionsItem>& telnet);
3536
void SetCustomNodes(YAML::Node node, const CustomItem& debugger);
3637
YAML::Node GetCustomNode(const CustomItem& value);
3738
};
@@ -112,6 +113,7 @@ void ProjMgrCbuildRun::SetDebuggerNode(YAML::Node node, const DebuggerType& debu
112113
}
113114
SetNodeValue(node[YAML_START_PNAME], debugger.startPname);
114115
SetGdbServerNode(node[YAML_GDBSERVER], debugger.gdbserver);
116+
SetTelnetNode(node[YAML_TELNET], debugger.telnet);
115117
SetCustomNodes(node, debugger.custom);
116118
}
117119
}
@@ -149,6 +151,19 @@ void ProjMgrCbuildRun::SetGdbServerNode(YAML::Node node, const std::vector<GdbSe
149151
}
150152
}
151153

154+
void ProjMgrCbuildRun::SetTelnetNode(YAML::Node node, const std::map<std::string, TelnetOptionsItem>& telnet) {
155+
for (const auto& [pname, item] : telnet) {
156+
YAML::Node telnetNode;
157+
SetNodeValue(telnetNode[YAML_MODE], item.mode);
158+
SetNodeValue(telnetNode[YAML_PNAME], pname);
159+
telnetNode[YAML_PORT] = item.ullPort;
160+
if (!item.file.empty()) {
161+
SetNodeValue(telnetNode[YAML_FILE], FormatPath(item.file, m_directory));
162+
}
163+
node.push_back(telnetNode);
164+
}
165+
}
166+
152167
void ProjMgrCbuildRun::SetDebugVarsNode(YAML::Node node, const DebugVarsType& debugVars) {
153168
if (!debugVars.vars.empty()) {
154169
SetNodeValue(node[YAML_VARS], "|\n" + debugVars.vars);

tools/projmgr/src/ProjMgrRunDebug.cpp

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,12 @@ void ProjMgrRunDebug::CollectDebuggerSettings(const ContextItem& context, const
322322
}
323323

324324
// add info from debug-adapters
325+
DebugAdapterItem adapter;
325326
if (!adapters.empty()) {
326-
DebugAdapterItem adapter;
327327
if (GetDebugAdapter(m_runDebug.debugger.name, adapters, adapter)) {
328328
m_runDebug.debugger.name = adapter.name;
329-
if (adapter.gdbserver) {
330-
unsigned long long port = adapter.defaults.port.empty() ? 0 : RteUtils::StringToULL(adapter.defaults.port);
329+
if (adapter.defaults.gdbserver.active) {
330+
unsigned long long port = adapter.defaults.gdbserver.port.empty() ? 0 : RteUtils::StringToULL(adapter.defaults.gdbserver.port);
331331
// add primary processor port first
332332
m_runDebug.debugger.gdbserver.push_back({ port, m_runDebug.debugger.startPname });
333333
for (const auto& [pname, _] : pnames) {
@@ -348,8 +348,77 @@ void ProjMgrRunDebug::CollectDebuggerSettings(const ContextItem& context, const
348348
}
349349
}
350350

351+
// collect telnet options
352+
CollectTelnetOptions(context, adapter, pnames);
353+
351354
// merge custom options
352355
MergeCustomItems(context.debugger.custom, m_runDebug.debugger.custom);
356+
357+
}
358+
359+
void ProjMgrRunDebug::CollectTelnetOptions(const ContextItem& context, DebugAdapterItem& adapter,
360+
const std::map<std::string, RteDeviceProperty*>& pnames) {
361+
if (!context.debugger.telnet.empty() || adapter.defaults.telnet.active) {
362+
set<unsigned long long> usedPorts;
363+
const string fileBase = context.directories.cprj + "/" + context.directories.outBaseDir + "/" +
364+
m_runDebug.solutionName + "+" + m_runDebug.targetType;
365+
366+
// get values from user definitions
367+
for (const auto& [pname, value] : context.debugger.telnet) {
368+
if (pnames.size() > 1 && value.pname.empty()) {
369+
ProjMgrLogger::Get().Warn("'telnet:' pname is required (multicore device)");
370+
continue;
371+
}
372+
if (pnames.find(pname) == pnames.end()) {
373+
ProjMgrLogger::Get().Warn("pname '" + pname + "' does not match any device pname");
374+
continue;
375+
}
376+
m_runDebug.debugger.telnet[pname] = { value };
377+
if (!value.port.empty()) {
378+
m_runDebug.debugger.telnet[pname].ullPort = RteUtils::StringToULL(value.port);
379+
usedPorts.insert(m_runDebug.debugger.telnet[pname].ullPort);
380+
}
381+
if (value.mode.empty()) {
382+
m_runDebug.debugger.telnet[pname].mode = adapter.defaults.telnet.mode.empty() ? "monitor" : adapter.defaults.telnet.mode;
383+
}
384+
if (value.mode == "file" && value.file.empty()) {
385+
m_runDebug.debugger.telnet[pname].file = fileBase + (pname.empty() ? "" : '.' + pname);
386+
}
387+
}
388+
// active flag: enable telnet options for all cores
389+
if (adapter.defaults.telnet.active) {
390+
for (const auto& [pname, _] : pnames) {
391+
auto& telnet = m_runDebug.debugger.telnet[pname];
392+
if (telnet.mode.empty() || telnet.mode == "off") {
393+
telnet.mode = adapter.defaults.telnet.mode.empty() ? "monitor" : adapter.defaults.telnet.mode;
394+
}
395+
}
396+
}
397+
// port number handling
398+
unsigned long long port = adapter.defaults.telnet.port.empty() ? 0 : RteUtils::StringToULL(adapter.defaults.telnet.port);
399+
if (m_runDebug.debugger.telnet.find(m_runDebug.debugger.startPname) != m_runDebug.debugger.telnet.end()) {
400+
// add primary processor port first
401+
auto& startPort = m_runDebug.debugger.telnet[m_runDebug.debugger.startPname].ullPort;
402+
if (startPort == 0) {
403+
startPort = port;
404+
} else {
405+
port = startPort;
406+
}
407+
usedPorts.insert(port);
408+
}
409+
for (auto& [pname, telnet] : m_runDebug.debugger.telnet) {
410+
// add ports for other processors
411+
if (pname != m_runDebug.debugger.startPname) {
412+
// get customized port if set
413+
port = telnet.port.empty() ? port : telnet.ullPort;
414+
while (usedPorts.find(port) != usedPorts.end()) {
415+
// skip port number if it has already been used
416+
port++;
417+
}
418+
telnet.ullPort = port;
419+
}
420+
}
421+
}
353422
}
354423

355424
void ProjMgrRunDebug::CollectDebugTopology(const ContextItem& context, const vector<pair<const RteItem*, vector<string>>> debugs,

tools/projmgr/src/ProjMgrWorker.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,6 +2646,14 @@ bool ProjMgrWorker::ProcessDebuggers(ContextItem& context) {
26462646
}
26472647
}
26482648
context.debugger.startPname = m_activeTargetSet.debugger.startPname;
2649+
for (auto telnet : m_activeTargetSet.debugger.telnet) {
2650+
if (!telnet.file.empty()) {
2651+
if (!ProcessSequenceRelative(context, telnet.file, context.csolution->directory)) {
2652+
return false;
2653+
}
2654+
}
2655+
context.debugger.telnet[telnet.pname] = { telnet };
2656+
}
26492657
context.debugger.custom = m_activeTargetSet.debugger.custom;
26502658
}
26512659
for (const auto& [filename, fi] : context.rteActiveProject->GetFileInstances()) {

0 commit comments

Comments
 (0)