diff --git a/resources/gdbHelpMonitorInfo.txt b/resources/gdbHelpMonitorInfo.txt index 42083e88..20c327bd 100644 --- a/resources/gdbHelpMonitorInfo.txt +++ b/resources/gdbHelpMonitorInfo.txt @@ -1,7 +1,9 @@ Supported Bloom commands: - help Displays this help text. - version Outputs Bloom's version information. - version machine Outputs Bloom's version information in JSON format. + help Displays this help text. + version Outputs Bloom's version information. + version machine Outputs Bloom's version information in JSON format. - reset Resets the target and holds it in a stopped state. + target-info machine Outputs information on the connected target, in JSON format. + + reset Resets the target and holds it in a stopped state. diff --git a/src/DebugServer/CMakeLists.txt b/src/DebugServer/CMakeLists.txt index ccac480c..664e4310 100755 --- a/src/DebugServer/CMakeLists.txt +++ b/src/DebugServer/CMakeLists.txt @@ -22,6 +22,7 @@ target_sources( ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/HelpMonitorInfo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/BloomVersion.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/BloomVersionMachine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/CommandPackets/TargetInfoMachine.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/ResponsePackets/SupportedFeaturesResponse.cpp # AVR GDB RSP Server diff --git a/src/DebugServer/Gdb/CommandPackets/TargetInfoMachine.cpp b/src/DebugServer/Gdb/CommandPackets/TargetInfoMachine.cpp new file mode 100644 index 00000000..9f28e1a9 --- /dev/null +++ b/src/DebugServer/Gdb/CommandPackets/TargetInfoMachine.cpp @@ -0,0 +1,70 @@ +#include "TargetInfoMachine.hpp" + +#include +#include +#include +#include + +#include "src/DebugServer/Gdb/ResponsePackets/ResponsePacket.hpp" + +#include "src/Application.hpp" +#include "src/Logger/Logger.hpp" +#include "src/Exceptions/Exception.hpp" + +namespace Bloom::DebugServer::Gdb::CommandPackets +{ + using TargetController::TargetControllerConsole; + + using ResponsePackets::ResponsePacket; + + using Exceptions::Exception; + + TargetInfoMachine::TargetInfoMachine(Monitor&& monitorPacket) + : Monitor(std::move(monitorPacket)) + {} + + void TargetInfoMachine::handle(DebugSession& debugSession, TargetControllerConsole&) { + Logger::debug("Handling TargetInfoMachine packet"); + + debugSession.connection.writePacket(ResponsePacket(Packet::toHex( + QJsonDocument( + this->generateTargetInfo(debugSession.gdbTargetDescriptor.targetDescriptor) + ).toJson().toStdString() + ))); + } + + QJsonObject TargetInfoMachine::generateTargetInfo(const Targets::TargetDescriptor& targetDescriptor) const { + using Targets::TargetMemoryType; + + static const auto memoryTypeNamesByType = std::map({ + {TargetMemoryType::FLASH, QString("Flash")}, + {TargetMemoryType::RAM, QString("RAM")}, + {TargetMemoryType::EEPROM, QString("EEPROM")}, + }); + + auto memoryDescriptors = QJsonArray(); + + for (const auto& [memoryType, memoryDescriptor] : targetDescriptor.memoryDescriptorsByType) { + if (!memoryTypeNamesByType.contains(memoryType)) { + continue; + } + + memoryDescriptors.push_back(QJsonObject({ + {"name", memoryTypeNamesByType.at(memoryType)}, + {"size", static_cast(memoryDescriptor.size())}, + {"addressRange", QJsonObject({ + {"startAddress", static_cast(memoryDescriptor.addressRange.startAddress)}, + {"endAddress", static_cast(memoryDescriptor.addressRange.endAddress)}, + })} + })); + } + + return QJsonObject({ + {"target", QJsonObject({ + {"name", QString::fromStdString(targetDescriptor.name)}, + {"id", QString::fromStdString(targetDescriptor.id)}, + {"memoryDescriptors", memoryDescriptors}, + })}, + }); + } +} diff --git a/src/DebugServer/Gdb/CommandPackets/TargetInfoMachine.hpp b/src/DebugServer/Gdb/CommandPackets/TargetInfoMachine.hpp new file mode 100644 index 00000000..04ad2d10 --- /dev/null +++ b/src/DebugServer/Gdb/CommandPackets/TargetInfoMachine.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#include "Monitor.hpp" + +#include "src/Targets/TargetDescriptor.hpp" + +namespace Bloom::DebugServer::Gdb::CommandPackets +{ + /** + * The TargetInfoMachine class implements a structure for the "monitor target-info machine" GDB command. + * + * We just output information on the connected target, in JSON format. + */ + class TargetInfoMachine: public Monitor + { + public: + explicit TargetInfoMachine(Monitor&& monitorPacket); + + void handle( + DebugSession& debugSession, + TargetController::TargetControllerConsole& targetControllerConsole + ) override; + + private: + QJsonObject generateTargetInfo(const Targets::TargetDescriptor& targetDescriptor) const; + }; +} diff --git a/src/DebugServer/Gdb/GdbRspDebugServer.cpp b/src/DebugServer/Gdb/GdbRspDebugServer.cpp index 66317857..132312d4 100644 --- a/src/DebugServer/Gdb/GdbRspDebugServer.cpp +++ b/src/DebugServer/Gdb/GdbRspDebugServer.cpp @@ -29,6 +29,7 @@ #include "CommandPackets/HelpMonitorInfo.hpp" #include "CommandPackets/BloomVersion.hpp" #include "CommandPackets/BloomVersionMachine.hpp" +#include "CommandPackets/TargetInfoMachine.hpp" // Response packets #include "ResponsePackets/TargetStopped.hpp" @@ -313,6 +314,10 @@ namespace Bloom::DebugServer::Gdb return std::make_unique(std::move(*(monitorCommand.get()))); } + if (monitorCommand->command == "target-info machine") { + return std::make_unique(std::move(*(monitorCommand.get()))); + } + return monitorCommand; } }