diff --git a/src/DebugServer/Gdb/GdbRspDebugServer.cpp b/src/DebugServer/Gdb/GdbRspDebugServer.cpp index a97131d1..b7419000 100644 --- a/src/DebugServer/Gdb/GdbRspDebugServer.cpp +++ b/src/DebugServer/Gdb/GdbRspDebugServer.cpp @@ -157,23 +157,15 @@ namespace Bloom::DebugServer::Gdb * service it. */ if (!this->targetControllerConsole.isTargetControllerInService()) { - // The TargetController is suspended - allow it some time to wake up + // The TargetController is suspended - attempt to wake it up + try { + this->targetControllerConsole.resumeTargetController(); - /* - * At first, it may seem like there is a possibility that we may miss the - * TargetControllerStateChanged event here. But this is nothing to worry about because - * this->eventListener is already listening for TargetControllerStateChanged events, so if an event - * does fire in between the call to isTargetControllerInService() (above) and waitForEvent() (below), - * then waitForEvent() will return immediately with the event. - */ - const auto targetControllerStateChangedEvent = this->eventListener.waitForEvent< - Events::TargetControllerStateChanged - >(std::chrono::milliseconds(10000)); + } catch (Bloom::Exceptions::Exception& exception) { + Logger::error("Failed to wake up TargetController - " + exception.getMessage()); + } - if ( - !targetControllerStateChangedEvent.has_value() - || targetControllerStateChangedEvent->get()->state != TargetControllerState::ACTIVE - ) { + if (!this->targetControllerConsole.isTargetControllerInService()) { this->activeDebugSession.reset(); throw DebugSessionAborted("TargetController not in service"); } diff --git a/src/TargetController/Commands/CommandTypes.hpp b/src/TargetController/Commands/CommandTypes.hpp index 188fde87..0d35aefb 100644 --- a/src/TargetController/Commands/CommandTypes.hpp +++ b/src/TargetController/Commands/CommandTypes.hpp @@ -8,6 +8,8 @@ namespace Bloom::TargetController::Commands { GENERIC, GET_STATE, + RESUME, + SUSPEND, GET_TARGET_DESCRIPTOR, STOP_TARGET_EXECUTION, RESUME_TARGET_EXECUTION, diff --git a/src/TargetController/Commands/Resume.hpp b/src/TargetController/Commands/Resume.hpp new file mode 100644 index 00000000..47e6e0e1 --- /dev/null +++ b/src/TargetController/Commands/Resume.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "Command.hpp" + +namespace Bloom::TargetController::Commands +{ + class Resume: public Command + { + public: + static constexpr CommandType type = CommandType::RESUME; + static inline const std::string name = "Resume"; + + [[nodiscard]] CommandType getType() const override { + return Resume::type; + } + + [[nodiscard]] bool requiresDebugMode() const override { + return false; + } + }; +} diff --git a/src/TargetController/Commands/Suspend.hpp b/src/TargetController/Commands/Suspend.hpp new file mode 100644 index 00000000..39371adc --- /dev/null +++ b/src/TargetController/Commands/Suspend.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "Command.hpp" + +namespace Bloom::TargetController::Commands +{ + class Suspend: public Command + { + public: + static constexpr CommandType type = CommandType::SUSPEND; + static inline const std::string name = "Suspend"; + + [[nodiscard]] CommandType getType() const override { + return Suspend::type; + } + + [[nodiscard]] bool requiresDebugMode() const override { + return false; + } + }; +} diff --git a/src/TargetController/TargetControllerComponent.cpp b/src/TargetController/TargetControllerComponent.cpp index 67417b54..26ffc833 100644 --- a/src/TargetController/TargetControllerComponent.cpp +++ b/src/TargetController/TargetControllerComponent.cpp @@ -24,6 +24,8 @@ namespace Bloom::TargetController using Commands::Command; using Commands::GetState; + using Commands::Resume; + using Commands::Suspend; using Commands::GetTargetDescriptor; using Commands::GetTargetState; using Commands::StopTargetExecution; @@ -172,6 +174,14 @@ namespace Bloom::TargetController std::bind(&TargetControllerComponent::handleGetState, this, std::placeholders::_1) ); + this->registerCommandHandler( + std::bind(&TargetControllerComponent::handleResume, this, std::placeholders::_1) + ); + + this->registerCommandHandler( + std::bind(&TargetControllerComponent::handleSuspend, this, std::placeholders::_1) + ); + this->registerCommandHandler( std::bind(&TargetControllerComponent::handleGetTargetDescriptor, this, std::placeholders::_1) ); @@ -765,6 +775,22 @@ namespace Bloom::TargetController return std::make_unique(this->state); } + std::unique_ptr TargetControllerComponent::handleResume(Resume& command) { + if (this->state != TargetControllerState::ACTIVE) { + this->resume(); + } + + return std::make_unique(); + } + + std::unique_ptr TargetControllerComponent::handleSuspend(Suspend& command) { + if (this->state != TargetControllerState::SUSPENDED) { + this->suspend(); + } + + return std::make_unique(); + } + std::unique_ptr TargetControllerComponent::handleGetTargetDescriptor( GetTargetDescriptor& command ) { diff --git a/src/TargetController/TargetControllerComponent.hpp b/src/TargetController/TargetControllerComponent.hpp index 0dfc72e6..881040f9 100644 --- a/src/TargetController/TargetControllerComponent.hpp +++ b/src/TargetController/TargetControllerComponent.hpp @@ -21,6 +21,8 @@ // Commands #include "Commands/Command.hpp" #include "Commands/GetState.hpp" +#include "Commands/Resume.hpp" +#include "Commands/Suspend.hpp" #include "Commands/GetTargetDescriptor.hpp" #include "Commands/GetTargetState.hpp" #include "Commands/StopTargetExecution.hpp" @@ -335,6 +337,8 @@ namespace Bloom::TargetController // Command handlers std::unique_ptr handleGetState(Commands::GetState& command); + std::unique_ptr handleSuspend(Commands::Suspend& command); + std::unique_ptr handleResume(Commands::Resume& command); std::unique_ptr handleGetTargetDescriptor(Commands::GetTargetDescriptor& command); std::unique_ptr handleGetTargetState(Commands::GetTargetState& command); std::unique_ptr handleStopTargetExecution(Commands::StopTargetExecution& command); diff --git a/src/TargetController/TargetControllerConsole.cpp b/src/TargetController/TargetControllerConsole.cpp index 34caf446..23563028 100644 --- a/src/TargetController/TargetControllerConsole.cpp +++ b/src/TargetController/TargetControllerConsole.cpp @@ -2,6 +2,8 @@ // Commands #include "Commands/GetState.hpp" +#include "Commands/Suspend.hpp" +#include "Commands/Resume.hpp" #include "Commands/GetTargetDescriptor.hpp" #include "Commands/GetTargetState.hpp" #include "Commands/StopTargetExecution.hpp" @@ -25,6 +27,8 @@ namespace Bloom::TargetController { using Commands::GetState; + using Commands::Suspend; + using Commands::Resume; using Commands::GetTargetDescriptor; using Commands::GetTargetState; using Commands::StopTargetExecution; @@ -81,6 +85,22 @@ namespace Bloom::TargetController } } + void TargetControllerConsole::resumeTargetController() { + this->commandManager.sendCommandAndWaitForResponse( + std::make_unique(), + this->defaultTimeout + ); + return; + } + + void TargetControllerConsole::suspendTargetController() { + this->commandManager.sendCommandAndWaitForResponse( + std::make_unique(), + this->defaultTimeout + ); + return; + } + TargetDescriptor TargetControllerConsole::getTargetDescriptor() { return this->commandManager.sendCommandAndWaitForResponse( std::make_unique(), diff --git a/src/TargetController/TargetControllerConsole.hpp b/src/TargetController/TargetControllerConsole.hpp index dbb24eba..ebd8767c 100644 --- a/src/TargetController/TargetControllerConsole.hpp +++ b/src/TargetController/TargetControllerConsole.hpp @@ -49,6 +49,16 @@ namespace Bloom::TargetController */ bool isTargetControllerInService() noexcept; + /** + * Resumes the TargetController if it's suspended. Otherwise, this function does nothing. + */ + void resumeTargetController(); + + /** + * Suspends the TargetController if it's active. Otherwise, this function does nothing. + */ + void suspendTargetController(); + /** * Requests the TargetDescriptor from the TargetController *