New custom GDB command to output target info in JSON format

This commit is contained in:
Nav
2022-05-06 19:31:33 +01:00
parent 7776ba88c3
commit a60f780287
5 changed files with 112 additions and 4 deletions

View File

@@ -4,4 +4,6 @@ Supported Bloom commands:
version Outputs Bloom's version information.
version machine Outputs Bloom's version information in JSON format.
target-info machine Outputs information on the connected target, in JSON format.
reset Resets the target and holds it in a stopped state.

View File

@@ -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

View File

@@ -0,0 +1,70 @@
#include "TargetInfoMachine.hpp"
#include <QString>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#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, QString>({
{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<qint64>(memoryDescriptor.size())},
{"addressRange", QJsonObject({
{"startAddress", static_cast<qint64>(memoryDescriptor.addressRange.startAddress)},
{"endAddress", static_cast<qint64>(memoryDescriptor.addressRange.endAddress)},
})}
}));
}
return QJsonObject({
{"target", QJsonObject({
{"name", QString::fromStdString(targetDescriptor.name)},
{"id", QString::fromStdString(targetDescriptor.id)},
{"memoryDescriptors", memoryDescriptors},
})},
});
}
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include <cstdint>
#include <QJsonObject>
#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;
};
}

View File

@@ -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<CommandPackets::ResetTarget>(std::move(*(monitorCommand.get())));
}
if (monitorCommand->command == "target-info machine") {
return std::make_unique<CommandPackets::TargetInfoMachine>(std::move(*(monitorCommand.get())));
}
return monitorCommand;
}
}