diff --git a/src/DebugServer/Gdb/CommandPackets/Detach.cpp b/src/DebugServer/Gdb/CommandPackets/Detach.cpp index 043ab965..4c3f7bf7 100644 --- a/src/DebugServer/Gdb/CommandPackets/Detach.cpp +++ b/src/DebugServer/Gdb/CommandPackets/Detach.cpp @@ -25,7 +25,7 @@ namespace Bloom::DebugServer::Gdb::CommandPackets try { if (Services::ProcessService::isManagedByClion()) { - // TODO: Force the TC to shutdown. + targetControllerService.shutdown(); } debugSession.connection.writePacket(OkResponsePacket()); diff --git a/src/Services/TargetControllerService.cpp b/src/Services/TargetControllerService.cpp index 7b9b501c..53ba896e 100644 --- a/src/Services/TargetControllerService.cpp +++ b/src/Services/TargetControllerService.cpp @@ -21,6 +21,7 @@ #include "src/TargetController/Commands/GetTargetProgramCounter.hpp" #include "src/TargetController/Commands/EnableProgrammingMode.hpp" #include "src/TargetController/Commands/DisableProgrammingMode.hpp" +#include "src/TargetController/Commands/Shutdown.hpp" namespace Bloom::Services { @@ -44,6 +45,7 @@ namespace Bloom::Services using TargetController::Commands::GetTargetProgramCounter; using TargetController::Commands::EnableProgrammingMode; using TargetController::Commands::DisableProgrammingMode; + using TargetController::Commands::Shutdown; using Targets::TargetDescriptor; using Targets::TargetState; @@ -239,4 +241,11 @@ namespace Bloom::Services this->defaultTimeout ); } + + void TargetControllerService::shutdown() const { + this->commandManager.sendCommandAndWaitForResponse( + std::make_unique(), + this->defaultTimeout + ); + } } diff --git a/src/Services/TargetControllerService.hpp b/src/Services/TargetControllerService.hpp index 1b114676..99fdbb95 100644 --- a/src/Services/TargetControllerService.hpp +++ b/src/Services/TargetControllerService.hpp @@ -187,6 +187,11 @@ namespace Bloom::Services */ void disableProgrammingMode() const; + /** + * Forces the TargetController to shutdown + */ + void shutdown() const; + private: TargetController::CommandManager commandManager = TargetController::CommandManager(); diff --git a/src/TargetController/Commands/CommandTypes.hpp b/src/TargetController/Commands/CommandTypes.hpp index bcd0a9b6..2d637516 100644 --- a/src/TargetController/Commands/CommandTypes.hpp +++ b/src/TargetController/Commands/CommandTypes.hpp @@ -7,6 +7,7 @@ namespace Bloom::TargetController::Commands enum class CommandType: std::uint8_t { GENERIC, + SHUTDOWN, GET_TARGET_DESCRIPTOR, STOP_TARGET_EXECUTION, RESUME_TARGET_EXECUTION, diff --git a/src/TargetController/Commands/Shutdown.hpp b/src/TargetController/Commands/Shutdown.hpp new file mode 100644 index 00000000..96e1ba48 --- /dev/null +++ b/src/TargetController/Commands/Shutdown.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "Command.hpp" + +namespace Bloom::TargetController::Commands +{ + class Shutdown: public Command + { + public: + static constexpr CommandType type = CommandType::SHUTDOWN; + static const inline std::string name = "Shutdown"; + + [[nodiscard]] CommandType getType() const override { + return Shutdown::type; + } + + [[nodiscard]] bool requiresDebugMode() const override { + return false; + } + }; +} diff --git a/src/TargetController/TargetControllerComponent.cpp b/src/TargetController/TargetControllerComponent.cpp index 8fd2515c..ff504eac 100644 --- a/src/TargetController/TargetControllerComponent.cpp +++ b/src/TargetController/TargetControllerComponent.cpp @@ -20,6 +20,7 @@ namespace Bloom::TargetController using Commands::CommandIdType; using Commands::Command; + using Commands::Shutdown; using Commands::GetTargetDescriptor; using Commands::GetTargetState; using Commands::StopTargetExecution; @@ -139,6 +140,10 @@ namespace Bloom::TargetController EventManager::registerListener(this->eventListener); // Register command handlers + this->registerCommandHandler( + std::bind(&TargetControllerComponent::handleShutdown, this, std::placeholders::_1) + ); + this->registerCommandHandler( std::bind(&TargetControllerComponent::handleGetTargetDescriptor, this, std::placeholders::_1) ); @@ -640,6 +645,11 @@ namespace Bloom::TargetController } } + std::unique_ptr TargetControllerComponent::handleShutdown(Shutdown& command) { + this->shutdown(); + return std::make_unique(); + } + std::unique_ptr TargetControllerComponent::handleGetTargetDescriptor( GetTargetDescriptor& command ) { diff --git a/src/TargetController/TargetControllerComponent.hpp b/src/TargetController/TargetControllerComponent.hpp index d1d1964b..63f96c17 100644 --- a/src/TargetController/TargetControllerComponent.hpp +++ b/src/TargetController/TargetControllerComponent.hpp @@ -20,6 +20,7 @@ // Commands #include "Commands/Command.hpp" +#include "Commands/Shutdown.hpp" #include "Commands/GetTargetDescriptor.hpp" #include "Commands/GetTargetState.hpp" #include "Commands/StopTargetExecution.hpp" @@ -303,6 +304,7 @@ namespace Bloom::TargetController void onDebugSessionFinishedEvent(const Events::DebugSessionFinished& event); // Command handlers + std::unique_ptr handleShutdown(Commands::Shutdown& command); std::unique_ptr handleGetTargetDescriptor(Commands::GetTargetDescriptor& command); std::unique_ptr handleGetTargetState(Commands::GetTargetState& command); std::unique_ptr handleStopTargetExecution(Commands::StopTargetExecution& command);