This commit is contained in:
Nav
2021-04-06 02:10:14 +01:00
parent 2fd045e056
commit 7a28f93ee9
85 changed files with 319 additions and 1177 deletions

3
.gitignore vendored
View File

@@ -6,4 +6,5 @@ build/cmake-build-release
build/resources
build/bin/bloom
build/bin/bloom.json
*.deb
*.deb
src/Generated

View File

@@ -1,6 +1,9 @@
## Bloom
Bloom is a Linux-based debug platform for microcontrollers. This is the official repository for Bloom's source code.
For information on how to use Bloom, please visit https://bloom.oscillate.io.
** First Beta release to be published by end of April 2021 **
Bloom is a debug interface for embedded systems development on Linux. This is the official repository for Bloom's
source code. For information on how to use Bloom, please visit https://bloom.oscillate.io.
Bloom implements a number of user-space device drivers, enabling support for many debug tools (such as the Atmel-ICE,
Power Debugger, MPLAB SNAP* and the MPLAB PICkit 4*). Bloom exposes an interface to the connected target, via a GDB
@@ -27,21 +30,25 @@ Bloom is a multithreaded event-driven program written in C++. It consists of fou
The TargetController possesses full control of the connected debug tool and target. Execution of user-space
device drivers takes place here. All interaction with the connected hardware goes through the TargetController.
It exposes an interface to the connected hardware via events. The TargetController runs on a dedicated thread.
See source code in src/TargetController/ for more.
##### DebugServer
The DebugServer exposes an interface to the connected target, for third-party programs such as IDEs. Currently, Bloom
only supports one DebugServer - the GDB RSP server. With this server, any IDE with GDB RSP support can interface with
Bloom and thus the connected target. The DebugServer runs on a dedicated thread.
See source code in src/DebugServer/ for more.
##### Insight
Insight is a graphical user interface that provides insight of the target's GPIO pin states. It also enables GPIO
pin manipulation. Insight occupies Bloom's main thread and employs a single worker thread for background tasks.
Unlike other components within Bloom, Insight relies heavily on the Qt framework for its GUI capabilities and
other useful utilities.
See source code in src/Insight/ for more.
##### SignalHandler
The SignalHandler is responsible for handling any UNIX signals issued to Bloom. It runs on a dedicated thread. All
other threads within Bloom do not accept any UNIX signals.
See source code in src/SignalHandler/ for more.
#### Inter-component communication
The components described above interact with each other using an event-based mechanism.

View File

@@ -22,7 +22,7 @@ int Application::run(const std::vector<std::string>& arguments) {
if (!arguments.empty()) {
auto firstArg = arguments.front();
auto commandsToCallbackMapping = this->getCommandToCallbackMapping();
auto commandsToCallbackMapping = this->getCommandToHandlerMapping();
if (commandsToCallbackMapping.contains(firstArg)) {
// User has passed an argument that maps to a command callback - invoke the callback and shutdown

View File

@@ -22,6 +22,12 @@ namespace Bloom
{
using namespace DebugServers;
/**
* Bloom - a debug interface for embedded systems development on Linux.
*
* This is the main entry-point of execution for the Bloom program. The methods within will run on the main
* thread. If Insight is enabled, execution will be passed over to Insight::run() upon startup.
*/
class Application: public Thread
{
public:
@@ -38,25 +44,65 @@ namespace Bloom
EventManager eventManager = EventManager();
EventListenerPointer applicationEventListener = std::make_shared<EventListener>("ApplicationEventListener");
/**
* The SignalHandler deals with any UNIX signals. It runs on a dedicated thread. All other threads
* ignore UNIX signals.
*
* See the SignalHandler class for more on this.
*/
SignalHandler signalHandler = SignalHandler(this->eventManager);
std::thread signalHandlerThread;
/**
* The TargetController possesses full control of the connect debug tool and target. It runs on a
* dedicated thread.
*
* See the TargetController class for more on this.
*/
TargetController targetController = TargetController(this->eventManager);
std::thread targetControllerThread;
/**
* The DebugServer exposes an interface to the connected target, to third-party software such as IDEs. It runs
* on a dedicated thread.
*
* See the DebugServer and GdbRspDebugServer class for more on this.
*/
std::unique_ptr<DebugServer> debugServer = nullptr;
std::thread debugServerThread;
/**
* Insight is, effectively, a small Qt application that serves a GUI to the user. It occupies the main thread,
* as well as a single worker thread, and possibly other threads created by Qt.
*
* When the user closes the Insight GUI, control of the main thread is returned to Application::run(). How we
* deal with the GUI being closed at this point depends on user configuration.
*
* See the Insight class for more on this.
*/
Insight insight = Insight(this->eventManager);
/**
* Configuration extracted from the user's project configuration file.
*
* See ApplicationConfig.hpp for more on this.
*/
ApplicationConfig applicationConfig;
EnvironmentConfig environmentConfig;
DebugServerConfig debugServerConfig;
InsightConfig insightConfig;
std::optional<std::string> selectedEnvironmentName;
auto getCommandToCallbackMapping() {
/**
* Some CLI arguments are interpreted as commands and thus require specific handler methods to be called.
* This mapping maps command strings to the appropriate handler methods. The mapped handler method is invoked
* when the command is provided as an argument from the CLI.
*
* See Application::run() for more on this.
*
* @return
*/
auto getCommandToHandlerMapping() {
return std::map<std::string, std::function<int()>> {
{
"--help",
@@ -135,13 +181,27 @@ namespace Bloom
*/
void stopTargetController();
/**
* Prepares a dedicated thread for the DebugServer and kicks it off with a call to DebugServer::run().
*/
void startDebugServer();
/**
* Sends a shutdown request to the DebugServer thread and waits on it to exit.
*/
void stopDebugServer();
public:
explicit Application() = default;
/**
* This mapping is used to map debug server names from project configuration files to polymorphic instances of
* the DebugServer class.
*
* See Application::startDebugServer() for more on this.
*
* @return
*/
auto getSupportedDebugServers() {
return std::map<std::string, std::function<std::unique_ptr<DebugServer>()>> {
{
@@ -153,10 +213,34 @@ namespace Bloom
};
};
/**
* Main entry-point for the Bloom program.
*
* @param arguments
* A vector of string arguments passed from the user via the cli.
*
* @return
*/
int run(const std::vector<std::string>& arguments);
/**
* If the TargetController unexpectedly shuts down, the rest of the application will follow.
*
* @param event
*/
void handleTargetControllerStateChangedEvent(EventPointer<Events::TargetControllerStateChanged> event);
/**
* Same goes for the DebugServer - it should never shutdown unless a shutdown request was issued. If it does,
* something horrible has happened and so we shutdown the rest of the application in response.
*
* @param event
*/
void onDebugServerStateChanged(EventPointer<Events::DebugServerStateChanged> event);
/**
* Triggers a shutdown of Bloom and all of its components.
*/
void handleShutdownApplicationEvent(EventPointer<Events::ShutdownApplication>);
/**

View File

@@ -1,6 +1,6 @@
#include <src/Logger/Logger.hpp>
#include <src/Exceptions/InvalidConfig.hpp>
#include "ApplicationConfig.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/InvalidConfig.hpp"
using namespace Bloom;

View File

@@ -169,7 +169,7 @@ namespace Bloom::DebugServers
void removeBreakpointOnTarget(TargetBreakpoint breakpoint);
public:
DebugServer(EventManager& eventManager) : eventManager(eventManager) {};
DebugServer(EventManager& eventManager): eventManager(eventManager) {};
void setApplicationConfig(const ApplicationConfig& applicationConfig) {
this->applicationConfig = applicationConfig;

View File

@@ -112,7 +112,7 @@ namespace Bloom::DebugServers::Gdb
};
public:
AvrGdbRsp(EventManager& eventManager) : GdbRspDebugServer(eventManager) {};
AvrGdbRsp(EventManager& eventManager): GdbRspDebugServer(eventManager) {};
std::string getName() const override {
return "AVR GDB Remote Serial Protocol Debug Server";

View File

@@ -37,7 +37,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
class CommandPacket: public Packet
{
public:
CommandPacket(const std::vector<unsigned char>& rawPacket) : Packet(rawPacket) {}
CommandPacket(const std::vector<unsigned char>& rawPacket): Packet(rawPacket) {}
/**
* Double dispatches the packet to the appropriate overload of handleGdbPacket(), within the passed instance of

View File

@@ -29,7 +29,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
*/
std::optional<std::uint32_t> fromProgramCounter;
ContinueExecution(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
ContinueExecution(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
init();
};

View File

@@ -17,7 +17,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
class InterruptExecution: public CommandPacket
{
public:
InterruptExecution(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {};
InterruptExecution(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {};
virtual void dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) override;
};

View File

@@ -28,7 +28,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
*/
std::optional<int> registerNumber;
ReadGeneralRegisters(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
ReadGeneralRegisters(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
init();
};

View File

@@ -33,7 +33,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
*/
std::uint32_t bytes;
ReadMemory(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
ReadMemory(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
init();
};

View File

@@ -35,7 +35,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
*/
std::uint32_t address;
RemoveBreakpoint(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
RemoveBreakpoint(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
this->init();
};

View File

@@ -35,7 +35,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
*/
std::uint32_t address;
SetBreakpoint(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
SetBreakpoint(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
this->init();
};

View File

@@ -23,7 +23,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
*/
std::optional<size_t> fromProgramCounter;
StepExecution(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
StepExecution(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
init();
};

View File

@@ -29,7 +29,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
void init();
public:
SupportedFeaturesQuery(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
SupportedFeaturesQuery(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
this->init();
};

View File

@@ -25,7 +25,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
int registerNumber;
std::vector<unsigned char> registerValue;
WriteGeneralRegisters(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
WriteGeneralRegisters(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
init();
};

View File

@@ -29,7 +29,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
TargetMemoryBuffer buffer;
WriteMemory(std::vector<unsigned char> rawPacket) : CommandPacket(rawPacket) {
WriteMemory(std::vector<unsigned char> rawPacket): CommandPacket(rawPacket) {
init();
};

View File

@@ -15,11 +15,11 @@ namespace Bloom::DebugServers::Gdb::Exceptions
class ClientCommunicationError: public Exception
{
public:
explicit ClientCommunicationError(const std::string& message) : Exception(message) {
explicit ClientCommunicationError(const std::string& message): Exception(message) {
this->message = message;
}
explicit ClientCommunicationError(const char* message) : Exception(message) {
explicit ClientCommunicationError(const char* message): Exception(message) {
this->message = std::string(message);
}

View File

@@ -16,11 +16,11 @@ namespace Bloom::DebugServers::Gdb::Exceptions
class ClientDisconnected: public Exception
{
public:
explicit ClientDisconnected(const std::string& message) : Exception(message) {
explicit ClientDisconnected(const std::string& message): Exception(message) {
this->message = message;
}
explicit ClientDisconnected(const char* message) : Exception(message) {
explicit ClientDisconnected(const char* message): Exception(message) {
this->message = std::string(message);
}

View File

@@ -15,11 +15,11 @@ namespace Bloom::DebugServers::Gdb::Exceptions
class ClientNotSupported: public Exception
{
public:
explicit ClientNotSupported(const std::string& message) : Exception(message) {
explicit ClientNotSupported(const std::string& message): Exception(message) {
this->message = message;
}
explicit ClientNotSupported(const char* message) : Exception(message) {
explicit ClientNotSupported(const char* message): Exception(message) {
this->message = std::string(message);
}

View File

@@ -163,7 +163,7 @@ namespace Bloom::DebugServers::Gdb
}
public:
GdbRspDebugServer(EventManager& eventManager) : DebugServer(eventManager) {};
GdbRspDebugServer(EventManager& eventManager): DebugServer(eventManager) {};
std::string getName() const override {
return "GDB Remote Serial Protocol DebugServer";

View File

@@ -20,7 +20,7 @@ namespace Bloom::DebugServers::Gdb::ResponsePackets
std::optional<TargetRegisterMap> registerMap;
std::optional<StopReason> stopReason;
TargetStopped(Signal signal) : signal(signal) {}
TargetStopped(Signal signal): signal(signal) {}
std::vector<unsigned char> getData() const override {
std::string output = "T" + this->dataToHex({static_cast<unsigned char>(this->signal)});

View File

@@ -1,5 +1,3 @@
#include <stdexcept>
#include "AtmelIce.hpp"
#include "src/Exceptions/Exception.hpp"

View File

@@ -67,7 +67,7 @@ namespace Bloom::DebugToolDrivers
static const std::uint16_t USB_VENDOR_ID = 1003;
static const std::uint16_t USB_PRODUCT_ID = 8513;
AtmelIce() : UsbDevice(AtmelIce::USB_VENDOR_ID, AtmelIce::USB_PRODUCT_ID) {}
AtmelIce(): UsbDevice(AtmelIce::USB_VENDOR_ID, AtmelIce::USB_PRODUCT_ID) {}
void init() override;
void close() override;

View File

@@ -1,5 +1,3 @@
#include <stdexcept>
#include "PowerDebugger.hpp"
#include "src/Exceptions/Exception.hpp"

View File

@@ -59,7 +59,7 @@ namespace Bloom::DebugToolDrivers
static const std::uint16_t USB_VENDOR_ID = 1003;
static const std::uint16_t USB_PRODUCT_ID = 8516;
PowerDebugger() : UsbDevice(PowerDebugger::USB_VENDOR_ID, PowerDebugger::USB_PRODUCT_ID) {}
PowerDebugger(): UsbDevice(PowerDebugger::USB_VENDOR_ID, PowerDebugger::USB_PRODUCT_ID) {}
void init() override;
void close() override;

View File

@@ -1,24 +1,15 @@
#include <cstdint>
#include "src/Exceptions/Exception.hpp"
#include "Response.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
void Response::init(unsigned char* response, std::size_t length)
void Response::init(const std::vector<unsigned char>& rawResponse)
{
if (length == 0) {
if (rawResponse.size() < 1) {
throw Exceptions::Exception("Failed to process CMSIS-DAP response - invalid response");
}
this->setResponseId(response[0]);
std::vector<unsigned char> data = this->getData();
// TODO: use insert with iterators here
for (std::size_t i = 1; i < length; i++) {
data.push_back(response[i]);
}
this->setData(data);
this->setResponseId(rawResponse[0]);
this->setData(std::vector<unsigned char>(rawResponse.begin() + 1, rawResponse.end()));
}

View File

@@ -1,6 +1,5 @@
#pragma once
#include <cstdint>
#include <vector>
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
@@ -23,10 +22,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
public:
Response() = default;
virtual void init(unsigned char* response, std::size_t length);
virtual void init(std::vector<unsigned char> response) {
this->init(response.data(), response.size());
}
virtual void init(const std::vector<unsigned char>& rawResponse);
unsigned char getResponseId() const {
return this->responseId;

View File

@@ -16,9 +16,7 @@ std::vector<unsigned char> AvrCommand::getData() const
data[2] = (unsigned char) (commandPacketSize & 0xFF);
if (commandPacketSize > 0) {
for (std::size_t index = 0; index <= commandPacketSize - 1; index++) {
data[3 + index] = commandPacket[index];
}
data.insert(data.begin() + 3, commandPacket.begin(), commandPacket.end());
}
return data;

View File

@@ -1,21 +1,17 @@
#include <stdexcept>
#include <iostream>
#include "AvrEvent.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void AvrEvent::init(unsigned char* response, size_t length)
{
Response::init(response, length);
void AvrEvent::init(const std::vector<unsigned char>& rawResponse) {
Response::init(rawResponse);
if (this->getResponseId() != 0x82) {
throw Exception("Failed to construct AvrEvent object - invalid response ID.");
}
std::vector<unsigned char> responseData = this->getData();
auto& responseData = this->getData();
if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID)
@@ -32,7 +28,7 @@ void AvrEvent::init(unsigned char* response, size_t length)
"contained invalid event data size.");
}
std::vector<unsigned char> eventData;
auto eventData = std::vector<unsigned char>();
/*
* Ignore the SOF, protocol version &handler id and sequence ID (with all make up 5 bytes in total, 7 when

View File

@@ -45,10 +45,10 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
void init(const Response& response) {
auto rawData = response.getData();
rawData.insert(rawData.begin(), response.getResponseId());
this->init(rawData.data(), rawData.size());
this->init(rawData);
}
void init(unsigned char* response, size_t length) override;
void init(const std::vector<unsigned char>& rawResponse) override;
const std::vector<unsigned char>& getEventData() const {
return this->eventData;

View File

@@ -6,20 +6,19 @@
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void AvrResponse::init(unsigned char* response, std::size_t length)
{
Response::init(response, length);
void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
Response::init(rawResponse);
if (this->getResponseId() != 0x81) {
throw Exception("Failed to construct AvrResponse object - invalid response ID.");
}
std::vector<unsigned char> responseData = this->getData();
auto& responseData = this->getData();
if (responseData.empty()) {
// All AVR responses should contain at least one byte (the fragment info byte)
throw Exception("Failed to construct AvrResponse object - AVR_RSP response "
"returned no additional data");
"returned no additional data");
}
if (responseData[0] == 0x00) {

View File

@@ -39,10 +39,10 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
void init(const Response& response) {
auto rawData = response.getData();
rawData.insert(rawData.begin(), response.getResponseId());
this->init(rawData.data(), rawData.size());
this->init(rawData);
}
void init(unsigned char* response, std::size_t length) override;
void init(const std::vector<unsigned char>& rawResponse) override;
std::uint8_t getFragmentNumber() const {
return this->fragmentNumber;

View File

@@ -11,7 +11,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
ActivatePhysical() = default;
ActivatePhysical(bool reset) : reset(reset) {};
ActivatePhysical(bool reset): reset(reset) {};
void setReset(bool reset) {
this->reset = reset;

View File

@@ -11,7 +11,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
Attach() = default;
Attach(bool breakAfterAttach) : breakAfterAttach(breakAfterAttach) {};
Attach(bool breakAfterAttach): breakAfterAttach(breakAfterAttach) {};
void setBreadAfterAttach(bool breakAfterAttach) {
this->breakAfterAttach = breakAfterAttach;

View File

@@ -14,7 +14,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
ClearSoftwareBreakpoints() = default;
ClearSoftwareBreakpoints(const std::vector<std::uint32_t>& addresses) : addresses(addresses) {}
ClearSoftwareBreakpoints(const std::vector<std::uint32_t>& addresses): addresses(addresses) {}
void setAddresses(const std::vector<std::uint32_t>& addresses) {
this->addresses = addresses;

View File

@@ -19,7 +19,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
this->setParameter(parameter);
}
GetParameter(const Avr8EdbgParameter& parameter, std::uint8_t size) : GetParameter(parameter) {
GetParameter(const Avr8EdbgParameter& parameter, std::uint8_t size): GetParameter(parameter) {
this->setSize(size);
}

View File

@@ -11,7 +11,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
Reset() = default;
Reset(bool stopAtMainAddress) : stopAtMainAddress(stopAtMainAddress) {};
Reset(bool stopAtMainAddress): stopAtMainAddress(stopAtMainAddress) {};
void setStopAtMainAddress(bool stopAtMainAddress) {
this->stopAtMainAddress = stopAtMainAddress;

View File

@@ -14,7 +14,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
RunTo() = default;
RunTo(const std::uint32_t& address) : address(address) {}
RunTo(const std::uint32_t& address): address(address) {}
void setAddress(const std::uint32_t& address) {
this->address = address;

View File

@@ -19,11 +19,11 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
this->setParameter(parameter);
}
SetParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value) : SetParameter(parameter) {
SetParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value): SetParameter(parameter) {
this->setValue(value);
}
SetParameter(const Avr8EdbgParameter& parameter, unsigned char value) : SetParameter(parameter) {
SetParameter(const Avr8EdbgParameter& parameter, unsigned char value): SetParameter(parameter) {
this->setValue(value);
}

View File

@@ -14,7 +14,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
std::uint32_t programCounter = 0;
public:
SetProgramCounter(std::uint32_t programCounter) : programCounter(programCounter) {}
SetProgramCounter(std::uint32_t programCounter): programCounter(programCounter) {}
virtual std::vector<unsigned char> getPayload() const override {
/*

View File

@@ -14,7 +14,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
SetSoftwareBreakpoints() = default;
SetSoftwareBreakpoints(const std::vector<std::uint32_t>& addresses) : addresses(addresses) {}
SetSoftwareBreakpoints(const std::vector<std::uint32_t>& addresses): addresses(addresses) {}
void setAddresses(const std::vector<std::uint32_t>& addresses) {
this->addresses = addresses;

View File

@@ -14,7 +14,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
SetXmegaSoftwareBreakpoint() = default;
SetXmegaSoftwareBreakpoint(std::uint32_t address) : address(address) {}
SetXmegaSoftwareBreakpoint(std::uint32_t address): address(address) {}
void setAddress(std::uint32_t address) {
this->address = address;

View File

@@ -11,7 +11,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
public:
Stop() = default;
Stop(bool stopImmediately) : stopImmediately(stopImmediately) {};
Stop(bool stopImmediately): stopImmediately(stopImmediately) {};
void setStopImmediately(bool stopImmediately) {
this->stopImmediately = stopImmediately;

View File

@@ -1,7 +1,7 @@
#pragma once
#include <src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/ResponseFrames/DiscoveryResponseFrame.hpp>
#include "../AvrCommandFrame.hpp"
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/ResponseFrames/DiscoveryResponseFrame.hpp"
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Discovery
{

View File

@@ -25,9 +25,9 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
QueryContext context;
public:
Query() : DiscoveryCommandFrame() {}
Query(): DiscoveryCommandFrame() {}
Query(QueryContext context) : DiscoveryCommandFrame() {
Query(QueryContext context): DiscoveryCommandFrame() {
this->setContext(context);
}

View File

@@ -23,7 +23,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
}
public:
EndSession() : HouseKeepingCommandFrame() {
EndSession(): HouseKeepingCommandFrame() {
this->init();
}
};

View File

@@ -22,7 +22,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames
}
public:
StartSession() : HouseKeepingCommandFrame() {
StartSession(): HouseKeepingCommandFrame() {
this->init();
}
};

View File

@@ -5,6 +5,7 @@
#include "EdbgAvr8Interface.hpp"
#include "src/Exceptions/InvalidConfig.hpp"
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Exceptions/Avr8CommandFailure.hpp"
#include "src/Logger/Logger.hpp"
// Command frames
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/SetParameter.hpp"

View File

@@ -16,7 +16,6 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
using namespace DebugToolDrivers;
using namespace Targets;
using namespace Targets::Microchip::Avr;
using namespace Events;
using Protocols::CmsisDap::Edbg::EdbgInterface;
using Targets::Microchip::Avr::Avr8Bit::Family;

View File

@@ -60,11 +60,11 @@ namespace Bloom::Exceptions
});
public:
explicit Avr8CommandFailure(const std::string& message) : Exception(message) {
explicit Avr8CommandFailure(const std::string& message): Exception(message) {
this->message = message;
}
explicit Avr8CommandFailure(const char* message) : Exception(message) {
explicit Avr8CommandFailure(const char* message): Exception(message) {
this->message = std::string(message);
}

View File

@@ -7,7 +7,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::ResponseFrame
class Avr8GenericResponseFrame: public AvrResponseFrame
{
public:
Avr8GenericResponseFrame(const std::vector<AvrResponse>& AVRResponses) : AvrResponseFrame(AVRResponses) {}
Avr8GenericResponseFrame(const std::vector<AvrResponse>& AVRResponses): AvrResponseFrame(AVRResponses) {}
Avr8GenericResponseFrame() {}
/**

View File

@@ -10,7 +10,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::ResponseFrame
class GetDeviceId: public Avr8GenericResponseFrame
{
public:
GetDeviceId(const std::vector<AvrResponse>& AvrResponses) : Avr8GenericResponseFrame(AvrResponses) {}
GetDeviceId(const std::vector<AvrResponse>& AvrResponses): Avr8GenericResponseFrame(AvrResponses) {}
GetDeviceId() {}
TargetSignature extractSignature(Avr8PhysicalInterface physicalInterface) {

View File

@@ -12,7 +12,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::ResponseFrame
class GetProgramCounter: public Avr8GenericResponseFrame
{
public:
GetProgramCounter(const std::vector<AvrResponse>& AVRResponses) : Avr8GenericResponseFrame(AVRResponses) {}
GetProgramCounter(const std::vector<AvrResponse>& AVRResponses): Avr8GenericResponseFrame(AVRResponses) {}
GetProgramCounter() {}
std::uint32_t extractProgramCounter() {

View File

@@ -11,7 +11,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::ResponseFrame
class ReadMemory: public Avr8GenericResponseFrame
{
public:
ReadMemory(const std::vector<AvrResponse>& AVRResponses) : Avr8GenericResponseFrame(AVRResponses) {}
ReadMemory(const std::vector<AvrResponse>& AVRResponses): Avr8GenericResponseFrame(AVRResponses) {}
ReadMemory() {}
TargetMemoryBuffer getMemoryBuffer() {

View File

@@ -7,7 +7,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::ResponseFrame
class DiscoveryResponseFrame: public AvrResponseFrame
{
public:
DiscoveryResponseFrame(const std::vector<AvrResponse>& AVRResponses) : AvrResponseFrame(AVRResponses) {}
DiscoveryResponseFrame(const std::vector<AvrResponse>& AVRResponses): AvrResponseFrame(AVRResponses) {}
DiscoveryResponseFrame() {}
/**

View File

@@ -53,7 +53,7 @@ std::optional<Protocols::CmsisDap::Edbg::Avr::AvrEvent> EdbgInterface::requestAv
// This is an AVR_EVT response
auto avrEvent = Protocols::CmsisDap::Edbg::Avr::AvrEvent();
avrEvent.init(*cmsisResponse);
return avrEvent.getEventDataSize() > 0 ? std::optional(avrEvent) : std::nullopt;
return avrEvent.getEventDataSize() > 0 ? std::optional(avrEvent): std::nullopt;
} else {
throw Exception("Unexpected response to AvrEventCommand from device");
}

View File

@@ -1,10 +1,10 @@
#include <cstdint>
#include <string>
#include <stdexcept>
#include <src/Logger/Logger.hpp>
#include "hidapi.hpp"
#include "HidInterface.hpp"
#include "hidapi.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Exceptions/DeviceCommunicationFailure.hpp"

View File

@@ -75,8 +75,7 @@ namespace Bloom::Usb
public:
std::size_t getInputReportSize() {
return 512;
// return this->inputReportSize;
return this->inputReportSize;
}
/**

View File

@@ -80,7 +80,7 @@ namespace Bloom
std::vector<GenericEventPointer> getEvents();
public:
explicit EventListener(const std::string& name) : name(name) {};
explicit EventListener(const std::string& name): name(name) {};
void setId(size_t id) {
this->id = id;

View File

@@ -1,7 +1,7 @@
#pragma once
#include <src/Helpers/Thread.hpp>
#include "Event.hpp"
#include "src/Helpers/Thread.hpp"
namespace Bloom::Events
{
@@ -10,7 +10,7 @@ namespace Bloom::Events
private:
ThreadState state;
public:
DebugServerStateChanged(ThreadState state) : state(state) {};
DebugServerStateChanged(ThreadState state): state(state) {};
static inline const std::string name = "DebugServerStateChanged";

View File

@@ -10,7 +10,7 @@ namespace Bloom::Events
private:
ThreadState state;
public:
InsightStateChanged(ThreadState state) : state(state) {
InsightStateChanged(ThreadState state): state(state) {
};

View File

@@ -17,6 +17,6 @@ namespace Bloom::Events
}
ResumeTargetExecution() = default;
ResumeTargetExecution(std::uint32_t fromProgramCounter) : fromProgramCounter(fromProgramCounter) {};
ResumeTargetExecution(std::uint32_t fromProgramCounter): fromProgramCounter(fromProgramCounter) {};
};
}

View File

@@ -17,6 +17,6 @@ namespace Bloom::Events
}
StepTargetExecution() = default;
StepTargetExecution(std::uint32_t fromProgramCounter) : fromProgramCounter(fromProgramCounter) {};
StepTargetExecution(std::uint32_t fromProgramCounter): fromProgramCounter(fromProgramCounter) {};
};
}

View File

@@ -11,7 +11,7 @@ namespace Bloom::Events
private:
ThreadState state;
public:
TargetControllerStateChanged(ThreadState state) : state(state) {
TargetControllerStateChanged(ThreadState state): state(state) {
};

View File

@@ -1,7 +1,7 @@
#pragma once
#include <src/Exceptions/Exception.hpp>
#include "Event.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Bloom::Events
{

View File

@@ -20,6 +20,6 @@ namespace Bloom::Events
}
WriteRegistersToTarget() = default;
WriteRegistersToTarget(const TargetRegisters& registers) : registers(registers) {};
WriteRegistersToTarget(const TargetRegisters& registers): registers(registers) {};
};
}

View File

@@ -7,11 +7,11 @@ namespace Bloom::Exceptions
class DeviceCommunicationFailure: public Exception
{
public:
explicit DeviceCommunicationFailure(const std::string& message) : Exception(message) {
explicit DeviceCommunicationFailure(const std::string& message): Exception(message) {
this->message = message;
}
explicit DeviceCommunicationFailure(const char* message) : Exception(message) {
explicit DeviceCommunicationFailure(const char* message): Exception(message) {
this->message = std::string(message);
}
};

View File

@@ -1,6 +1,7 @@
#pragma once
#include <stdexcept>
namespace Bloom::Exceptions
{
class Exception: public std::runtime_error
@@ -9,13 +10,13 @@ namespace Bloom::Exceptions
std::string message;
public:
explicit Exception() : std::runtime_error("") {}
explicit Exception(): std::runtime_error("") {}
explicit Exception(const std::string& message) : std::runtime_error(message.c_str()) {
explicit Exception(const std::string& message): std::runtime_error(message.c_str()) {
this->message = message;
}
explicit Exception(const char* message) : std::runtime_error(message) {
explicit Exception(const char* message): std::runtime_error(message) {
this->message = std::string(message);
}

View File

@@ -6,11 +6,11 @@ namespace Bloom::Exceptions
class InvalidConfig: public Exception
{
public:
explicit InvalidConfig(const std::string& message) : Exception(message) {
explicit InvalidConfig(const std::string& message): Exception(message) {
this->message = message;
}
explicit InvalidConfig(const char* message) : Exception(message) {
explicit InvalidConfig(const char* message): Exception(message) {
this->message = std::string(message);
}
};

View File

@@ -6,11 +6,11 @@ namespace Bloom::Exceptions
class TargetControllerStartupFailure: public Exception
{
public:
explicit TargetControllerStartupFailure(const std::string& message) : Exception(message) {
explicit TargetControllerStartupFailure(const std::string& message): Exception(message) {
this->message = message;
}
explicit TargetControllerStartupFailure(const char* message) : Exception(message) {
explicit TargetControllerStartupFailure(const char* message): Exception(message) {
this->message = std::string(message);
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
#include <QtUiTools>
#include <src/Exceptions/Exception.hpp>
#include "AboutWindow.hpp"
#include "TargetWidgets/DIP/DualInlinePackageWidget.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Application.hpp"
using namespace Bloom;

View File

@@ -5,7 +5,6 @@
#include <QtUiTools/QtUiTools>
#include <memory>
#include <optional>
#include <src/Logger/Logger.hpp>
#include "AboutWindow.hpp"
#include "TargetWidgets/TargetPackageWidget.hpp"

View File

@@ -17,7 +17,7 @@ QMainWindow {
image-position: center;
}
#author-label {
#author-label, #os-link-label {
font-size: 14px;
color: #adadb1;

View File

@@ -1,13 +1,9 @@
#include <iostream>
#include <csignal>
#include <QtCore>
#include <experimental/filesystem>
#include <thread>
#include <src/Exceptions/Exception.hpp>
#include <src/EventManager/Events/ShutdownTargetController.hpp>
#include "src/Logger/Logger.hpp"
#include "SignalHandler.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom;

View File

@@ -1,10 +1,11 @@
#pragma once
#include <src/Helpers/Thread.hpp>
#include <src/EventManager/EventManager.hpp>
#include "src/Helpers/SyncSafe.hpp"
#include <csignal>
#include "src/Helpers/Thread.hpp"
#include "src/EventManager/EventManager.hpp"
#include "src/Helpers/SyncSafe.hpp"
namespace Bloom
{
class SignalHandler: public Thread
@@ -33,7 +34,7 @@ namespace Bloom
int shutdownSignalsReceived = 0;
public:
SignalHandler(EventManager& eventManager) : eventManager(eventManager) {};
SignalHandler(EventManager& eventManager): eventManager(eventManager) {};
/**
* Entry point for SignalHandler thread.

View File

@@ -39,13 +39,27 @@ namespace Bloom
ApplicationConfig applicationConfig;
EnvironmentConfig environmentConfig;
/**
* The TargetController should be the sole owner of the target and debugTool. They are constructed and
* destroyed within the TargetController. Under no circumstance should ownership of these resources be
* transferred to any other component within Bloom.
*/
std::unique_ptr<Targets::Target> target = nullptr;
std::unique_ptr<DebugTool> debugTool = nullptr;
EventManager& eventManager;
EventListenerPointer eventListener = std::make_shared<EventListener>("TargetControllerEventListener");
/**
* We keep record of the last known execution state of the target. When the connected target reports a
* different state to what's stored in lastTargetState, a state change (TargetExecutionStopped/TargetExecutionResumed)
* event is emitted.
*/
TargetState lastTargetState = TargetState::UNKNOWN;
/**
* Obtaining a TargetDescriptor for the connected target can be quite expensive. We cache it here.
*/
std::optional<TargetDescriptor> cachedTargetDescriptor;
/**
@@ -168,9 +182,15 @@ namespace Bloom
*/
void fireTargetEvents();
/**
* When the TargetController fails to handle an event, a TargetControllerErrorOccurred event is emitted, with
* a correlation ID matching the ID of the event that triggered the handler.
*
* @param correlationId
*/
void emitErrorEvent(int correlationId);
public:
TargetController(EventManager& eventManager) : eventManager(eventManager) {};
TargetController(EventManager& eventManager): eventManager(eventManager) {};
void setApplicationConfig(const ApplicationConfig& applicationConfig) {
this->applicationConfig = applicationConfig;
@@ -185,38 +205,128 @@ namespace Bloom
*/
void run();
/**
* Obtains a TargetDescriptor from the target and includes it in a TargetDescriptorExtracted event.
*
* @param event
*/
void onExtractTargetDescriptor(EventPointer<Events::ExtractTargetDescriptor> event);
/**
* Callback for StopTargetExecution event.
* Will attempt to stop execution on the target and emit a TargetExecutionStopped event.
*
* Will attempt to stop the target and emit a TargetExecutionStopped event.
* @param event
*/
void onStopTargetExecutionEvent(EventPointer<Events::StopTargetExecution> event);
/**
* Will attempt to step execution on the target and emit a TargetExecutionResumed event.
*
* @param event
*/
void onStepTargetExecutionEvent(EventPointer<Events::StepTargetExecution> event);
/**
* Callback for ResumeTargetExecution event.
* Will attempt to resume execution on the target and emit a TargetExecutionResumed event.
*
* @param event
*/
void onResumeTargetExecutionEvent(EventPointer<Events::ResumeTargetExecution> event);
/**
* Callback for ShutdownTargetController event.
* Invokes a shutdown.
*
* @param event
*/
void onShutdownTargetControllerEvent(EventPointer<Events::ShutdownTargetController> event);
/**
* Will attempt to read the requested registers and emit a RegistersRetrievedFromTarget event.
*
* @param event
*/
void onReadRegistersEvent(EventPointer<Events::RetrieveRegistersFromTarget> event);
/**
* Will attempt to write the specified register values and emit a RegistersWrittenToTarget event.
*
* @param event
*/
void onWriteRegistersEvent(EventPointer<Events::WriteRegistersToTarget> event);
/**
* Will attempt to read memory from the target and include the data in a MemoryRetrievedFromTarget event.
*
* @param event
*/
void onReadMemoryEvent(EventPointer<Events::RetrieveMemoryFromTarget> event);
/**
* Will attempt to write memory to the target. On success, a MemoryWrittenToTarget event is emitted.
*
* @param event
*/
void onWriteMemoryEvent(EventPointer<Events::WriteMemoryToTarget> event);
/**
* Will attempt to set the specific breakpoint on the target. On success, the BreakpointSetOnTarget event will
* be emitted.
*
* @param event
*/
void onSetBreakpointEvent(EventPointer<Events::SetBreakpointOnTarget> event);
/**
* Will attempt to remove a breakpoint at the specified address, on the target. On success, the
* BreakpointRemovedOnTarget event is emitted.
*
* @param event
*/
void onRemoveBreakpointEvent(EventPointer<Events::RemoveBreakpointOnTarget> event);
/**
* Will hold the target stopped at it's current state.
*
* @param event
*/
void onDebugSessionStartedEvent(EventPointer<Events::DebugSessionStarted> event);
/**
* Will simply kick off execution on the target.
*
* @param event
*/
void onDebugSessionFinishedEvent(EventPointer<Events::DebugSessionFinished> event);
/**
* Will update the program counter value on the target. On success, a ProgramCounterSetOnTarget event is
* emitted.
*
* @param event
*/
void onSetProgramCounterEvent(EventPointer<Events::SetProgramCounterOnTarget> event);
/**
* Will automatically fire a target state update event.
* @TODO: get rid of this - Insight should request this itself.
*
* @param event
*/
void onInsightStateChangedEvent(EventPointer<Events::InsightStateChanged> event);
/**
* Will attempt to obtain the pin states from the target. Will emit a TargetPinStatesRetrieved event on success.
*
* @param event
*/
void onRetrieveTargetPinStatesEvent(EventPointer<Events::RetrieveTargetPinStates> event);
/**
* Will update a pin state for a particular pin. Will emit a TargetPinStatesRetrieved with the new pin
* state, on success.
*
* @param event
*/
void onSetPinStateEvent(EventPointer<Events::SetTargetPinState> event);
};
}

View File

@@ -9,7 +9,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
protected:
public:
Mega(const Avr8& avr8) : Avr8(avr8) {};
Mega(const Avr8& avr8): Avr8(avr8) {};
virtual bool supportsPromotion() override {
return false;

View File

@@ -7,7 +7,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
class Tiny: public Avr8
{
public:
Tiny(const Avr8& avr8) : Avr8(avr8) {};
Tiny(const Avr8& avr8): Avr8(avr8) {};
virtual bool supportsPromotion() override {
return false;

View File

@@ -7,7 +7,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
class XMega: public Avr8
{
public:
XMega(const Avr8& avr8) : Avr8(avr8) {};
XMega(const Avr8& avr8): Avr8(avr8) {};
virtual bool supportsPromotion() override {
return false;

View File

@@ -1,6 +1,5 @@
#pragma once
#include <src/Logger/Logger.hpp>
#include <sstream>
#include <iomanip>
@@ -14,16 +13,6 @@ namespace Bloom::Targets::Microchip::Avr
protected:
std::optional<TargetSignature> id;
virtual void setId(unsigned char byteZero, unsigned char byteOne, unsigned char byteTwo) {
if (!this->id.has_value()) {
this->id = TargetSignature();
}
this->id->byteZero = byteZero;
this->id->byteOne = byteOne;
this->id->byteTwo = byteTwo;
}
virtual void setId(const TargetSignature& id) {
this->id = id;
}

View File

@@ -4,7 +4,6 @@
#include <string>
#include <vector>
#include <memory>
#include <src/EventManager/Events/Event.hpp>
#include <set>
#include <map>
@@ -18,8 +17,6 @@
namespace Bloom::Targets
{
using namespace Events;
class Target
{
protected:

View File

@@ -1,5 +1,5 @@
#pragma once
#include <src/Targets/Target.hpp>
#include <src/Targets/Microchip/AVR/Target.hpp>
#include <src/Targets/Microchip/AVR/AVR8/Avr8.hpp>
#include "src/Targets/Target.hpp"
#include "src/Targets/Microchip/AVR/Target.hpp"
#include "src/Targets/Microchip/AVR/AVR8/Avr8.hpp"