diff --git a/tools/projmgr/CMakeLists.txt b/tools/projmgr/CMakeLists.txt index 0d7122dc3..f786579ae 100644 --- a/tools/projmgr/CMakeLists.txt +++ b/tools/projmgr/CMakeLists.txt @@ -12,8 +12,8 @@ include(FetchContent) FetchContent_Declare( debug-adapter-registry DOWNLOAD_EXTRACT_TIMESTAMP ON - URL https://github.com/Open-CMSIS-Pack/debug-adapter-registry/releases/download/v2.12.0/debug-adapter-registry.zip - URL_HASH SHA256=bb372b97264496bbcb483d2e6d746427974ccdb8a9b91f42f5f8f2ee274742b0 + URL https://github.com/Open-CMSIS-Pack/debug-adapter-registry/releases/download/v2.12.1/debug-adapter-registry.zip + URL_HASH SHA256=cdba4704cbc8f0d8815508e733b9eb2180c87f749312a6b6938ad5dbe3ace3fa ) FetchContent_MakeAvailable(debug-adapter-registry) 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 list(TRANSFORM PROJMGR_SOURCE_FILES PREPEND src/) list(TRANSFORM PROJMGR_HEADER_FILES PREPEND include/) +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") +endif() + add_library(projmgrlib OBJECT ${PROJMGR_SOURCE_FILES} ${PROJMGR_HEADER_FILES} diff --git a/tools/projmgr/include/ProjMgrParser.h b/tools/projmgr/include/ProjMgrParser.h index 3c6dbef59..b24deb63d 100644 --- a/tools/projmgr/include/ProjMgrParser.h +++ b/tools/projmgr/include/ProjMgrParser.h @@ -128,6 +128,20 @@ struct MemoryItem { std::string algorithm; }; +/** + * @brief telnet item containing + * mode + * port + * file + * pname +*/ +struct TelnetItem { + std::string mode; + std::string port; + std::string file; + std::string pname; +}; + /** * @brief custom item containing * scalar @@ -147,6 +161,7 @@ struct CustomItem { * debug clock speed * debug configuration file * start pname + * telnet options * custom properties */ struct DebuggerItem { @@ -155,6 +170,7 @@ struct DebuggerItem { std::string clock; std::string dbgconf; std::string startPname; + std::vector telnet; CustomItem custom; }; @@ -634,14 +650,38 @@ struct CbuildSetItem { std::string compiler; }; +/** + * @brief gdbserver defaults item containing + * gdbserver port + * active flag +*/ +struct GdbServerDefaults { + std::string port; + bool active = false; +}; + +/** + * @brief telnet defaults item containing + * telnet port + * telnet mode + * active flag +*/ +struct TelnetDefaults { + std::string port; + std::string mode; + bool active = false; +}; + /** * @brief debug-adapter defaults item containing - * port number of processor + * gdbserver defaults + * telnet defaults * debug protocol(jtag or swd) * debug clock speed */ struct DebugAdapterDefaultsItem { - std::string port; + GdbServerDefaults gdbserver; + TelnetDefaults telnet; std::string protocol; std::string clock; CustomItem custom; @@ -659,7 +699,6 @@ struct DebugAdapterItem { std::string name; std::vector alias; std::string templateFile; - bool gdbserver = false; DebugAdapterDefaultsItem defaults; }; diff --git a/tools/projmgr/include/ProjMgrRunDebug.h b/tools/projmgr/include/ProjMgrRunDebug.h index 5d904a69c..e4bf6c1db 100644 --- a/tools/projmgr/include/ProjMgrRunDebug.h +++ b/tools/projmgr/include/ProjMgrRunDebug.h @@ -225,6 +225,8 @@ class ProjMgrRunDebug { const std::map& pnames); void CollectDebugTopology(const ContextItem& context, std::vector>> debugs, const std::map& pnames); + void CollectTelnetOptions(const ContextItem& context, DebugAdapterItem& adapter, + const std::map& pnames); CustomItem& CustomMapFind(std::vector>& customMap, const std::string& key); void MergeCustomItems(const CustomItem& src, CustomItem& dst); }; diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 583ffea47..27c52b495 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -283,6 +283,14 @@ struct GdbServerItem { std::string pname; }; +/** + * @brief telnet port item extends TelnetItem containing + resolved port number +*/ +struct TelnetOptionsItem : TelnetItem { + unsigned long long ullPort; +}; + /** * @brief example environment item containing * project file with extension @@ -355,6 +363,7 @@ struct TemplateItem { * debug configuration file * start pname * list of gdbserver items + * list of telnet options items * custom options */ struct DebuggerType { @@ -365,6 +374,7 @@ struct DebuggerType { std::string dbgconf; std::string startPname; std::vector gdbserver; + std::map telnet; CustomItem custom; }; diff --git a/tools/projmgr/include/ProjMgrYamlParser.h b/tools/projmgr/include/ProjMgrYamlParser.h index e19d62207..da0e53834 100644 --- a/tools/projmgr/include/ProjMgrYamlParser.h +++ b/tools/projmgr/include/ProjMgrYamlParser.h @@ -15,6 +15,7 @@ */ static constexpr const char* YAML_ACCESS = "access"; static constexpr const char* YAML_ACCESSPORTS = "accessports"; +static constexpr const char* YAML_ACTIVE = "active"; static constexpr const char* YAML_ALGORITHM = "algorithm"; static constexpr const char* YAML_ALIAS = "alias"; static constexpr const char* YAML_ALIAS_NAME = "alias-name"; @@ -164,6 +165,7 @@ static constexpr const char* YAML_MISC_LIBRARY = "Library"; static constexpr const char* YAML_MISC_LINK = "Link"; static constexpr const char* YAML_MISC_LINK_C = "Link-C"; static constexpr const char* YAML_MISC_LINK_CPP = "Link-CPP"; +static constexpr const char* YAML_MODE = "mode"; static constexpr const char* YAML_MVE = "mve"; static constexpr const char* YAML_NAME = "name"; static constexpr const char* YAML_NOTFORCONTEXT = "not-for-context"; @@ -234,6 +236,7 @@ static constexpr const char* YAML_TARGET_SET = "target-set"; static constexpr const char* YAML_TARGETTYPE = "target-type"; static constexpr const char* YAML_TARGETTYPES = "target-types"; static constexpr const char* YAML_TEMPLATE = "template"; +static constexpr const char* YAML_TELNET = "telnet"; static constexpr const char* YAML_TIMEOUT = "timeout"; static constexpr const char* YAML_TRUSTZONE = "trustzone"; static constexpr const char* YAML_TITLE = "title"; @@ -359,6 +362,7 @@ class ProjMgrYamlParser { bool ParseLinker(const YAML::Node& parent, const std::string& file, std::vector& linker); void ParseRte(const YAML::Node& parent, std::string& rteBaseDir); void ParseDebugDefaults(const YAML::Node& parent, const std::string& file, DebugAdapterDefaultsItem& defaults); + void ParseTelnet(const YAML::Node& parent, const std::string& file, std::vector& telnet); void ParseCustom(const YAML::Node& parent, const std::vector& skip, CustomItem& custom); bool GetTypes(const std::string& type, std::string& buildType, std::string& targetType, std::string& pattern); bool ValidateCdefault(const std::string& input, const YAML::Node& root); diff --git a/tools/projmgr/schemas/common.schema.json b/tools/projmgr/schemas/common.schema.json index 6ded1132c..eb1a2d71b 100644 --- a/tools/projmgr/schemas/common.schema.json +++ b/tools/projmgr/schemas/common.schema.json @@ -2217,11 +2217,30 @@ "clock": { "type": "number", "description": "Selected debug clock speed (in Hz)." }, "dbgconf": { "type": "string", "description": "Debugger configuration file (pinout, trace)." }, "start-pname": { "type": "string", "description": "Debugger connects at start to this processor." }, - "gdbserver": { "$ref": "#/definitions/GdbServersType" } + "gdbserver": { "$ref": "#/definitions/GdbServersType" }, + "telnet": { "$ref": "#/definitions/TelnetOptionsType" } }, "additionalProperties": true, "required": ["name"] }, + "TelnetOptionsType": { + "title": "telnet:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-Input-Format/#telnet-for-pyocd", + "description": "Telnet port for connecting remote tools.", + "type": "array", + "uniqueItems": true, + "items": { "$ref": "#/definitions/TelnetOptionType" } + }, + "TelnetOptionType": { + "type": "object", + "properties": { + "mode": { "enum": [ "off", "server", "file", "console", "monitor" ], "description": "Redirect output mode." }, + "pname": { "type": "string", "description": "Processor name of the processor (only required for multi-core systems)." }, + "port": { "type": "number", "description": "Set TCP/IP port number of Telnet Server." }, + "file": { "type": "string", "description": "Base path and name of the telnet output file (without extension)."} + }, + "additionalProperties": false, + "required": ["mode"] + }, "GdbServersType": { "title": "gdbserver:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-CBuild-Format/#gdbserver", "description": "Information for GDB server option of debugger.", @@ -2431,7 +2450,8 @@ "protocol": { "enum": [ "jtag", "swd" ], "description": "Selected debug protocol (jtag or swd)." }, "clock": { "type": "number", "description": "Selected debug clock speed (in Hz)." }, "dbgconf": { "type": "string", "description": "Debugger configuration file (pinout, trace)." }, - "start-pname": { "type": "string", "description": "Debugger connects at start to this processor." } + "start-pname": { "type": "string", "description": "Debugger connects at start to this processor." }, + "telnet": { "$ref": "#/definitions/TelnetOptionsType" } }, "additionalProperties": true, "required": ["name"] diff --git a/tools/projmgr/src/ProjMgrCbuildRun.cpp b/tools/projmgr/src/ProjMgrCbuildRun.cpp index 22f4e594a..6bef076e7 100644 --- a/tools/projmgr/src/ProjMgrCbuildRun.cpp +++ b/tools/projmgr/src/ProjMgrCbuildRun.cpp @@ -32,6 +32,7 @@ class ProjMgrCbuildRun : public ProjMgrCbuildBase { void SetAccessPortsNode(YAML::Node node, const std::vector& accessPorts); void SetDatapatchNode(YAML::Node node, const std::vector& datapatch); void SetGdbServerNode(YAML::Node node, const std::vector& gdbserver); + void SetTelnetNode(YAML::Node node, const std::map& telnet); void SetCustomNodes(YAML::Node node, const CustomItem& debugger); YAML::Node GetCustomNode(const CustomItem& value); }; @@ -112,6 +113,7 @@ void ProjMgrCbuildRun::SetDebuggerNode(YAML::Node node, const DebuggerType& debu } SetNodeValue(node[YAML_START_PNAME], debugger.startPname); SetGdbServerNode(node[YAML_GDBSERVER], debugger.gdbserver); + SetTelnetNode(node[YAML_TELNET], debugger.telnet); SetCustomNodes(node, debugger.custom); } } @@ -149,6 +151,19 @@ void ProjMgrCbuildRun::SetGdbServerNode(YAML::Node node, const std::vector& telnet) { + for (const auto& [pname, item] : telnet) { + YAML::Node telnetNode; + SetNodeValue(telnetNode[YAML_MODE], item.mode); + SetNodeValue(telnetNode[YAML_PNAME], pname); + telnetNode[YAML_PORT] = item.ullPort; + if (!item.file.empty()) { + SetNodeValue(telnetNode[YAML_FILE], FormatPath(item.file, m_directory)); + } + node.push_back(telnetNode); + } +} + void ProjMgrCbuildRun::SetDebugVarsNode(YAML::Node node, const DebugVarsType& debugVars) { if (!debugVars.vars.empty()) { SetNodeValue(node[YAML_VARS], "|\n" + debugVars.vars); diff --git a/tools/projmgr/src/ProjMgrRunDebug.cpp b/tools/projmgr/src/ProjMgrRunDebug.cpp index feae88781..e00b2615d 100644 --- a/tools/projmgr/src/ProjMgrRunDebug.cpp +++ b/tools/projmgr/src/ProjMgrRunDebug.cpp @@ -322,12 +322,12 @@ void ProjMgrRunDebug::CollectDebuggerSettings(const ContextItem& context, const } // add info from debug-adapters + DebugAdapterItem adapter; if (!adapters.empty()) { - DebugAdapterItem adapter; if (GetDebugAdapter(m_runDebug.debugger.name, adapters, adapter)) { m_runDebug.debugger.name = adapter.name; - if (adapter.gdbserver) { - unsigned long long port = adapter.defaults.port.empty() ? 0 : RteUtils::StringToULL(adapter.defaults.port); + if (adapter.defaults.gdbserver.active) { + unsigned long long port = adapter.defaults.gdbserver.port.empty() ? 0 : RteUtils::StringToULL(adapter.defaults.gdbserver.port); // add primary processor port first m_runDebug.debugger.gdbserver.push_back({ port, m_runDebug.debugger.startPname }); for (const auto& [pname, _] : pnames) { @@ -348,8 +348,77 @@ void ProjMgrRunDebug::CollectDebuggerSettings(const ContextItem& context, const } } + // collect telnet options + CollectTelnetOptions(context, adapter, pnames); + // merge custom options MergeCustomItems(context.debugger.custom, m_runDebug.debugger.custom); + +} + +void ProjMgrRunDebug::CollectTelnetOptions(const ContextItem& context, DebugAdapterItem& adapter, + const std::map& pnames) { + if (!context.debugger.telnet.empty() || adapter.defaults.telnet.active) { + set usedPorts; + const string fileBase = context.directories.cprj + "/" + context.directories.outBaseDir + "/" + + m_runDebug.solutionName + "+" + m_runDebug.targetType; + + // get values from user definitions + for (const auto& [pname, value] : context.debugger.telnet) { + if (pnames.size() > 1 && value.pname.empty()) { + ProjMgrLogger::Get().Warn("'telnet:' pname is required (multicore device)"); + continue; + } + if (pnames.find(pname) == pnames.end()) { + ProjMgrLogger::Get().Warn("pname '" + pname + "' does not match any device pname"); + continue; + } + m_runDebug.debugger.telnet[pname] = { value }; + if (!value.port.empty()) { + m_runDebug.debugger.telnet[pname].ullPort = RteUtils::StringToULL(value.port); + usedPorts.insert(m_runDebug.debugger.telnet[pname].ullPort); + } + if (value.mode.empty()) { + m_runDebug.debugger.telnet[pname].mode = adapter.defaults.telnet.mode.empty() ? "monitor" : adapter.defaults.telnet.mode; + } + if (value.mode == "file" && value.file.empty()) { + m_runDebug.debugger.telnet[pname].file = fileBase + (pname.empty() ? "" : '.' + pname); + } + } + // active flag: enable telnet options for all cores + if (adapter.defaults.telnet.active) { + for (const auto& [pname, _] : pnames) { + auto& telnet = m_runDebug.debugger.telnet[pname]; + if (telnet.mode.empty() || telnet.mode == "off") { + telnet.mode = adapter.defaults.telnet.mode.empty() ? "monitor" : adapter.defaults.telnet.mode; + } + } + } + // port number handling + unsigned long long port = adapter.defaults.telnet.port.empty() ? 0 : RteUtils::StringToULL(adapter.defaults.telnet.port); + if (m_runDebug.debugger.telnet.find(m_runDebug.debugger.startPname) != m_runDebug.debugger.telnet.end()) { + // add primary processor port first + auto& startPort = m_runDebug.debugger.telnet[m_runDebug.debugger.startPname].ullPort; + if (startPort == 0) { + startPort = port; + } else { + port = startPort; + } + usedPorts.insert(port); + } + for (auto& [pname, telnet] : m_runDebug.debugger.telnet) { + // add ports for other processors + if (pname != m_runDebug.debugger.startPname) { + // get customized port if set + port = telnet.port.empty() ? port : telnet.ullPort; + while (usedPorts.find(port) != usedPorts.end()) { + // skip port number if it has already been used + port++; + } + telnet.ullPort = port; + } + } + } } void ProjMgrRunDebug::CollectDebugTopology(const ContextItem& context, const vector>> debugs, diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index d196da91e..2239f4999 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -2646,6 +2646,14 @@ bool ProjMgrWorker::ProcessDebuggers(ContextItem& context) { } } context.debugger.startPname = m_activeTargetSet.debugger.startPname; + for (auto telnet : m_activeTargetSet.debugger.telnet) { + if (!telnet.file.empty()) { + if (!ProcessSequenceRelative(context, telnet.file, context.csolution->directory)) { + return false; + } + } + context.debugger.telnet[telnet.pname] = { telnet }; + } context.debugger.custom = m_activeTargetSet.debugger.custom; } for (const auto& [filename, fi] : context.rteActiveProject->GetFileInstances()) { diff --git a/tools/projmgr/src/ProjMgrYamlParser.cpp b/tools/projmgr/src/ProjMgrYamlParser.cpp index 753c7daa6..634cb7860 100644 --- a/tools/projmgr/src/ProjMgrYamlParser.cpp +++ b/tools/projmgr/src/ProjMgrYamlParser.cpp @@ -316,7 +316,6 @@ bool ProjMgrYamlParser::ParseDebugAdapters(const string& input, DebugAdaptersIte ParseString(adaptersEntry, YAML_NAME, adapter.name); ParseVector(adaptersEntry, YAML_ALIAS_NAME, adapter.alias); ParseString(adaptersEntry, YAML_TEMPLATE, adapter.templateFile); - adapter.gdbserver = adaptersEntry[YAML_GDBSERVER].IsDefined(); ParseDebugDefaults(adaptersEntry, debugAdaptersPath, adapter.defaults); adapters.push_back(adapter); } @@ -602,6 +601,20 @@ void ProjMgrYamlParser::ParseExecutes(const YAML::Node& parent, const string& fi } } +void ProjMgrYamlParser::ParseTelnet(const YAML::Node& parent, const std::string& file, std::vector& telnet) { + if (parent[YAML_TELNET].IsDefined()) { + const YAML::Node& telnetNode = parent[YAML_TELNET]; + for (const auto& telnetEntry : telnetNode) { + TelnetItem telnetItem; + ParseString(telnetEntry, YAML_MODE, telnetItem.mode); + ParseString(telnetEntry, YAML_PORT, telnetItem.port); + ParseString(telnetEntry, YAML_FILE, telnetItem.file); + ParseString(telnetEntry, YAML_PNAME, telnetItem.pname); + telnet.push_back(telnetItem); + } + } +} + void ProjMgrYamlParser::ParseDebugger(const YAML::Node& parent, const string& file, DebuggerItem& debugger) { if (parent[YAML_DEBUGGER].IsDefined()) { const YAML::Node& debuggerNode = parent[YAML_DEBUGGER]; @@ -610,7 +623,8 @@ void ProjMgrYamlParser::ParseDebugger(const YAML::Node& parent, const string& fi ParseNumber(debuggerNode, file, YAML_CLOCK, debugger.clock); ParsePortablePath(debuggerNode, file, YAML_DBGCONF, debugger.dbgconf); ParseString(debuggerNode, YAML_START_PNAME, debugger.startPname); - ParseCustom(debuggerNode, { YAML_NAME, YAML_PROTOCOL, YAML_CLOCK, YAML_DBGCONF, YAML_START_PNAME }, debugger.custom); + ParseTelnet(debuggerNode, file, debugger.telnet); + ParseCustom(debuggerNode, { YAML_NAME, YAML_PROTOCOL, YAML_CLOCK, YAML_DBGCONF, YAML_START_PNAME, YAML_TELNET }, debugger.custom); } } @@ -624,10 +638,20 @@ void ProjMgrYamlParser::ParseRte(const YAML::Node& parent, string& rteBaseDir) { void ProjMgrYamlParser::ParseDebugDefaults(const YAML::Node& parent, const string& file, DebugAdapterDefaultsItem& defaults) { if (parent[YAML_DEFAULTS].IsDefined()) { const YAML::Node& defaultsNode = parent[YAML_DEFAULTS]; - ParseNumber(defaultsNode, file, YAML_PORT, defaults.port); + if (defaultsNode[YAML_GDBSERVER].IsDefined()) { + const YAML::Node& gdbserverNode = defaultsNode[YAML_GDBSERVER]; + ParseString(gdbserverNode, YAML_PORT, defaults.gdbserver.port); + defaults.gdbserver.active = gdbserverNode[YAML_ACTIVE].IsDefined(); + } + if (defaultsNode[YAML_TELNET].IsDefined()) { + const YAML::Node& telnetNode = defaultsNode[YAML_TELNET]; + ParseString(telnetNode, YAML_PORT, defaults.telnet.port); + ParseString(telnetNode, YAML_MODE, defaults.telnet.mode); + defaults.telnet.active = telnetNode[YAML_ACTIVE].IsDefined(); + } ParseString(defaultsNode, YAML_PROTOCOL, defaults.protocol); ParseNumber(defaultsNode, file, YAML_CLOCK, defaults.clock); - ParseCustom(defaultsNode, { YAML_PORT, YAML_PROTOCOL, YAML_CLOCK }, defaults.custom); + ParseCustom(defaultsNode, { YAML_GDBSERVER, YAML_TELNET, YAML_PROTOCOL, YAML_CLOCK }, defaults.custom); } } diff --git a/tools/projmgr/test/data/TestRunDebug/telnet.cproject.yml b/tools/projmgr/test/data/TestRunDebug/telnet.cproject.yml new file mode 100644 index 000000000..6a56960a3 --- /dev/null +++ b/tools/projmgr/test/data/TestRunDebug/telnet.cproject.yml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + + components: + - component: Startup + - component: CORE + diff --git a/tools/projmgr/test/data/TestRunDebug/telnet.csolution.yml b/tools/projmgr/test/data/TestRunDebug/telnet.csolution.yml new file mode 100644 index 000000000..e142db8a2 --- /dev/null +++ b/tools/projmgr/test/data/TestRunDebug/telnet.csolution.yml @@ -0,0 +1,77 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json + +solution: + + compiler: AC6 + + target-types: + - type: SingleCore + device: RteTest_ARMCM0 + target-set: + - set: + debugger: + name: CMSIS-DAP + telnet: + - mode: file + images: + - project-context: telnet + + - type: DualCore + device: RteTest_ARMCM0_Dual + target-set: + - set: + images: + - project-context: core0 + - project-context: core1 + debugger: + name: CMSIS-DAP + start-pname: cm0_core1 + telnet: + - mode: console + pname: cm0_core1 + - mode: server + pname: cm0_core0 + + - set: TelnetFile + images: + - project-context: core0 + - project-context: core1 + debugger: + name: CMSIS-DAP + start-pname: cm0_core1 + telnet: + - mode: file + pname: cm0_core1 + port: 5555 + - mode: monitor + pname: cm0_core0 + + - set: JLinkNoTelnet + images: + - project-context: core0 + - project-context: core1 + debugger: + name: J-Link Server + start-pname: cm0_core1 + + - set: Warnings + images: + - project-context: core0 + - project-context: core1 + debugger: + name: CMSIS-DAP + start-pname: cm0_core1 + telnet: + - mode: monitor + - mode: monitor + pname: unknown + projects: + - project: telnet.cproject.yml + for-context: +SingleCore + - project: core0.cproject.yml + for-context: +DualCore + - project: core1.cproject.yml + for-context: +DualCore + + packs: + - pack: ARM::RteTest_DFP diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index e2db7032b..69f51c5f4 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -6841,6 +6841,81 @@ TEST_F(ProjMgrUnitTests, TestRunDebugMulticore) { testinput_folder + "/TestRunDebug/ref/run-debug+TestHW3.cbuild-run.yml"); } +TEST_F(ProjMgrUnitTests, TestRunDebugTelnet) { + char* argv[7]; + const string& csolution = testinput_folder + "/TestRunDebug/telnet.csolution.yml"; + argv[1] = (char*)"convert"; + argv[2] = (char*)csolution.c_str(); + argv[3] = (char*)"-o"; + argv[4] = (char*)testoutput_folder.c_str(); + argv[5] = (char*)"--active"; + + // single core without port, with file mode + argv[6] = (char*)"SingleCore"; + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + stringstream sstream0; + const YAML::Node& cbuildrun0 = YAML::LoadFile(testoutput_folder + "/out/telnet+SingleCore.cbuild-run.yml"); + sstream0 << cbuildrun0["cbuild-run"]["debugger"]["telnet"]; + EXPECT_EQ( +R"(- mode: file + port: 4444 + file: telnet+SingleCore)", sstream0.str()); + + // dual core without ports + argv[6] = (char*)"DualCore"; + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + const YAML::Node& cbuildrun1 = YAML::LoadFile(testoutput_folder + "/out/telnet+DualCore.cbuild-run.yml"); + stringstream sstream1; + sstream1 << cbuildrun1["cbuild-run"]["debugger"]["telnet"]; + EXPECT_EQ( +R"(- mode: server + pname: cm0_core0 + port: 4445 +- mode: console + pname: cm0_core1 + port: 4444)", sstream1.str()); + + // dual core with start port and file mode + argv[6] = (char*)"DualCore@TelnetFile"; + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + const YAML::Node& cbuildrun2 = YAML::LoadFile(testoutput_folder + "/out/telnet+DualCore.cbuild-run.yml"); + stringstream sstream2; + sstream2 << cbuildrun2["cbuild-run"]["debugger"]["telnet"]; + EXPECT_EQ( +R"(- mode: monitor + pname: cm0_core0 + port: 5556 +- mode: file + pname: cm0_core1 + port: 5555 + file: telnet+DualCore.cm0_core1)", sstream2.str()); + + // dual core with jlink and no telnet + argv[6] = (char*)"DualCore@JLinkNoTelnet"; + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + const YAML::Node& cbuildrun3 = YAML::LoadFile(testoutput_folder + "/out/telnet+DualCore.cbuild-run.yml"); + stringstream sstream3; + sstream3 << cbuildrun3["cbuild-run"]["debugger"]["telnet"]; + EXPECT_EQ( +R"(- mode: monitor + pname: cm0_core0 + port: 4445 +- mode: monitor + pname: cm0_core1 + port: 4444)", sstream3.str()); + + // warnings + StdStreamRedirect streamRedirect; + argv[6] = (char*)"DualCore@Warnings"; + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + string expected = "\ +warning csolution: \\'telnet:\\' pname is required \\(multicore device\\)\n\ +warning csolution: pname \\'unknown\\' does not match any device pname\n\ +"; + string errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(regex_search(errStr, regex(expected))); +} + TEST_F(ProjMgrUnitTests, Test_Check_Define_Value_With_Quotes) { StdStreamRedirect streamRedirect; char* argv[6];