diff --git a/src/DebugServer/CMakeLists.txt b/src/DebugServer/CMakeLists.txt index d4ed26b6..4ba62c18 100755 --- a/src/DebugServer/CMakeLists.txt +++ b/src/DebugServer/CMakeLists.txt @@ -16,6 +16,7 @@ target_sources( ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/SetBreakpoint.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/RemoveBreakpoint.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/Monitor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/ResetTarget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/ResponsePackets/SupportedFeaturesResponse.cpp # AVR GDB Server diff --git a/src/DebugServer/Gdb/CommandPackets/ResetTarget.cpp b/src/DebugServer/Gdb/CommandPackets/ResetTarget.cpp new file mode 100644 index 00000000..0e72468b --- /dev/null +++ b/src/DebugServer/Gdb/CommandPackets/ResetTarget.cpp @@ -0,0 +1,35 @@ +#include "ResetTarget.hpp" + +#include "src/DebugServer/Gdb/ResponsePackets/ErrorResponsePacket.hpp" +#include "src/DebugServer/Gdb/ResponsePackets/ResponsePacket.hpp" + +#include "src/Logger/Logger.hpp" +#include "src/Exceptions/Exception.hpp" + +namespace Bloom::DebugServer::Gdb::CommandPackets +{ + using ResponsePackets::ErrorResponsePacket; + using ResponsePackets::ResponsePacket; + + using Exceptions::Exception; + + ResetTarget::ResetTarget(Monitor&& monitorPacket) + : Monitor(std::move(monitorPacket)) + {} + + void ResetTarget::handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) { + Logger::debug("Handling ResetTarget packet"); + + try { + targetControllerConsole.resetTarget(); + + debugSession.connection.writePacket(ResponsePacket(Packet::toHex( + "Target reset complete - use the 'continue' command to begin execution.\n" + ))); + + } catch (const Exception& exception) { + Logger::error("Failed to reset target - " + exception.getMessage()); + debugSession.connection.writePacket(ErrorResponsePacket()); + } + } +} diff --git a/src/DebugServer/Gdb/CommandPackets/ResetTarget.hpp b/src/DebugServer/Gdb/CommandPackets/ResetTarget.hpp new file mode 100644 index 00000000..adf217a5 --- /dev/null +++ b/src/DebugServer/Gdb/CommandPackets/ResetTarget.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include "Monitor.hpp" + +namespace Bloom::DebugServer::Gdb::CommandPackets +{ + /** + * The ResetTarget class implements a structure for the custom reset command (triggered via the "monitor reset" + * GDB command + * + * The "monitor reset" command will trigger a target reset and hold the target in a stopped state. + */ + class ResetTarget: public Monitor + { + public: + explicit ResetTarget(Monitor&& monitorPacket); + + void handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) override; + }; +} diff --git a/src/DebugServer/Gdb/GdbRspDebugServer.cpp b/src/DebugServer/Gdb/GdbRspDebugServer.cpp index 4375b4cc..fcac4195 100644 --- a/src/DebugServer/Gdb/GdbRspDebugServer.cpp +++ b/src/DebugServer/Gdb/GdbRspDebugServer.cpp @@ -25,6 +25,7 @@ #include "CommandPackets/SetBreakpoint.hpp" #include "CommandPackets/RemoveBreakpoint.hpp" #include "CommandPackets/Monitor.hpp" +#include "CommandPackets/ResetTarget.hpp" // Response packets #include "ResponsePackets/TargetStopped.hpp" @@ -270,6 +271,11 @@ namespace Bloom::DebugServer::Gdb if (rawPacketString.find("qRcmd") == 1) { // This is a monitor packet auto monitorCommand = std::make_unique(rawPacket); + + if (monitorCommand->command == "reset") { + return std::make_unique(std::move(*(monitorCommand.get()))); + } + return monitorCommand; } } diff --git a/src/DebugServer/Gdb/Packet.hpp b/src/DebugServer/Gdb/Packet.hpp index 389ea030..8f8d50c4 100644 --- a/src/DebugServer/Gdb/Packet.hpp +++ b/src/DebugServer/Gdb/Packet.hpp @@ -101,6 +101,24 @@ namespace Bloom::DebugServer::Gdb return stream.str(); } + /** + * Converts a string to hexadecimal form, the form in which responses are expected to be delivered from the + * server. + * + * @param data + * @return + */ + static std::string toHex(const std::string& data) { + std::stringstream stream; + stream << std::hex << std::setfill('0'); + + for (const auto& byte : data) { + stream << std::setw(2) << static_cast(byte); + } + + return stream.str(); + } + /** * Converts data in hexadecimal form to raw data. *