diff --git a/src/DebugServer/Gdb/CommandPackets/HelpMonitorInfo.cpp b/src/DebugServer/Gdb/CommandPackets/HelpMonitorInfo.cpp index 886ea37e..999e0580 100644 --- a/src/DebugServer/Gdb/CommandPackets/HelpMonitorInfo.cpp +++ b/src/DebugServer/Gdb/CommandPackets/HelpMonitorInfo.cpp @@ -24,7 +24,7 @@ namespace DebugServer::Gdb::CommandPackets DebugSession& debugSession, const TargetDescriptor& gdbTargetDescriptor, const Targets::TargetDescriptor& targetDescriptor, - TargetControllerService& + TargetControllerService& targetControllerService ) { Logger::info("Handling HelpMonitorInfo packet"); @@ -132,6 +132,12 @@ namespace DebugServer::Gdb::CommandPackets output += leftPadding + " To repeat the hexadecimal sequence 'FF00FF00AABBCC' across the entirety of the target's EEPROM memory segment.\n\n"; } + const auto passthroughText = targetControllerService.getTargetPassthroughHelpText(); + if (!passthroughText.empty()) { + output += "--------------------------------------------------------------------------------------------------------------\n\n"; + output += "Target driver passthrough commands:\n\n" + passthroughText; + } + output += "\n"; debugSession.connection.writePacket(ResponsePacket{Services::StringService::toHex(output)}); } diff --git a/src/Services/TargetControllerService.cpp b/src/Services/TargetControllerService.cpp index c029a51d..e666ba9f 100644 --- a/src/Services/TargetControllerService.cpp +++ b/src/Services/TargetControllerService.cpp @@ -25,6 +25,8 @@ #include "src/TargetController/Commands/EnableProgrammingMode.hpp" #include "src/TargetController/Commands/DisableProgrammingMode.hpp" #include "src/TargetController/Commands/Shutdown.hpp" +#include "src/TargetController/Commands/GetTargetPassthroughHelpText.hpp" +#include "src/TargetController/Commands/InvokeTargetPassthroughCommand.hpp" #include "src/Exceptions/Exception.hpp" @@ -54,6 +56,7 @@ namespace Services using TargetController::Commands::EnableProgrammingMode; using TargetController::Commands::DisableProgrammingMode; using TargetController::Commands::Shutdown; + using TargetController::Commands::GetTargetPassthroughHelpText; using TargetController::Commands::InvokeTargetPassthroughCommand; using Targets::TargetDescriptor; @@ -346,6 +349,14 @@ namespace Services ); } + std::string TargetControllerService::getTargetPassthroughHelpText() const { + return this->commandManager.sendCommandAndWaitForResponse( + std::make_unique(), + this->defaultTimeout, + this->activeAtomicSessionId + )->text; + } + std::optional TargetControllerService::invokeTargetPassthroughCommand( Targets::PassthroughCommand&& command ) const { diff --git a/src/Services/TargetControllerService.hpp b/src/Services/TargetControllerService.hpp index 58348650..0b437d38 100644 --- a/src/Services/TargetControllerService.hpp +++ b/src/Services/TargetControllerService.hpp @@ -268,6 +268,8 @@ namespace Services */ void shutdown() const; + std::string getTargetPassthroughHelpText() const; + std::optional invokeTargetPassthroughCommand( Targets::PassthroughCommand&& command ) const; diff --git a/src/TargetController/Commands/CommandTypes.hpp b/src/TargetController/Commands/CommandTypes.hpp index 344eaee0..78d6a060 100644 --- a/src/TargetController/Commands/CommandTypes.hpp +++ b/src/TargetController/Commands/CommandTypes.hpp @@ -31,6 +31,7 @@ namespace TargetController::Commands GET_TARGET_PROGRAM_COUNTER, ENABLE_PROGRAMMING_MODE, DISABLE_PROGRAMMING_MODE, + GET_TARGET_PASSTHROUGH_HELP_TEXT, INVOKE_TARGET_PASSTHROUGH_COMMAND, }; } diff --git a/src/TargetController/Commands/GetTargetPassthroughHelpText.hpp b/src/TargetController/Commands/GetTargetPassthroughHelpText.hpp new file mode 100644 index 00000000..f77a6705 --- /dev/null +++ b/src/TargetController/Commands/GetTargetPassthroughHelpText.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "Command.hpp" +#include "src/TargetController/Responses/TargetPassthroughHelpText.hpp" + +namespace TargetController::Commands +{ + class GetTargetPassthroughHelpText: public Command + { + public: + using SuccessResponseType = Responses::TargetPassthroughHelpText; + static constexpr CommandType type = CommandType::GET_TARGET_PASSTHROUGH_HELP_TEXT; + static const inline std::string name = "GetTargetPassthroughHelpText"; + + [[nodiscard]] CommandType getType() const override { + return GetTargetPassthroughHelpText::type; + } + }; +} diff --git a/src/TargetController/Responses/ResponseTypes.hpp b/src/TargetController/Responses/ResponseTypes.hpp index 6a13957b..76277196 100644 --- a/src/TargetController/Responses/ResponseTypes.hpp +++ b/src/TargetController/Responses/ResponseTypes.hpp @@ -17,6 +17,7 @@ namespace TargetController::Responses TARGET_STACK_POINTER, TARGET_PROGRAM_COUNTER, PROGRAM_BREAKPOINT, + TARGET_PASSTHROUGH_HELP_TEXT, TARGET_PASSTHROUGH_RESPONSE, }; } diff --git a/src/TargetController/Responses/TargetPassthroughHelpText.hpp b/src/TargetController/Responses/TargetPassthroughHelpText.hpp new file mode 100644 index 00000000..21e6b37f --- /dev/null +++ b/src/TargetController/Responses/TargetPassthroughHelpText.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "Response.hpp" + +namespace TargetController::Responses +{ + class TargetPassthroughHelpText: public Response + { + public: + static constexpr ResponseType type = ResponseType::TARGET_PASSTHROUGH_RESPONSE; + + std::string text; + + explicit TargetPassthroughHelpText(std::string&& text) + : text(std::move(text)) + {} + + [[nodiscard]] ResponseType getType() const override { + return TargetPassthroughHelpText::type; + } + }; +} diff --git a/src/TargetController/TargetControllerComponent.cpp b/src/TargetController/TargetControllerComponent.cpp index da8c5165..7dcf7140 100644 --- a/src/TargetController/TargetControllerComponent.cpp +++ b/src/TargetController/TargetControllerComponent.cpp @@ -51,6 +51,7 @@ namespace TargetController using Commands::GetTargetProgramCounter; using Commands::EnableProgrammingMode; using Commands::DisableProgrammingMode; + using Commands::GetTargetPassthroughHelpText; using Commands::InvokeTargetPassthroughCommand; using Responses::Response; @@ -61,6 +62,7 @@ namespace TargetController using Responses::TargetStackPointer; using Responses::TargetProgramCounter; using Responses::ProgramBreakpoint; + using Responses::TargetPassthroughHelpText; using Responses::TargetPassthroughResponse; TargetControllerComponent::TargetControllerComponent( @@ -264,6 +266,10 @@ namespace TargetController std::bind(&TargetControllerComponent::handleDisableProgrammingMode, this, std::placeholders::_1) ); + this->registerCommandHandler( + std::bind(&TargetControllerComponent::handleTargetPassthroughHelpText, this, std::placeholders::_1) + ); + this->registerCommandHandler( std::bind(&TargetControllerComponent::handleTargetPassthroughCommand, this, std::placeholders::_1) ); @@ -1180,6 +1186,12 @@ namespace TargetController return std::make_unique(); } + std::unique_ptr TargetControllerComponent::handleTargetPassthroughHelpText( + GetTargetPassthroughHelpText& command + ) { + return std::make_unique(this->target->passthroughCommandHelpText()); + } + std::unique_ptr TargetControllerComponent::handleTargetPassthroughCommand( InvokeTargetPassthroughCommand& command ) { diff --git a/src/TargetController/TargetControllerComponent.hpp b/src/TargetController/TargetControllerComponent.hpp index 74e529c8..d99d8eb2 100644 --- a/src/TargetController/TargetControllerComponent.hpp +++ b/src/TargetController/TargetControllerComponent.hpp @@ -45,6 +45,7 @@ #include "Commands/GetTargetProgramCounter.hpp" #include "Commands/EnableProgrammingMode.hpp" #include "Commands/DisableProgrammingMode.hpp" +#include "Commands/GetTargetPassthroughHelpText.hpp" #include "Commands/InvokeTargetPassthroughCommand.hpp" // Responses @@ -58,6 +59,7 @@ #include "Responses/TargetStackPointer.hpp" #include "Responses/TargetProgramCounter.hpp" #include "Responses/ProgramBreakpoint.hpp" +#include "Responses/TargetPassthroughHelpText.hpp" #include "Responses/TargetPassthroughResponse.hpp" #include "src/DebugToolDrivers/DebugTools.hpp" @@ -381,6 +383,9 @@ namespace TargetController ); std::unique_ptr handleEnableProgrammingMode(Commands::EnableProgrammingMode& command); std::unique_ptr handleDisableProgrammingMode(Commands::DisableProgrammingMode& command); + std::unique_ptr handleTargetPassthroughHelpText( + Commands::GetTargetPassthroughHelpText& command + ); std::unique_ptr handleTargetPassthroughCommand( Commands::InvokeTargetPassthroughCommand& command ); diff --git a/src/Targets/Microchip/AVR8/Avr8.cpp b/src/Targets/Microchip/AVR8/Avr8.cpp index 3f8cac68..1156bfca 100644 --- a/src/Targets/Microchip/AVR8/Avr8.cpp +++ b/src/Targets/Microchip/AVR8/Avr8.cpp @@ -691,6 +691,10 @@ namespace Targets::Microchip::Avr8 return this->activeProgrammingSession.has_value(); } + std::string Avr8::passthroughCommandHelpText() { + return {}; + } + std::optional Avr8::invokePassthroughCommand(const PassthroughCommand& command) { // AVR targets do not currently support any passthrough commands return std::nullopt; diff --git a/src/Targets/Microchip/AVR8/Avr8.hpp b/src/Targets/Microchip/AVR8/Avr8.hpp index 5329e60e..8b87e5f1 100644 --- a/src/Targets/Microchip/AVR8/Avr8.hpp +++ b/src/Targets/Microchip/AVR8/Avr8.hpp @@ -108,6 +108,7 @@ namespace Targets::Microchip::Avr8 void disableProgrammingMode() override; bool programmingModeEnabled() override; + std::string passthroughCommandHelpText() override; std::optional invokePassthroughCommand(const PassthroughCommand& command) override; protected: diff --git a/src/Targets/RiscV/Wch/WchRiscV.cpp b/src/Targets/RiscV/Wch/WchRiscV.cpp index 1c7fe14a..fc58f739 100644 --- a/src/Targets/RiscV/Wch/WchRiscV.cpp +++ b/src/Targets/RiscV/Wch/WchRiscV.cpp @@ -351,6 +351,35 @@ namespace Targets::RiscV::Wch return programCounter; } + std::string WchRiscV::passthroughCommandHelpText() { + using Services::StringService; + + static constexpr auto CMD_COLOR = StringService::TerminalColor::DARK_YELLOW; + static constexpr auto PARAM_COLOR = StringService::TerminalColor::BLUE; + + static const auto leftPadding = std::string{std::string::size_type{3}, ' ', std::string::allocator_type{}}; + auto output = std::string{}; + + output += StringService::applyTerminalColor("program_mode", CMD_COLOR) + "\n\n"; + output += leftPadding + "Determines the target's current program mode (boot/user).\n\n"; + + output += StringService::applyTerminalColor("program_mode", CMD_COLOR) + " [" + + StringService::applyTerminalColor("MODE", PARAM_COLOR) + "]\n\n"; + output += leftPadding + "Changes the program mode on the target. Triggers a target reset.\n"; + output += leftPadding + "Valid modes: \"boot\" and \"user\".\n\n"; + output += leftPadding + "Examples:\n\n"; + output += leftPadding + "mon " + StringService::applyTerminalColor("program_mode", CMD_COLOR) + " " + + StringService::applyTerminalColor("boot", PARAM_COLOR) + "\n"; + output += leftPadding + " To switch to boot mode, where the mapped program memory segment aliases the boot" + " segment (key: \"" + this->bootProgramSegmentDescriptor.key + "\").\n\n"; + output += leftPadding + "mon " + StringService::applyTerminalColor("program_mode", CMD_COLOR) + " " + + StringService::applyTerminalColor("user", PARAM_COLOR) + "\n"; + output += leftPadding + " To switch to user mode, where the mapped program memory segment aliases the main" + " program segment (key: \"" + this->mainProgramSegmentDescriptor.key + "\").\n"; + + return output; + } + std::optional WchRiscV::invokePassthroughCommand(const PassthroughCommand& command) { using Services::StringService; @@ -362,7 +391,7 @@ namespace Targets::RiscV::Wch auto response = PassthroughResponse{}; try { - if (arguments[0] == "pm") { + if (arguments[0] == "program_mode") { const auto &actualAliasedSegment = this->resolveAliasedMemorySegment(); if (arguments.size() == 1) { diff --git a/src/Targets/RiscV/Wch/WchRiscV.hpp b/src/Targets/RiscV/Wch/WchRiscV.hpp index 5fa75291..f5f2e80d 100644 --- a/src/Targets/RiscV/Wch/WchRiscV.hpp +++ b/src/Targets/RiscV/Wch/WchRiscV.hpp @@ -43,6 +43,7 @@ namespace Targets::RiscV::Wch TargetMemoryAddress getProgramCounter() override; + std::string passthroughCommandHelpText() override; std::optional invokePassthroughCommand(const PassthroughCommand& command) override; protected: diff --git a/src/Targets/Target.hpp b/src/Targets/Target.hpp index 6c39f0c5..10287868 100644 --- a/src/Targets/Target.hpp +++ b/src/Targets/Target.hpp @@ -155,6 +155,7 @@ namespace Targets virtual void disableProgrammingMode() = 0; virtual bool programmingModeEnabled() = 0; + virtual std::string passthroughCommandHelpText() = 0; virtual std::optional invokePassthroughCommand(const PassthroughCommand& command) = 0; }; }