Introduced the TargetControllerConsole class to provide access to common functionality within the TargetController.
This commit is contained in:
217
src/TargetController/TargetControllerConsole.cpp
Normal file
217
src/TargetController/TargetControllerConsole.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "TargetControllerConsole.hpp"
|
||||
#include "src/EventManager/Events/Events.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
|
||||
using namespace Bloom;
|
||||
|
||||
Targets::TargetDescriptor TargetControllerConsole::getTargetDescriptor() {
|
||||
auto extractEvent = std::make_shared<Events::ExtractTargetDescriptor>();
|
||||
this->eventManager.triggerEvent(extractEvent);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::TargetDescriptorExtracted,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), extractEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetDescriptorExtracted>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
|
||||
auto descriptorExtracted = std::get<EventPointer<Events::TargetDescriptorExtracted>>(responseEvent.value());
|
||||
return descriptorExtracted->targetDescriptor;
|
||||
}
|
||||
|
||||
void TargetControllerConsole::stopTargetExecution() {
|
||||
auto stopTargetEvent = std::make_shared<Events::StopTargetExecution>();
|
||||
this->eventManager.triggerEvent(stopTargetEvent);
|
||||
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::TargetExecutionStopped,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), stopTargetEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetExecutionStopped>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void TargetControllerConsole::continueTargetExecution(std::optional<std::uint32_t> fromAddress) {
|
||||
auto resumeExecutionEvent = std::make_shared<Events::ResumeTargetExecution>();
|
||||
|
||||
if (fromAddress.has_value()) {
|
||||
resumeExecutionEvent->fromProgramCounter = fromAddress.value();
|
||||
}
|
||||
|
||||
this->eventManager.triggerEvent(resumeExecutionEvent);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::TargetExecutionResumed,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), resumeExecutionEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetExecutionResumed>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void TargetControllerConsole::stepTargetExecution(std::optional<std::uint32_t> fromAddress) {
|
||||
auto stepExecutionEvent = std::make_shared<Events::StepTargetExecution>();
|
||||
|
||||
if (fromAddress.has_value()) {
|
||||
stepExecutionEvent->fromProgramCounter = fromAddress.value();
|
||||
}
|
||||
|
||||
this->eventManager.triggerEvent(stepExecutionEvent);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::TargetExecutionResumed,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), stepExecutionEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetExecutionResumed>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
TargetRegisters TargetControllerConsole::readGeneralRegisters(TargetRegisterDescriptors descriptors) {
|
||||
auto readRegistersEvent = std::make_shared<Events::RetrieveRegistersFromTarget>();
|
||||
readRegistersEvent->descriptors = descriptors;
|
||||
|
||||
this->eventManager.triggerEvent(readRegistersEvent);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::RegistersRetrievedFromTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), readRegistersEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::RegistersRetrievedFromTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
|
||||
auto retrievedRegistersEvent = std::get<EventPointer<Events::RegistersRetrievedFromTarget>>(responseEvent.value());
|
||||
return retrievedRegistersEvent->registers;
|
||||
}
|
||||
|
||||
void TargetControllerConsole::writeGeneralRegisters(TargetRegisters registers) {
|
||||
auto event = std::make_shared<Events::WriteRegistersToTarget>();
|
||||
event->registers = registers;
|
||||
|
||||
this->eventManager.triggerEvent(event);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::RegistersWrittenToTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), event->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::RegistersWrittenToTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
TargetMemoryBuffer TargetControllerConsole::readMemory(
|
||||
TargetMemoryType memoryType,
|
||||
std::uint32_t startAddress,
|
||||
std::uint32_t bytes
|
||||
) {
|
||||
auto readMemoryEvent = std::make_shared<Events::RetrieveMemoryFromTarget>();
|
||||
readMemoryEvent->memoryType = memoryType;
|
||||
readMemoryEvent->startAddress = startAddress;
|
||||
readMemoryEvent->bytes = bytes;
|
||||
|
||||
this->eventManager.triggerEvent(readMemoryEvent);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::MemoryRetrievedFromTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), readMemoryEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::MemoryRetrievedFromTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
|
||||
auto retrievedRegistersEvent = std::get<EventPointer<Events::MemoryRetrievedFromTarget>>(responseEvent.value());
|
||||
return retrievedRegistersEvent->data;
|
||||
}
|
||||
|
||||
void TargetControllerConsole::writeMemory(
|
||||
TargetMemoryType memoryType,
|
||||
std::uint32_t startAddress,
|
||||
const TargetMemoryBuffer& buffer
|
||||
) {
|
||||
auto writeMemoryEvent = std::make_shared<Events::WriteMemoryToTarget>();
|
||||
writeMemoryEvent->memoryType = memoryType;
|
||||
writeMemoryEvent->startAddress = startAddress;
|
||||
writeMemoryEvent->buffer = buffer;
|
||||
|
||||
this->eventManager.triggerEvent(writeMemoryEvent);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::MemoryWrittenToTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), writeMemoryEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::MemoryWrittenToTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void TargetControllerConsole::setBreakpoint(TargetBreakpoint breakpoint) {
|
||||
auto event = std::make_shared<Events::SetBreakpointOnTarget>();
|
||||
event->breakpoint = breakpoint;
|
||||
|
||||
this->eventManager.triggerEvent(event);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::BreakpointSetOnTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), event->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::BreakpointSetOnTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void TargetControllerConsole::removeBreakpoint(TargetBreakpoint breakpoint) {
|
||||
auto event = std::make_shared<Events::RemoveBreakpointOnTarget>();
|
||||
event->breakpoint = breakpoint;
|
||||
|
||||
this->eventManager.triggerEvent(event);
|
||||
auto responseEvent = this->eventListener.waitForEvent<
|
||||
Events::BreakpointRemovedOnTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), event->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::BreakpointRemovedOnTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void TargetControllerConsole::requestPinStates(int variantId) {
|
||||
auto requestEvent = std::make_shared<Events::RetrieveTargetPinStates>();
|
||||
requestEvent->variantId = variantId;
|
||||
|
||||
this->eventManager.triggerEvent(requestEvent);
|
||||
}
|
||||
|
||||
void TargetControllerConsole::setPinState(int variantId, TargetPinDescriptor pinDescriptor, TargetPinState pinState) {
|
||||
auto updateEvent = std::make_shared<Events::SetTargetPinState>();
|
||||
updateEvent->variantId = variantId;
|
||||
updateEvent->pinDescriptor = pinDescriptor;
|
||||
updateEvent->pinState = pinState;
|
||||
|
||||
this->eventManager.triggerEvent(updateEvent);
|
||||
}
|
||||
126
src/TargetController/TargetControllerConsole.hpp
Normal file
126
src/TargetController/TargetControllerConsole.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include "src/EventManager/EventListener.hpp"
|
||||
#include "src/EventManager/EventManager.hpp"
|
||||
|
||||
#include "src/Targets/TargetRegister.hpp"
|
||||
#include "src/Targets/TargetMemory.hpp"
|
||||
#include "src/Targets/TargetBreakpoint.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
#include "src/Targets/TargetState.hpp"
|
||||
#include "src/Targets/TargetPinDescriptor.hpp"
|
||||
|
||||
namespace Bloom
|
||||
{
|
||||
using namespace Targets;
|
||||
|
||||
/**
|
||||
* The TargetControllerConsole provides an interface to the TargetController, for components within Bloom that
|
||||
* require access to common functionality from the TargetController.
|
||||
*/
|
||||
class TargetControllerConsole
|
||||
{
|
||||
private:
|
||||
EventManager& eventManager;
|
||||
EventListener& eventListener;
|
||||
|
||||
public:
|
||||
TargetControllerConsole(EventManager& eventManager, EventListener& eventListener):
|
||||
eventManager(eventManager), eventListener(eventListener) {};
|
||||
|
||||
/**
|
||||
* Requests the TargetDescriptor from the TargetController
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TargetDescriptor getTargetDescriptor();
|
||||
|
||||
/**
|
||||
* Requests the TargetController to halt execution on the target.
|
||||
*/
|
||||
void stopTargetExecution();
|
||||
|
||||
/**
|
||||
* Requests the TargetController to continue execution on the target.
|
||||
*
|
||||
* @param fromAddress
|
||||
*/
|
||||
void continueTargetExecution(std::optional<std::uint32_t> fromAddress);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to step execution on the target.
|
||||
*
|
||||
* @param fromAddress
|
||||
*/
|
||||
void stepTargetExecution(std::optional<std::uint32_t> fromAddress);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to read register values from the target.
|
||||
*
|
||||
* @param descriptors
|
||||
* Descriptors of the registers to read.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TargetRegisters readGeneralRegisters(TargetRegisterDescriptors descriptors);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to write register values to the target.
|
||||
*
|
||||
* @param registers
|
||||
*/
|
||||
void writeGeneralRegisters(TargetRegisters registers);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to read memory from the target.
|
||||
*
|
||||
* @param memoryType
|
||||
* @param startAddress
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
TargetMemoryBuffer readMemory(TargetMemoryType memoryType, std::uint32_t startAddress, std::uint32_t bytes);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to write memory to the target.
|
||||
*
|
||||
* @param memoryType
|
||||
* @param startAddress
|
||||
* @param buffer
|
||||
*/
|
||||
void writeMemory(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to set a breakpoint on the target.
|
||||
*
|
||||
* @param breakpoint
|
||||
*/
|
||||
void setBreakpoint(TargetBreakpoint breakpoint);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to remove a breakpoint from the target.
|
||||
*
|
||||
* @param breakpoint
|
||||
*/
|
||||
void removeBreakpoint(TargetBreakpoint breakpoint);
|
||||
|
||||
/**
|
||||
* Requests a pin state update on the target, for a specific pin.
|
||||
*
|
||||
* @param variantId
|
||||
* @param pinDescriptor
|
||||
* @param pinState
|
||||
*/
|
||||
void setPinState(int variantId, TargetPinDescriptor pinDescriptor, TargetPinState pinState);
|
||||
|
||||
/**
|
||||
* Requests a pin state refresh from the TargetController, for a specific target variant.
|
||||
*
|
||||
* @param variantId
|
||||
*/
|
||||
void requestPinStates(int variantId);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user