Support for vFlashWrite GDB command packet

This commit is contained in:
Nav
2022-05-29 17:18:29 +01:00
parent 36800db064
commit 1a541dcd17
4 changed files with 102 additions and 0 deletions

View File

@@ -32,4 +32,5 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/WriteMemory.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/ReadMemoryMap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/FlashErase.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/FlashErase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Gdb/AvrGdb/CommandPackets/FlashWrite.cpp
) )

View File

@@ -5,6 +5,7 @@
#include "CommandPackets/WriteMemory.hpp" #include "CommandPackets/WriteMemory.hpp"
#include "CommandPackets/ReadMemoryMap.hpp" #include "CommandPackets/ReadMemoryMap.hpp"
#include "CommandPackets/FlashErase.hpp" #include "CommandPackets/FlashErase.hpp"
#include "CommandPackets/FlashWrite.hpp"
namespace Bloom::DebugServer::Gdb::AvrGdb namespace Bloom::DebugServer::Gdb::AvrGdb
{ {
@@ -36,6 +37,7 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
using AvrGdb::CommandPackets::WriteMemory; using AvrGdb::CommandPackets::WriteMemory;
using AvrGdb::CommandPackets::ReadMemoryMap; using AvrGdb::CommandPackets::ReadMemoryMap;
using AvrGdb::CommandPackets::FlashErase; using AvrGdb::CommandPackets::FlashErase;
using AvrGdb::CommandPackets::FlashWrite;
if (rawPacket.size() >= 2) { if (rawPacket.size() >= 2) {
if (rawPacket[1] == 'm') { if (rawPacket[1] == 'm') {
@@ -55,6 +57,10 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
if (rawPacketString.find("vFlashErase") == 0) { if (rawPacketString.find("vFlashErase") == 0) {
return std::make_unique<FlashErase>(rawPacket); return std::make_unique<FlashErase>(rawPacket);
} }
if (rawPacketString.find("vFlashWrite") == 0) {
return std::make_unique<FlashWrite>(rawPacket);
}
} }
return GdbRspDebugServer::resolveCommandPacket(rawPacket); return GdbRspDebugServer::resolveCommandPacket(rawPacket);

View File

@@ -0,0 +1,68 @@
#include "FlashWrite.hpp"
#include <QByteArray>
#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;
FlashWrite::FlashWrite(const RawPacketType& rawPacket)
: MemoryAccessCommandPacket(rawPacket)
{
if (this->data.size() < 15) {
throw Exception("Invalid packet length");
}
/*
* The flash write ('vFlashWrite') packet consists of two segments, an address and a buffer.
*
* Seperated by a colon.
*/
auto colonIt = std::find(this->data.begin() + 12, this->data.end(), ':');
if (colonIt == this->data.end()) {
throw Exception("Failed to find colon delimiter in write flash packet.");
}
bool conversionStatus = false;
this->startAddress = QByteArray(
reinterpret_cast<const char*>(this->data.data() + 12),
std::distance(this->data.begin(), colonIt) - 12
).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse start address from flash write packet data");
}
this->buffer = Targets::TargetMemoryBuffer(colonIt + 1, this->data.end());
}
void FlashWrite::handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) {
Logger::debug("Handling FlashWrite packet");
try {
targetControllerConsole.writeMemory(
Targets::TargetMemoryType::FLASH,
this->startAddress,
this->buffer
);
debugSession.connection.writePacket(OkResponsePacket());
} catch (const Exception& exception) {
Logger::error("Failed to write to 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 FlashWrite class implements the structure for the "vFlashWrite" packet. Upon receiving this packet, the
* server is expected to write to a particular region of the target's flash memory.
*/
class FlashWrite: public MemoryAccessCommandPacket
{
public:
std::uint32_t startAddress = 0;
Targets::TargetMemoryBuffer buffer;
explicit FlashWrite(const RawPacketType& rawPacket);
void handle(
DebugSession& debugSession,
TargetController::TargetControllerConsole& targetControllerConsole
) override;
};
}