Support for vFlashErase GDB command packet

This commit is contained in:
Nav
2022-05-28 22:47:25 +01:00
parent ce33ecba99
commit 9bf0e30de8
4 changed files with 102 additions and 0 deletions

View File

@@ -31,4 +31,5 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/ReadMemory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/WriteMemory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/ReadMemoryMap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/FlashErase.cpp
)

View File

@@ -4,6 +4,7 @@
#include "CommandPackets/ReadMemory.hpp"
#include "CommandPackets/WriteMemory.hpp"
#include "CommandPackets/ReadMemoryMap.hpp"
#include "CommandPackets/FlashErase.hpp"
namespace Bloom::DebugServer::Gdb::AvrGdb
{
@@ -34,6 +35,7 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
using AvrGdb::CommandPackets::ReadMemory;
using AvrGdb::CommandPackets::WriteMemory;
using AvrGdb::CommandPackets::ReadMemoryMap;
using AvrGdb::CommandPackets::FlashErase;
if (rawPacket.size() >= 2) {
if (rawPacket[1] == 'm') {
@@ -49,6 +51,10 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
if (rawPacketString.find("qXfer:memory-map:read::") == 0) {
return std::make_unique<ReadMemoryMap>(rawPacket);
}
if (rawPacketString.find("vFlashErase") == 0) {
return std::make_unique<FlashErase>(rawPacket);
}
}
return GdbRspDebugServer::resolveCommandPacket(rawPacket);

View File

@@ -0,0 +1,68 @@
#include "FlashErase.hpp"
#include "src/DebugServer/Gdb/ResponsePackets/ErrorResponsePacket.hpp"
#include "src/DebugServer/Gdb/ResponsePackets/OkResponsePacket.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Bloom::DebugServer::Gdb::AvrGdb::CommandPackets
{
using TargetController::TargetControllerConsole;
using ResponsePackets::ErrorResponsePacket;
using ResponsePackets::OkResponsePacket;
using namespace Bloom::Exceptions;
FlashErase::FlashErase(const RawPacketType& rawPacket)
: MemoryAccessCommandPacket(rawPacket)
{
auto packetString = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 12),
static_cast<int>(this->data.size() - 12)
);
/*
* The flash erase ('vFlashErase') packet consists of two segments, an address and a length, separated by a
* comma.
*/
auto packetSegments = packetString.split(",");
if (packetSegments.size() != 2) {
throw Exception(
"Unexpected number of segments in packet data: " + std::to_string(packetSegments.size())
);
}
bool conversionStatus = false;
this->startAddress = packetSegments.at(0).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse start address from flash erase packet data");
}
this->bytes = packetSegments.at(1).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse length from flash erase packet data");
}
}
void FlashErase::handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) {
Logger::debug("Handling FlashErase packet");
try {
targetControllerConsole.writeMemory(
Targets::TargetMemoryType::FLASH,
this->startAddress,
Targets::TargetMemoryBuffer(this->bytes, 0xFF)
);
debugSession.connection.writePacket(OkResponsePacket());
} catch (const Exception& exception) {
Logger::error("Failed to erase flash memory - " + exception.getMessage());
debugSession.connection.writePacket(ErrorResponsePacket());
}
}
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include <cstdint>
#include <optional>
#include "MemoryAccessCommandPacket.hpp"
namespace Bloom::DebugServer::Gdb::AvrGdb::CommandPackets
{
/**
* The FlashErase class implements the structure for the "vFlashErase" packet. Upon receiving this packet, the
* server is expected to erase a particular region of the target's flash memory.
*/
class FlashErase: public MemoryAccessCommandPacket
{
public:
std::uint32_t startAddress = 0;
std::uint32_t bytes = 0;
explicit FlashErase(const RawPacketType& rawPacket);
void handle(
DebugSession& debugSession,
TargetController::TargetControllerConsole& targetControllerConsole
) override;
};
}