diff --git a/src/EventManager/Events/Event.hpp b/src/EventManager/Events/Event.hpp index 40dca69a..6fdd6768 100644 --- a/src/EventManager/Events/Event.hpp +++ b/src/EventManager/Events/Event.hpp @@ -28,7 +28,6 @@ namespace Bloom::Events REGISTERS_WRITTEN_TO_TARGET, TARGET_EXECUTION_RESUMED, TARGET_EXECUTION_STOPPED, - WRITE_MEMORY_TO_TARGET, MEMORY_WRITTEN_TO_TARGET, SET_BREAKPOINT_ON_TARGET, REMOVE_BREAKPOINT_ON_TARGET, diff --git a/src/EventManager/Events/Events.hpp b/src/EventManager/Events/Events.hpp index dd659188..10f8a179 100644 --- a/src/EventManager/Events/Events.hpp +++ b/src/EventManager/Events/Events.hpp @@ -15,7 +15,6 @@ #include "RegistersWrittenToTarget.hpp" #include "TargetExecutionResumed.hpp" #include "TargetExecutionStopped.hpp" -#include "WriteMemoryToTarget.hpp" #include "MemoryWrittenToTarget.hpp" #include "SetBreakpointOnTarget.hpp" #include "RemoveBreakpointOnTarget.hpp" diff --git a/src/EventManager/Events/WriteMemoryToTarget.hpp b/src/EventManager/Events/WriteMemoryToTarget.hpp deleted file mode 100644 index 9ef06cef..00000000 --- a/src/EventManager/Events/WriteMemoryToTarget.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "Event.hpp" -#include "MemoryWrittenToTarget.hpp" -#include "src/Targets/TargetMemory.hpp" - -namespace Bloom::Events -{ - class WriteMemoryToTarget: public Event - { - public: - using TargetControllerResponseType = MemoryWrittenToTarget; - - static constexpr EventType type = EventType::WRITE_MEMORY_TO_TARGET; - static inline const std::string name = "WriteMemoryToTarget"; - Targets::TargetMemoryType memoryType = Targets::TargetMemoryType::RAM; - std::uint32_t startAddress = 0; - Targets::TargetMemoryBuffer buffer; - - WriteMemoryToTarget() = default; - WriteMemoryToTarget( - Targets::TargetMemoryType memoryType, - std::uint32_t startAddress, - Targets::TargetMemoryBuffer buffer - ): memoryType(memoryType), startAddress(startAddress), buffer(std::move(buffer)) {}; - - [[nodiscard]] EventType getType() const override { - return WriteMemoryToTarget::type; - } - - [[nodiscard]] std::string getName() const override { - return WriteMemoryToTarget::name; - } - }; -} diff --git a/src/TargetController/Commands/CommandTypes.hpp b/src/TargetController/Commands/CommandTypes.hpp index b9a732ff..4843c279 100644 --- a/src/TargetController/Commands/CommandTypes.hpp +++ b/src/TargetController/Commands/CommandTypes.hpp @@ -16,5 +16,6 @@ namespace Bloom::TargetController::Commands READ_TARGET_MEMORY, GET_TARGET_STATE, STEP_TARGET_EXECUTION, + WRITE_TARGET_MEMORY, }; } diff --git a/src/TargetController/Commands/WriteTargetMemory.hpp b/src/TargetController/Commands/WriteTargetMemory.hpp new file mode 100644 index 00000000..ea56a8de --- /dev/null +++ b/src/TargetController/Commands/WriteTargetMemory.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "Command.hpp" +#include "src/TargetController/Responses/TargetMemoryRead.hpp" + +#include "src/Targets/TargetMemory.hpp" + +namespace Bloom::TargetController::Commands +{ + class WriteTargetMemory: public Command + { + public: + static constexpr CommandType type = CommandType::WRITE_TARGET_MEMORY; + static inline const std::string name = "WriteTargetMemory"; + + Targets::TargetMemoryType memoryType; + std::uint32_t startAddress; + Targets::TargetMemoryBuffer buffer; + + explicit WriteTargetMemory( + Targets::TargetMemoryType memoryType, + std::uint32_t startAddress, + const Targets::TargetMemoryBuffer& buffer + ) + : memoryType(memoryType) + , startAddress(startAddress) + , buffer(buffer) + {}; + + [[nodiscard]] CommandType getType() const override { + return WriteTargetMemory::type; + } + + [[nodiscard]] bool requiresStoppedTargetState() const override { + return true; + } + }; +} diff --git a/src/TargetController/TargetControllerComponent.cpp b/src/TargetController/TargetControllerComponent.cpp index e4e9aee3..73ce7dc2 100644 --- a/src/TargetController/TargetControllerComponent.cpp +++ b/src/TargetController/TargetControllerComponent.cpp @@ -29,6 +29,7 @@ namespace Bloom::TargetController using Commands::ReadTargetRegisters; using Commands::WriteTargetRegisters; using Commands::ReadTargetMemory; + using Commands::WriteTargetMemory; using Commands::StepTargetExecution; using Responses::Response; @@ -389,11 +390,11 @@ namespace Bloom::TargetController this->deregisterCommandHandler(ReadTargetRegisters::type); this->deregisterCommandHandler(WriteTargetRegisters::type); this->deregisterCommandHandler(ReadTargetMemory::type); + this->deregisterCommandHandler(WriteTargetMemory::type); this->deregisterCommandHandler(StepTargetExecution::type); this->eventListener->deregisterCallbacksForEventType(); this->eventListener->deregisterCallbacksForEventType(); - this->eventListener->deregisterCallbacksForEventType(); this->eventListener->deregisterCallbacksForEventType(); this->eventListener->deregisterCallbacksForEventType(); this->eventListener->deregisterCallbacksForEventType(); @@ -445,6 +446,10 @@ namespace Bloom::TargetController std::bind(&TargetControllerComponent::handleReadTargetMemory, this, std::placeholders::_1) ); + this->registerCommandHandler( + std::bind(&TargetControllerComponent::handleWriteTargetMemory, this, std::placeholders::_1) + ); + this->registerCommandHandler( std::bind(&TargetControllerComponent::handleStepTargetExecution, this, std::placeholders::_1) ); @@ -457,10 +462,6 @@ namespace Bloom::TargetController std::bind(&TargetControllerComponent::onExtractTargetDescriptor, this, std::placeholders::_1) ); - this->eventListener->registerCallbackForEventType( - std::bind(&TargetControllerComponent::onWriteMemoryEvent, this, std::placeholders::_1) - ); - this->eventListener->registerCallbackForEventType( std::bind(&TargetControllerComponent::onSetBreakpointEvent, this, std::placeholders::_1) ); @@ -799,6 +800,55 @@ namespace Bloom::TargetController )); } + std::unique_ptr TargetControllerComponent::handleWriteTargetMemory(WriteTargetMemory& command) { + const auto& buffer = command.buffer; + const auto bufferSize = command.buffer.size(); + const auto bufferStartAddress = command.startAddress; + + this->target->writeMemory(command.memoryType, bufferStartAddress, buffer); + EventManager::triggerEvent(std::make_shared()); + + if ( + EventManager::isEventTypeListenedFor(Events::RegistersWrittenToTarget::type) + && this->registerDescriptorsByMemoryType.contains(command.memoryType) + ) { + /* + * The memory type we just wrote to contains some number of registers - if we've written to any address + * that is known to store the value of a register, trigger a RegistersWrittenToTarget event + */ + const auto bufferEndAddress = static_cast(bufferStartAddress + (bufferSize - 1)); + auto registerDescriptors = this->getRegisterDescriptorsWithinAddressRange( + bufferStartAddress, + bufferEndAddress, + command.memoryType + ); + + if (!registerDescriptors.empty()) { + auto registersWrittenEvent = std::make_shared(); + + for (const auto& registerDescriptor : registerDescriptors) { + const auto registerSize = registerDescriptor.size; + const auto registerStartAddress = registerDescriptor.startAddress.value(); + const auto registerEndAddress = registerStartAddress + (registerSize - 1); + + if (registerStartAddress < bufferStartAddress || registerEndAddress > bufferEndAddress) { + continue; + } + + const auto bufferBeginIt = buffer.begin() + (registerStartAddress - bufferStartAddress); + registersWrittenEvent->registers.emplace_back(TargetRegister( + registerDescriptor, + TargetMemoryBuffer(bufferBeginIt, bufferBeginIt + registerSize) + )); + } + + EventManager::triggerEvent(registersWrittenEvent); + } + } + + return std::make_unique(); + } + std::unique_ptr TargetControllerComponent::handleStepTargetExecution(StepTargetExecution& command) { if (command.fromProgramCounter.has_value()) { this->target->setProgramCounter(command.fromProgramCounter.value()); @@ -811,62 +861,6 @@ namespace Bloom::TargetController return std::make_unique(); } - void TargetControllerComponent::onWriteMemoryEvent(const Events::WriteMemoryToTarget& event) { - try { - const auto& buffer = event.buffer; - const auto bufferSize = event.buffer.size(); - const auto bufferStartAddress = event.startAddress; - - this->target->writeMemory(event.memoryType, event.startAddress, event.buffer); - - auto memoryWrittenEvent = std::make_shared(); - memoryWrittenEvent->correlationId = event.id; - EventManager::triggerEvent(memoryWrittenEvent); - - if (EventManager::isEventTypeListenedFor(Events::RegistersWrittenToTarget::type) - && this->registerDescriptorsByMemoryType.contains(event.memoryType) - ) { - /* - * The memory type we just wrote to contains some number of registers - if we've written to any address - * that is known to store the value of a register, trigger a RegistersWrittenToTarget event - */ - const auto bufferEndAddress = static_cast(bufferStartAddress + (bufferSize - 1)); - auto registerDescriptors = this->getRegisterDescriptorsWithinAddressRange( - bufferStartAddress, - bufferEndAddress, - event.memoryType - ); - - if (!registerDescriptors.empty()) { - auto registersWrittenEvent = std::make_shared(); - registersWrittenEvent->correlationId = event.id; - - for (const auto& registerDescriptor : registerDescriptors) { - const auto registerSize = registerDescriptor.size; - const auto registerStartAddress = registerDescriptor.startAddress.value(); - const auto registerEndAddress = registerStartAddress + (registerSize - 1); - - if (registerStartAddress < bufferStartAddress || registerEndAddress > bufferEndAddress) { - continue; - } - - const auto bufferBeginIt = buffer.begin() + (registerStartAddress - bufferStartAddress); - registersWrittenEvent->registers.emplace_back(TargetRegister( - registerDescriptor, - TargetMemoryBuffer(bufferBeginIt, bufferBeginIt + registerSize) - )); - } - - EventManager::triggerEvent(registersWrittenEvent); - } - } - - } catch (const TargetOperationFailure& exception) { - Logger::error("Failed to write memory to target - " + exception.getMessage()); - this->emitErrorEvent(event.id, exception.getMessage()); - } - } - void TargetControllerComponent::onSetBreakpointEvent(const Events::SetBreakpointOnTarget& event) { try { this->target->setBreakpoint(event.breakpoint.address); diff --git a/src/TargetController/TargetControllerComponent.hpp b/src/TargetController/TargetControllerComponent.hpp index 51927108..f25a15de 100644 --- a/src/TargetController/TargetControllerComponent.hpp +++ b/src/TargetController/TargetControllerComponent.hpp @@ -25,6 +25,7 @@ #include "Commands/ReadTargetRegisters.hpp" #include "Commands/WriteTargetRegisters.hpp" #include "Commands/ReadTargetMemory.hpp" +#include "Commands/WriteTargetMemory.hpp" #include "Commands/StepTargetExecution.hpp" // Responses @@ -303,15 +304,9 @@ namespace Bloom::TargetController ); std::unique_ptr handleWriteTargetRegisters(Commands::WriteTargetRegisters& command); std::unique_ptr handleReadTargetMemory(Commands::ReadTargetMemory& command); + std::unique_ptr handleWriteTargetMemory(Commands::WriteTargetMemory& command); std::unique_ptr handleStepTargetExecution(Commands::StepTargetExecution& command); - /** - * Will attempt to write memory to the target. On success, a MemoryWrittenToTarget event is emitted. - * - * @param event - */ - void onWriteMemoryEvent(const Events::WriteMemoryToTarget& event); - /** * Will attempt to set the specific breakpoint on the target. On success, the BreakpointSetOnTarget event will * be emitted. diff --git a/src/TargetController/TargetControllerConsole.cpp b/src/TargetController/TargetControllerConsole.cpp index f3f5a007..c2647735 100644 --- a/src/TargetController/TargetControllerConsole.cpp +++ b/src/TargetController/TargetControllerConsole.cpp @@ -12,6 +12,7 @@ #include "Commands/ReadTargetRegisters.hpp" #include "Commands/WriteTargetRegisters.hpp" #include "Commands/ReadTargetMemory.hpp" +#include "Commands/WriteTargetMemory.hpp" #include "Commands/StepTargetExecution.hpp" #include "src/Logger/Logger.hpp" @@ -29,6 +30,7 @@ namespace Bloom::TargetController using Commands::ReadTargetRegisters; using Commands::WriteTargetRegisters; using Commands::ReadTargetMemory; + using Commands::WriteTargetMemory; using Commands::StepTargetExecution; TargetControllerConsole::TargetControllerConsole(EventListener& eventListener) @@ -130,12 +132,10 @@ namespace Bloom::TargetController std::uint32_t startAddress, const TargetMemoryBuffer& buffer ) { - auto writeMemoryEvent = std::make_shared(); - writeMemoryEvent->memoryType = memoryType; - writeMemoryEvent->startAddress = startAddress; - writeMemoryEvent->buffer = buffer; - - this->triggerTargetControllerEventAndWaitForResponse(writeMemoryEvent); + this->commandManager.sendCommandAndWaitForResponse( + std::make_unique(memoryType, startAddress, buffer), + this->defaultTimeout + ); } void TargetControllerConsole::setBreakpoint(TargetBreakpoint breakpoint) {