Introduced the TargetControllerConsole class to provide access to common functionality within the TargetController.
This commit is contained in:
@@ -63,6 +63,7 @@ add_executable(Bloom
|
|||||||
src/Application.cpp
|
src/Application.cpp
|
||||||
src/DebugToolDrivers/USB/UsbDevice.cpp
|
src/DebugToolDrivers/USB/UsbDevice.cpp
|
||||||
src/TargetController/TargetController.cpp
|
src/TargetController/TargetController.cpp
|
||||||
|
src/TargetController/TargetControllerConsole.cpp
|
||||||
src/EventManager/EventListener.cpp
|
src/EventManager/EventListener.cpp
|
||||||
src/EventManager/EventManager.cpp
|
src/EventManager/EventManager.cpp
|
||||||
src/DebugServers/DebugServer.cpp
|
src/DebugServers/DebugServer.cpp
|
||||||
|
|||||||
@@ -57,177 +57,4 @@ void DebugServer::shutdown() {
|
|||||||
|
|
||||||
void DebugServer::onShutdownDebugServerEvent(EventPointer<Events::ShutdownDebugServer> event) {
|
void DebugServer::onShutdownDebugServerEvent(EventPointer<Events::ShutdownDebugServer> event) {
|
||||||
this->shutdown();
|
this->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugServer::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 DebugServer::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 DebugServer::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 DebugServer::readGeneralRegistersFromTarget(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 DebugServer::writeGeneralRegistersToTarget(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 DebugServer::readMemoryFromTarget(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 DebugServer::writeMemoryToTarget(
|
|
||||||
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 DebugServer::setBreakpointOnTarget(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 DebugServer::removeBreakpointOnTarget(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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||||
#include "src/EventManager/Events/Events.hpp"
|
#include "src/EventManager/Events/Events.hpp"
|
||||||
#include "src/EventManager/EventManager.hpp"
|
#include "src/EventManager/EventManager.hpp"
|
||||||
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
||||||
@@ -75,6 +76,11 @@ namespace Bloom::DebugServers
|
|||||||
EventManager& eventManager;
|
EventManager& eventManager;
|
||||||
EventListenerPointer eventListener = std::make_shared<EventListener>("DebugServerEventListener");
|
EventListenerPointer eventListener = std::make_shared<EventListener>("DebugServerEventListener");
|
||||||
|
|
||||||
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(
|
||||||
|
this->eventManager,
|
||||||
|
*(this->eventListener)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the interruption of any blocking file IO.
|
* Enables the interruption of any blocking file IO.
|
||||||
*/
|
*/
|
||||||
@@ -99,75 +105,6 @@ namespace Bloom::DebugServers
|
|||||||
*/
|
*/
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 readGeneralRegistersFromTarget(TargetRegisterDescriptors descriptors);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests the TargetController to write register values to the target.
|
|
||||||
*
|
|
||||||
* @param registers
|
|
||||||
*/
|
|
||||||
void writeGeneralRegistersToTarget(TargetRegisters registers);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests the TargetController to read memory from the target.
|
|
||||||
*
|
|
||||||
* @param memoryType
|
|
||||||
* @param startAddress
|
|
||||||
* @param bytes
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
TargetMemoryBuffer readMemoryFromTarget(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 writeMemoryToTarget(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests the TargetController to set a breakpoint on the target.
|
|
||||||
*
|
|
||||||
* @param breakpoint
|
|
||||||
*/
|
|
||||||
void setBreakpointOnTarget(TargetBreakpoint breakpoint);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests the TargetController to remove a breakpoint from the target.
|
|
||||||
*
|
|
||||||
* @param breakpoint
|
|
||||||
*/
|
|
||||||
void removeBreakpointOnTarget(TargetBreakpoint breakpoint);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DebugServer(EventManager& eventManager): eventManager(eventManager) {};
|
DebugServer(EventManager& eventManager): eventManager(eventManager) {};
|
||||||
|
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadGeneralRegisters& pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto registerSet = this->readGeneralRegistersFromTarget(descriptors);
|
auto registerSet = this->targetControllerConsole.readGeneralRegisters(descriptors);
|
||||||
auto registerNumberToDescriptorMapping = this->getRegisterNumberToDescriptorMapping();
|
auto registerNumberToDescriptorMapping = this->getRegisterNumberToDescriptorMapping();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -297,7 +297,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteGeneralRegisters& p
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
auto registerDescriptor = this->getRegisterDescriptorFromNumber(packet.registerNumber);
|
auto registerDescriptor = this->getRegisterDescriptorFromNumber(packet.registerNumber);
|
||||||
this->writeGeneralRegistersToTarget({TargetRegister(registerDescriptor, packet.registerValue)});
|
this->targetControllerConsole.writeGeneralRegisters({
|
||||||
|
TargetRegister(registerDescriptor, packet.registerValue)
|
||||||
|
});
|
||||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
@@ -310,7 +312,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ContinueExecution& packe
|
|||||||
Logger::debug("Handling ContinueExecution packet");
|
Logger::debug("Handling ContinueExecution packet");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this->continueTargetExecution(packet.fromProgramCounter);
|
this->targetControllerConsole.continueTargetExecution(packet.fromProgramCounter);
|
||||||
this->clientConnection->waitingForBreak = true;
|
this->clientConnection->waitingForBreak = true;
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
@@ -323,7 +325,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::StepExecution& packet) {
|
|||||||
Logger::debug("Handling StepExecution packet");
|
Logger::debug("Handling StepExecution packet");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this->stepTargetExecution(packet.fromProgramCounter);
|
this->targetControllerConsole.stepTargetExecution(packet.fromProgramCounter);
|
||||||
this->clientConnection->waitingForBreak = true;
|
this->clientConnection->waitingForBreak = true;
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
@@ -338,7 +340,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadMemory& packet) {
|
|||||||
try {
|
try {
|
||||||
auto memoryType = this->getMemoryTypeFromGdbAddress(packet.startAddress);
|
auto memoryType = this->getMemoryTypeFromGdbAddress(packet.startAddress);
|
||||||
auto startAddress = this->removeMemoryTypeIndicatorFromGdbAddress(packet.startAddress);
|
auto startAddress = this->removeMemoryTypeIndicatorFromGdbAddress(packet.startAddress);
|
||||||
auto memoryBuffer = this->readMemoryFromTarget(memoryType, startAddress, packet.bytes);
|
auto memoryBuffer = this->targetControllerConsole.readMemory(memoryType, startAddress, packet.bytes);
|
||||||
|
|
||||||
auto hexMemoryBuffer = Packet::dataToHex(memoryBuffer);
|
auto hexMemoryBuffer = Packet::dataToHex(memoryBuffer);
|
||||||
this->clientConnection->writePacket(
|
this->clientConnection->writePacket(
|
||||||
@@ -357,7 +359,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteMemory& packet) {
|
|||||||
try {
|
try {
|
||||||
auto memoryType = this->getMemoryTypeFromGdbAddress(packet.startAddress);
|
auto memoryType = this->getMemoryTypeFromGdbAddress(packet.startAddress);
|
||||||
auto startAddress = this->removeMemoryTypeIndicatorFromGdbAddress(packet.startAddress);
|
auto startAddress = this->removeMemoryTypeIndicatorFromGdbAddress(packet.startAddress);
|
||||||
this->writeMemoryToTarget(memoryType, startAddress, packet.buffer);
|
this->targetControllerConsole.writeMemory(memoryType, startAddress, packet.buffer);
|
||||||
|
|
||||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||||
|
|
||||||
@@ -373,7 +375,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::SetBreakpoint& packet) {
|
|||||||
try {
|
try {
|
||||||
auto breakpoint = TargetBreakpoint();
|
auto breakpoint = TargetBreakpoint();
|
||||||
breakpoint.address = packet.address;
|
breakpoint.address = packet.address;
|
||||||
this->setBreakpointOnTarget(breakpoint);
|
this->targetControllerConsole.setBreakpoint(breakpoint);
|
||||||
|
|
||||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||||
|
|
||||||
@@ -389,7 +391,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::RemoveBreakpoint& packet
|
|||||||
try {
|
try {
|
||||||
auto breakpoint = TargetBreakpoint();
|
auto breakpoint = TargetBreakpoint();
|
||||||
breakpoint.address = packet.address;
|
breakpoint.address = packet.address;
|
||||||
this->removeBreakpointOnTarget(breakpoint);
|
this->targetControllerConsole.removeBreakpoint(breakpoint);
|
||||||
|
|
||||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||||
|
|
||||||
@@ -403,7 +405,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::InterruptExecution& pack
|
|||||||
Logger::debug("Handling InterruptExecution packet");
|
Logger::debug("Handling InterruptExecution packet");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this->stopTargetExecution();
|
this->targetControllerConsole.stopTargetExecution();
|
||||||
this->clientConnection->writePacket(TargetStopped(Signal::INTERRUPTED));
|
this->clientConnection->writePacket(TargetStopped(Signal::INTERRUPTED));
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void Insight::startup() {
|
|||||||
std::bind(&Insight::onTargetControllerStateChangedEvent, this, std::placeholders::_1)
|
std::bind(&Insight::onTargetControllerStateChangedEvent, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto targetDescriptor = this->getTargetDescriptor();
|
auto targetDescriptor = this->targetControllerConsole.getTargetDescriptor();
|
||||||
|
|
||||||
std::string qtAppName = "Bloom";
|
std::string qtAppName = "Bloom";
|
||||||
char* appArguments[] = {qtAppName.data()};
|
char* appArguments[] = {qtAppName.data()};
|
||||||
@@ -91,24 +91,6 @@ void Insight::startup() {
|
|||||||
connect(&(this->mainWindow), &InsightWindow::setTargetPinState, worker, &InsightWorker::requestPinStateUpdate);
|
connect(&(this->mainWindow), &InsightWindow::setTargetPinState, worker, &InsightWorker::requestPinStateUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Targets::TargetDescriptor Insight::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 Insight::shutdown() {
|
void Insight::shutdown() {
|
||||||
if (this->getState() == ThreadState::STOPPED) {
|
if (this->getState() == ThreadState::STOPPED) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "UserInterfaces/InsightWindow/InsightWindow.hpp"
|
#include "UserInterfaces/InsightWindow/InsightWindow.hpp"
|
||||||
|
|
||||||
#include "src/Helpers/Thread.hpp"
|
#include "src/Helpers/Thread.hpp"
|
||||||
#include "src/ApplicationConfig.hpp"
|
#include "src/ApplicationConfig.hpp"
|
||||||
#include "src/EventManager/EventManager.hpp"
|
#include "src/EventManager/EventManager.hpp"
|
||||||
#include "src/EventManager/EventListener.hpp"
|
#include "src/EventManager/EventListener.hpp"
|
||||||
#include "src/Targets/TargetDescriptor.hpp"
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||||
|
|
||||||
namespace Bloom
|
namespace Bloom
|
||||||
{
|
{
|
||||||
@@ -34,6 +34,11 @@ namespace Bloom
|
|||||||
QApplication* application = nullptr;
|
QApplication* application = nullptr;
|
||||||
InsightWindow mainWindow;
|
InsightWindow mainWindow;
|
||||||
|
|
||||||
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(
|
||||||
|
this->eventManager,
|
||||||
|
*(this->eventListener)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insight consists of two threads - the main thread where the main Qt event loop runs (for the GUI), and
|
* Insight consists of two threads - the main thread where the main Qt event loop runs (for the GUI), and
|
||||||
* a single worker thread to handle any blocking/time-expensive operations.
|
* a single worker thread to handle any blocking/time-expensive operations.
|
||||||
@@ -42,8 +47,6 @@ namespace Bloom
|
|||||||
|
|
||||||
void startup();
|
void startup();
|
||||||
|
|
||||||
Targets::TargetDescriptor getTargetDescriptor();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Insight(EventManager& eventManager): eventManager(eventManager) {};
|
Insight(EventManager& eventManager): eventManager(eventManager) {};
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,7 @@ void InsightWorker::startup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InsightWorker::requestPinStates(int variantId) {
|
void InsightWorker::requestPinStates(int variantId) {
|
||||||
auto requestEvent = std::make_shared<Events::RetrieveTargetPinStates>();
|
this->targetControllerConsole.requestPinStates(variantId);
|
||||||
requestEvent->variantId = variantId;
|
|
||||||
|
|
||||||
this->eventManager.triggerEvent(requestEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsightWorker::requestPinStateUpdate(
|
void InsightWorker::requestPinStateUpdate(
|
||||||
@@ -54,12 +51,7 @@ void InsightWorker::requestPinStateUpdate(
|
|||||||
Bloom::Targets::TargetPinDescriptor pinDescriptor,
|
Bloom::Targets::TargetPinDescriptor pinDescriptor,
|
||||||
Bloom::Targets::TargetPinState pinState
|
Bloom::Targets::TargetPinState pinState
|
||||||
) {
|
) {
|
||||||
auto updateEvent = std::make_shared<Events::SetTargetPinState>();
|
this->targetControllerConsole.setPinState(variantId, pinDescriptor, pinState);
|
||||||
updateEvent->variantId = variantId;
|
|
||||||
updateEvent->pinDescriptor = pinDescriptor;
|
|
||||||
updateEvent->pinState = pinState;
|
|
||||||
|
|
||||||
this->eventManager.triggerEvent(updateEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsightWorker::onTargetStoppedEvent(EventPointer<TargetExecutionStopped> event) {
|
void InsightWorker::onTargetStoppedEvent(EventPointer<TargetExecutionStopped> event) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "src/ApplicationConfig.hpp"
|
#include "src/ApplicationConfig.hpp"
|
||||||
#include "src/EventManager/EventManager.hpp"
|
#include "src/EventManager/EventManager.hpp"
|
||||||
#include "src/EventManager/EventListener.hpp"
|
#include "src/EventManager/EventListener.hpp"
|
||||||
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||||
|
|
||||||
namespace Bloom
|
namespace Bloom
|
||||||
{
|
{
|
||||||
@@ -25,6 +26,11 @@ namespace Bloom
|
|||||||
EventManager& eventManager;
|
EventManager& eventManager;
|
||||||
EventListenerPointer eventListener = std::make_shared<EventListener>("InsightWorkerEventListener");
|
EventListenerPointer eventListener = std::make_shared<EventListener>("InsightWorkerEventListener");
|
||||||
|
|
||||||
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(
|
||||||
|
this->eventManager,
|
||||||
|
*(this->eventListener)
|
||||||
|
);
|
||||||
|
|
||||||
QTimer* eventDispatchTimer = nullptr;
|
QTimer* eventDispatchTimer = nullptr;
|
||||||
|
|
||||||
void onTargetStoppedEvent(EventPointer<TargetExecutionStopped> event);
|
void onTargetStoppedEvent(EventPointer<TargetExecutionStopped> event);
|
||||||
|
|||||||
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