Removed using namespace directive for class member function definitions in source files

This commit is contained in:
Nav
2022-02-05 15:32:08 +00:00
parent 9bbc534973
commit 53a3c815d7
116 changed files with 13113 additions and 12664 deletions

View File

@@ -11,11 +11,11 @@
#include "src/Helpers/Paths.hpp"
#include "Exceptions/InvalidConfig.hpp"
using namespace Bloom;
using namespace Bloom::Events;
using namespace Bloom::Exceptions;
namespace Bloom
{
using namespace Exceptions;
int Application::run(const std::vector<std::string>& arguments) {
int Application::run(const std::vector<std::string>& arguments) {
try {
this->setName("Bloom");
@@ -70,22 +70,24 @@ int Application::run(const std::vector<std::string>& arguments) {
this->applicationEventListener->waitAndDispatch();
}
} catch (const InvalidConfig& exception) {
}
catch (const InvalidConfig& exception) {
Logger::error(exception.getMessage());
} catch (const Exception& exception) {
}
catch (const Exception& exception) {
Logger::error(exception.getMessage());
}
this->shutdown();
return EXIT_SUCCESS;
}
}
bool Application::isRunningAsRoot() {
bool Application::isRunningAsRoot() {
return geteuid() == 0;
}
}
void Application::startup() {
void Application::startup() {
auto applicationEventListener = this->applicationEventListener;
this->eventManager.registerListener(applicationEventListener);
applicationEventListener->registerCallbackForEventType<Events::ShutdownApplication>(
@@ -117,9 +119,9 @@ void Application::startup() {
this->startDebugServer();
Thread::setThreadState(ThreadState::READY);
}
}
void Application::shutdown() {
void Application::shutdown() {
auto appState = Thread::getThreadState();
if (appState == ThreadState::STOPPED || appState == ThreadState::SHUTDOWN_INITIATED) {
return;
@@ -134,9 +136,9 @@ void Application::shutdown() {
this->saveProjectSettings();
Thread::setThreadState(ThreadState::STOPPED);
}
}
void Application::loadProjectSettings() {
void Application::loadProjectSettings() {
const auto projectSettingsPath = Paths::projectSettingsPath();
auto jsonSettingsFile = QFile(QString::fromStdString(projectSettingsPath));
@@ -152,7 +154,8 @@ void Application::loadProjectSettings() {
this->projectSettings = ProjectSettings(jsonObject);
return;
} catch (const std::exception& exception) {
}
catch (const std::exception& exception) {
Logger::error(
"Failed to load project settings from " + projectSettingsPath + " - " + exception.what()
);
@@ -160,9 +163,9 @@ void Application::loadProjectSettings() {
}
this->projectSettings = ProjectSettings();
}
}
void Application::saveProjectSettings() {
void Application::saveProjectSettings() {
if (!this->projectSettings.has_value()) {
return;
}
@@ -186,14 +189,15 @@ void Application::saveProjectSettings() {
jsonSettingsFile.write(jsonDocument.toJson());
jsonSettingsFile.close();
} catch (const Exception& exception) {
}
catch (const Exception& exception) {
Logger::error(
"Failed to save project settings - " + exception.getMessage()
);
}
}
}
void Application::loadProjectConfiguration() {
void Application::loadProjectConfiguration() {
auto jsonConfigFile = QFile(QString::fromStdString(Paths::projectConfigPath()));
if (!jsonConfigFile.exists()) {
@@ -223,25 +227,29 @@ void Application::loadProjectConfiguration() {
if (this->environmentConfig->insightConfig.has_value()) {
this->insightConfig = this->environmentConfig->insightConfig.value();
} else if (this->projectConfig->insightConfig.has_value()) {
}
else if (this->projectConfig->insightConfig.has_value()) {
this->insightConfig = this->projectConfig->insightConfig.value();
} else {
}
else {
throw InvalidConfig("Insight configuration missing.");
}
if (this->environmentConfig->debugServerConfig.has_value()) {
this->debugServerConfig = this->environmentConfig->debugServerConfig.value();
} else if (this->projectConfig->debugServerConfig.has_value()) {
}
else if (this->projectConfig->debugServerConfig.has_value()) {
this->debugServerConfig = this->projectConfig->debugServerConfig.value();
} else {
}
else {
throw InvalidConfig("Debug server configuration missing.");
}
}
}
int Application::presentHelpText() {
int Application::presentHelpText() {
/*
* Silence all logging here, as we're just to display the help text and then exit the application. Any
* further logging will just be noise.
@@ -258,16 +266,17 @@ int Application::presentHelpText() {
if (!helpFile.open(QIODevice::ReadOnly)) {
// This should never happen - if it does, something has gone very wrong
throw Exception(
"Failed to open help file - please report this issue at " + Paths::homeDomainName() + "/report-issue"
"Failed to open help file - please report this issue at " + Paths::homeDomainName()
+ "/report-issue"
);
}
std::cout << "Bloom v" << Application::VERSION.toString() << "\n";
std::cout << QTextStream(&helpFile).readAll().toUtf8().constData() << "\n";
return EXIT_SUCCESS;
}
}
int Application::presentVersionText() {
int Application::presentVersionText() {
Logger::silence();
std::cout << "Bloom v" << Application::VERSION.toString() << "\n";
@@ -279,10 +288,12 @@ int Application::presentVersionText() {
std::cout << Paths::homeDomainName() + "/\n";
std::cout << "Nav Mohammed\n";
return EXIT_SUCCESS;
}
}
int Application::initProject() {
auto configFile = QFile(QString::fromStdString(std::filesystem::current_path().string() + "/bloom.json"));
int Application::initProject() {
auto configFile = QFile(
QString::fromStdString(std::filesystem::current_path().string() + "/bloom.json")
);
if (configFile.exists()) {
throw Exception("Bloom configuration file (bloom.json) already exists in working directory.");
@@ -294,10 +305,8 @@ int Application::initProject() {
*
* We simply copy the template file into the user's working directory.
*/
auto templateConfigFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/resources/bloom.template.json"
)
auto templateConfigFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()+ "/resources/bloom.template.json")
);
if (!templateConfigFile.open(QIODevice::ReadOnly)) {
@@ -318,21 +327,21 @@ int Application::initProject() {
Logger::info("Bloom configuration file (bloom.json) created in working directory.");
return EXIT_SUCCESS;
}
}
void Application::startSignalHandler() {
void Application::startSignalHandler() {
this->signalHandlerThread = std::thread(&SignalHandler::run, std::ref(this->signalHandler));
}
}
void Application::stopSignalHandler() {
void Application::stopSignalHandler() {
if (this->signalHandler.getThreadState() != ThreadState::STOPPED
&& this->signalHandler.getThreadState() != ThreadState::UNINITIALISED
) {
this->signalHandler.triggerShutdown();
/*
* Send meaningless signal to the SignalHandler thread to have it shutdown. The signal will pull it out of a
* blocking state and allow it to action the shutdown. See SignalHandler::run() for more.
* Send meaningless signal to the SignalHandler thread to have it shutdown. The signal will pull it out of
* a blocking state and allow it to action the shutdown. See SignalHandler::run() for more.
*/
pthread_kill(this->signalHandlerThread.native_handle(), SIGUSR1);
}
@@ -342,9 +351,9 @@ void Application::stopSignalHandler() {
this->signalHandlerThread.join();
Logger::debug("SignalHandler thread joined");
}
}
}
void Application::startTargetController() {
void Application::startTargetController() {
this->targetController = std::make_unique<TargetController>(
this->eventManager,
this->projectConfig.value(),
@@ -356,14 +365,15 @@ void Application::startTargetController() {
this->targetController.get()
);
auto tcStateChangeEvent = this->applicationEventListener->waitForEvent<Events::TargetControllerThreadStateChanged>();
auto tcStateChangeEvent =
this->applicationEventListener->waitForEvent<Events::TargetControllerThreadStateChanged>();
if (!tcStateChangeEvent.has_value() || tcStateChangeEvent->get()->getState() != ThreadState::READY) {
throw Exception("TargetController failed to startup.");
}
}
}
void Application::stopTargetController() {
void Application::stopTargetController() {
if (this->targetController == nullptr) {
return;
}
@@ -381,12 +391,14 @@ void Application::stopTargetController() {
this->targetControllerThread.join();
Logger::debug("TargetController thread joined");
}
}
}
void Application::startDebugServer() {
void Application::startDebugServer() {
auto supportedDebugServers = this->getSupportedDebugServers();
if (!supportedDebugServers.contains(this->debugServerConfig->name)) {
throw Exceptions::InvalidConfig("DebugServer \"" + this->debugServerConfig->name + "\" not found.");
throw Exceptions::InvalidConfig(
"DebugServer \"" + this->debugServerConfig->name + "\" not found."
);
}
this->debugServer = supportedDebugServers.at(this->debugServerConfig->name)();
@@ -402,9 +414,9 @@ void Application::startDebugServer() {
if (!dsStateChangeEvent.has_value() || dsStateChangeEvent->get()->getState() != ThreadState::READY) {
throw Exception("DebugServer failed to startup.");
}
}
}
void Application::stopDebugServer() {
void Application::stopDebugServer() {
if (this->debugServer == nullptr) {
// DebugServer hasn't been resolved yet.
return;
@@ -423,23 +435,24 @@ void Application::stopDebugServer() {
this->debugServerThread.join();
Logger::debug("DebugServer thread joined");
}
}
}
void Application::onTargetControllerThreadStateChanged(const Events::TargetControllerThreadStateChanged& event) {
void Application::onTargetControllerThreadStateChanged(const Events::TargetControllerThreadStateChanged& event) {
if (event.getState() == ThreadState::STOPPED || event.getState() == ThreadState::SHUTDOWN_INITIATED) {
// TargetController has unexpectedly shutdown - it must have encountered a fatal error.
this->shutdown();
}
}
}
void Application::onShutdownApplicationRequest(const Events::ShutdownApplication&) {
void Application::onShutdownApplicationRequest(const Events::ShutdownApplication&) {
Logger::debug("ShutdownApplication event received.");
this->shutdown();
}
}
void Application::onDebugServerThreadStateChanged(const Events::DebugServerThreadStateChanged& event) {
void Application::onDebugServerThreadStateChanged(const Events::DebugServerThreadStateChanged& event) {
if (event.getState() == ThreadState::STOPPED || event.getState() == ThreadState::SHUTDOWN_INITIATED) {
// DebugServer has unexpectedly shutdown - it must have encountered a fatal error.
this->shutdown();
}
}
}

View File

@@ -5,10 +5,11 @@
#include "src/Exceptions/InvalidConfig.hpp"
#include "src/Logger/Logger.hpp"
using namespace Bloom::DebugServers;
using namespace Bloom::Events;
namespace Bloom::DebugServers
{
using namespace Bloom::Events;
void DebugServer::run() {
void DebugServer::run() {
try {
this->startup();
@@ -23,9 +24,9 @@ void DebugServer::run() {
}
this->shutdown();
}
}
void DebugServer::startup() {
void DebugServer::startup() {
this->setName("DS");
Logger::info("Starting DebugServer");
@@ -43,10 +44,12 @@ void DebugServer::startup() {
this->init();
this->setThreadStateAndEmitEvent(ThreadState::READY);
}
}
void DebugServer::shutdown() {
if (this->getThreadState() == ThreadState::STOPPED || this->getThreadState() == ThreadState::SHUTDOWN_INITIATED) {
void DebugServer::shutdown() {
if (this->getThreadState() == ThreadState::STOPPED
|| this->getThreadState() == ThreadState::SHUTDOWN_INITIATED
) {
return;
}
@@ -55,8 +58,9 @@ void DebugServer::shutdown() {
this->close();
this->setThreadStateAndEmitEvent(ThreadState::STOPPED);
this->eventManager.deregisterListener(this->eventListener->getId());
}
}
void DebugServer::onShutdownDebugServerEvent(const Events::ShutdownDebugServer& event) {
void DebugServer::onShutdownDebugServerEvent(const Events::ShutdownDebugServer& event) {
this->shutdown();
}
}

View File

@@ -2,19 +2,20 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugServers::Gdb;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterType;
void AvrGdbRsp::init() {
void AvrGdbRsp::init() {
this->loadRegisterMappings();
GdbRspDebugServer::init();
}
}
void AvrGdbRsp::loadRegisterMappings() {
void AvrGdbRsp::loadRegisterMappings() {
auto& registerDescriptorsByType = this->targetDescriptor.registerDescriptorsByType;
if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) {
throw Exception("Missing status register descriptor");
@@ -41,7 +42,9 @@ void AvrGdbRsp::loadRegisterMappings() {
* we're assuming that the registers will be laid out in the correct order, in memory. I think this assumption is
* fair.
*/
const auto& gpRegisterDescriptors = registerDescriptorsByType.at(TargetRegisterType::GENERAL_PURPOSE_REGISTER);
const auto& gpRegisterDescriptors = registerDescriptorsByType.at(
TargetRegisterType::GENERAL_PURPOSE_REGISTER
);
// General purpose CPU registers
GdbRegisterNumberType regNumber = 0;
@@ -81,7 +84,9 @@ void AvrGdbRsp::loadRegisterMappings() {
"Stack Pointer Register"
);
this->registerDescriptorsByGdbNumber.insert(std::pair(stackPointerDescriptor.number, stackPointerDescriptor));
this->registerDescriptorsByGdbNumber.insert(
std::pair(stackPointerDescriptor.number, stackPointerDescriptor)
);
this->targetRegisterDescriptorsByGdbNumber.insert(std::pair(
stackPointerDescriptor.number,
*(registerDescriptorsByType.at(TargetRegisterType::STACK_POINTER).begin())
@@ -110,31 +115,34 @@ void AvrGdbRsp::loadRegisterMappings() {
throw Exception("AVR8 stack pointer target register size exceeds the GDB register size.");
}
if (registerDescriptorsByType.at(TargetRegisterType::PROGRAM_COUNTER).size() > programCounterDescriptor.size) {
if (
registerDescriptorsByType.at(TargetRegisterType::PROGRAM_COUNTER).size() > programCounterDescriptor.size
) {
throw Exception("AVR8 program counter size exceeds the GDB register size.");
}
}
}
std::optional<GdbRegisterNumberType> AvrGdbRsp::getRegisterNumberFromTargetRegisterDescriptor(
std::optional<GdbRegisterNumberType> AvrGdbRsp::getRegisterNumberFromTargetRegisterDescriptor(
const Targets::TargetRegisterDescriptor& registerDescriptor
) {
) {
return this->targetRegisterDescriptorsByGdbNumber.valueAt(registerDescriptor);
}
}
const RegisterDescriptor& AvrGdbRsp::getRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
const RegisterDescriptor& AvrGdbRsp::getRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
if (this->registerDescriptorsByGdbNumber.contains(number)) {
return this->registerDescriptorsByGdbNumber.at(number);
}
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
+ ") not mapped to any GDB register descriptor.");
}
}
const TargetRegisterDescriptor& AvrGdbRsp::getTargetRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
const TargetRegisterDescriptor& AvrGdbRsp::getTargetRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
if (this->targetRegisterDescriptorsByGdbNumber.contains(number)) {
return this->targetRegisterDescriptorsByGdbNumber.at(number);
}
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
+ ") not mapped to any target register descriptor.");
}
}

View File

@@ -2,8 +2,9 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void CommandPacket::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void CommandPacket::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}

View File

@@ -4,10 +4,13 @@
#include <memory>
#include <map>
using namespace Bloom::DebugServers::Gdb;
using namespace Bloom::DebugServers::Gdb::CommandPackets;
namespace Bloom::DebugServers::Gdb
{
using CommandPackets::CommandPacket;
std::vector<std::vector<unsigned char>> CommandPacketFactory::extractRawPackets(std::vector<unsigned char> buffer) {
std::vector<std::vector<unsigned char>> CommandPacketFactory::extractRawPackets(
std::vector<unsigned char> buffer
) {
std::vector<std::vector<unsigned char>> output;
std::size_t bufferIndex;
@@ -81,9 +84,9 @@ std::vector<std::vector<unsigned char>> CommandPacketFactory::extractRawPackets(
}
return output;
}
}
std::unique_ptr<CommandPacket> CommandPacketFactory::create(std::vector<unsigned char> rawPacket) {
std::unique_ptr<CommandPacket> CommandPacketFactory::create(std::vector<unsigned char> rawPacket) {
if (rawPacket.size() == 5 && rawPacket[1] == 0x03) {
// This is an interrupt request - create a fake packet for it
return std::make_unique<CommandPackets::InterruptExecution>(rawPacket);
@@ -98,32 +101,41 @@ std::unique_ptr<CommandPacket> CommandPacketFactory::create(std::vector<unsigned
*/
if (rawPacketString.find("qSupported") == 1) {
return std::make_unique<CommandPackets::SupportedFeaturesQuery>(rawPacket);
}
} else if (rawPacketString[1] == 'g' || rawPacketString[1] == 'p') {
if (rawPacketString[1] == 'g' || rawPacketString[1] == 'p') {
return std::make_unique<CommandPackets::ReadRegisters>(rawPacket);
}
} else if (rawPacketString[1] == 'P') {
if (rawPacketString[1] == 'P') {
return std::make_unique<CommandPackets::WriteRegister>(rawPacket);
}
} else if (rawPacketString[1] == 'c') {
if (rawPacketString[1] == 'c') {
return std::make_unique<CommandPackets::ContinueExecution>(rawPacket);
}
} else if (rawPacketString[1] == 's') {
if (rawPacketString[1] == 's') {
return std::make_unique<CommandPackets::StepExecution>(rawPacket);
}
} else if (rawPacketString[1] == 'm') {
if (rawPacketString[1] == 'm') {
return std::make_unique<CommandPackets::ReadMemory>(rawPacket);
}
} else if (rawPacketString[1] == 'M') {
if (rawPacketString[1] == 'M') {
return std::make_unique<CommandPackets::WriteMemory>(rawPacket);
}
} else if (rawPacketString[1] == 'Z') {
if (rawPacketString[1] == 'Z') {
return std::make_unique<CommandPackets::SetBreakpoint>(rawPacket);
}
} else if (rawPacketString[1] == 'z') {
if (rawPacketString[1] == 'z') {
return std::make_unique<CommandPackets::RemoveBreakpoint>(rawPacket);
}
}
return std::make_unique<CommandPacket>(rawPacket);
}
}

View File

@@ -4,16 +4,17 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void ContinueExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void ContinueExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void ContinueExecution::init() {
void ContinueExecution::init() {
if (this->data.size() > 1) {
this->fromProgramCounter = static_cast<std::uint32_t>(
std::stoi(std::string(this->data.begin(), this->data.end()), nullptr, 16)
);
}
}
}

View File

@@ -2,8 +2,9 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void InterruptExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void InterruptExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}

View File

@@ -2,14 +2,15 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void ReadMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
void ReadMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void ReadMemory::init() {
void ReadMemory::init() {
if (this->data.size() < 4) {
throw Exception("Invalid packet length");
}
@@ -26,7 +27,9 @@ void ReadMemory::init() {
auto packetSegments = packetString.split(",");
if (packetSegments.size() != 2) {
throw Exception("Unexpected number of segments in packet data: " + std::to_string(packetSegments.size()));
throw Exception(
"Unexpected number of segments in packet data: " + std::to_string(packetSegments.size())
);
}
bool conversionStatus = false;
@@ -41,4 +44,5 @@ void ReadMemory::init() {
if (!conversionStatus) {
throw Exception("Failed to parse read length from read memory packet data");
}
}
}

View File

@@ -2,15 +2,18 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void ReadRegisters::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void ReadRegisters::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void ReadRegisters::init() {
void ReadRegisters::init() {
if (this->data.size() >= 2 && this->data.front() == 'p') {
// This command packet is requesting a specific register
this->registerNumber = static_cast<size_t>(std::stoi(std::string(this->data.begin() + 1, this->data.end())));
this->registerNumber = static_cast<size_t>(
std::stoi(std::string(this->data.begin() + 1, this->data.end()))
);
}
}
}

View File

@@ -4,14 +4,15 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void RemoveBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
void RemoveBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void RemoveBreakpoint::init() {
void RemoveBreakpoint::init() {
if (data.size() < 6) {
throw Exception("Unexpected RemoveBreakpoint packet size");
}
@@ -36,4 +37,5 @@ void RemoveBreakpoint::init() {
if (!conversionStatus) {
throw Exception("Failed to convert address hex value from RemoveBreakpoint packet.");
}
}
}

View File

@@ -1,18 +1,18 @@
#include "SetBreakpoint.hpp"
#include <QtCore/QString>
#include <QtCore/QStringList>
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void SetBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
void SetBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void SetBreakpoint::init() {
void SetBreakpoint::init() {
if (data.size() < 6) {
throw Exception("Unexpected SetBreakpoint packet size");
}
@@ -37,4 +37,5 @@ void SetBreakpoint::init() {
if (!conversionStatus) {
throw Exception("Failed to convert address hex value from SetBreakpoint packet.");
}
}
}

View File

@@ -1,18 +1,20 @@
#include "StepExecution.hpp"
#include <cstdint>
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
#include "StepExecution.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void StepExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void StepExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void StepExecution::init() {
void StepExecution::init() {
if (this->data.size() > 1) {
this->fromProgramCounter = static_cast<std::uint32_t>(
std::stoi(std::string(this->data.begin(), this->data.end()), nullptr, 16)
);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
/**
* The address from which to begin the step.
*/
std::optional<size_t> fromProgramCounter;
std::optional<std::size_t> fromProgramCounter;
explicit StepExecution(const std::vector<unsigned char>& rawPacket): CommandPacket(rawPacket) {
init();

View File

@@ -4,13 +4,13 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void SupportedFeaturesQuery::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void SupportedFeaturesQuery::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void SupportedFeaturesQuery::init() {
void SupportedFeaturesQuery::init() {
/*
* For qSupported packets, supported and unsupported GDB features are reported in the packet
* data, where each GDB feature is separated by a semicolon.
@@ -40,4 +40,5 @@ void SupportedFeaturesQuery::init() {
}
}
}
}
}

View File

@@ -2,14 +2,15 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void WriteMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
void WriteMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void WriteMemory::init() {
void WriteMemory::init() {
if (this->data.size() < 4) {
throw Exception("Invalid packet length");
}
@@ -25,7 +26,9 @@ void WriteMemory::init() {
*/
auto packetSegments = packetString.split(",");
if (packetSegments.size() != 2) {
throw Exception("Unexpected number of segments in packet data: " + std::to_string(packetSegments.size()));
throw Exception(
"Unexpected number of segments in packet data: " + std::to_string(packetSegments.size())
);
}
bool conversionStatus = false;
@@ -37,7 +40,10 @@ void WriteMemory::init() {
auto lengthAndBufferSegments = packetSegments.at(1).split(":");
if (lengthAndBufferSegments.size() != 2) {
throw Exception("Unexpected number of segments in packet data: " + std::to_string(lengthAndBufferSegments.size()));
throw Exception(
"Unexpected number of segments in packet data: "
+ std::to_string(lengthAndBufferSegments.size())
);
}
auto bufferSize = lengthAndBufferSegments.at(0).toUInt(&conversionStatus, 16);
@@ -50,4 +56,5 @@ void WriteMemory::init() {
if (this->buffer.size() != bufferSize) {
throw Exception("Buffer size does not match length value given in write memory packet");
}
}
}

View File

@@ -3,14 +3,15 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void WriteRegister::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
void WriteRegister::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}
void WriteRegister::init() {
void WriteRegister::init() {
// The P packet updates a single register
auto packet = std::string(this->data.begin(), this->data.end());
@@ -26,4 +27,5 @@ void WriteRegister::init() {
this->registerNumber = static_cast<int>(packetSegments.front().mid(1).toUInt(nullptr, 16));
this->registerValue = Packet::hexToData(packetSegments.back().toStdString());
std::reverse(this->registerValue.begin(), this->registerValue.end());
}
}

View File

@@ -14,19 +14,20 @@
#include "src/Logger/Logger.hpp"
using namespace Bloom::DebugServers::Gdb;
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::DebugServers::Gdb::ResponsePackets;
using namespace Bloom::DebugServers::Gdb::Exceptions;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb
{
using namespace CommandPackets;
using namespace ResponsePackets;
using namespace Exceptions;
using namespace Bloom::Exceptions;
void Connection::accept(int serverSocketFileDescriptor) {
void Connection::accept(int serverSocketFileDescriptor) {
int socketAddressLength = sizeof(this->socketAddress);
this->socketFileDescriptor = ::accept(
serverSocketFileDescriptor,
(sockaddr*)& (this->socketAddress),
(socklen_t*)& socketAddressLength
(sockaddr*) &(this->socketAddress),
(socklen_t*) &socketAddressLength
);
if (this->socketFileDescriptor == -1) {
@@ -46,23 +47,26 @@ void Connection::accept(int serverSocketFileDescriptor) {
event.data.fd = this->socketFileDescriptor;
if (::epoll_ctl(this->eventFileDescriptor, EPOLL_CTL_ADD, this->socketFileDescriptor, &event) != 0) {
throw Exception("Failed to create event FD for GDB client connection - could not add client connection "
"socket FD to epoll FD");
throw Exception(
"Failed to create event FD for GDB client connection - could not add client connection "
"socket FD to epoll FD"
);
}
this->enableReadInterrupts();
}
}
void Connection::close() noexcept {
void Connection::close() noexcept {
if (this->socketFileDescriptor > 0) {
::close(this->socketFileDescriptor);
this->socketFileDescriptor = 0;
}
}
}
std::vector<std::unique_ptr<CommandPacket>> Connection::readPackets() {
std::vector<std::unique_ptr<CommandPacket>> Connection::readPackets() {
auto buffer = this->read();
Logger::debug("GDB client data received (" + std::to_string(buffer.size()) + " bytes): " + std::string(buffer.begin(), buffer.end()));
Logger::debug("GDB client data received (" + std::to_string(buffer.size()) + " bytes): "
+ std::string(buffer.begin(), buffer.end()));
auto rawPackets = CommandPacketFactory::extractRawPackets(buffer);
std::vector<std::unique_ptr<CommandPacket>> output;
@@ -82,9 +86,9 @@ std::vector<std::unique_ptr<CommandPacket>> Connection::readPackets() {
}
return output;
}
}
void Connection::writePacket(const ResponsePacket& packet) {
void Connection::writePacket(const ResponsePacket& packet) {
// Write the packet repeatedly until the GDB client acknowledges it.
int attempts = 0;
auto rawPacket = packet.toRawPacket();
@@ -97,11 +101,10 @@ void Connection::writePacket(const ResponsePacket& packet) {
this->write(rawPacket);
attempts++;
} while (this->readSingleByte(false).value_or(0) != '+');
}
} while(this->readSingleByte(false).value_or(0) != '+');
}
std::vector<unsigned char> Connection::read(size_t bytes, bool interruptible, std::optional<int> msTimeout) {
std::vector<unsigned char> Connection::read(size_t bytes, bool interruptible, std::optional<int> msTimeout) {
auto output = std::vector<unsigned char>();
constexpr size_t bufferSize = 1024;
std::array<unsigned char, bufferSize> buffer = {};
@@ -110,6 +113,7 @@ std::vector<unsigned char> Connection::read(size_t bytes, bool interruptible, st
if (interruptible) {
if (this->readInterruptEnabled != interruptible) {
this->enableReadInterrupts();
} else {
// Clear any previous interrupts that are still hanging around
this->interruptEventNotifier->clear();
@@ -141,7 +145,8 @@ std::vector<unsigned char> Connection::read(size_t bytes, bool interruptible, st
}
size_t bytesToRead = (bytes > bufferSize || bytes == 0) ? bufferSize : bytes;
while (bytesToRead > 0 && (bytesRead = ::read(this->socketFileDescriptor, buffer.data(), bytesToRead)) > 0) {
while (bytesToRead > 0
&& (bytesRead = ::read(this->socketFileDescriptor, buffer.data(), bytesToRead)) > 0) {
output.insert(output.end(), buffer.begin(), buffer.begin() + bytesRead);
if (bytesRead < bytesToRead) {
@@ -149,7 +154,8 @@ std::vector<unsigned char> Connection::read(size_t bytes, bool interruptible, st
break;
}
bytesToRead = ((bytes - output.size()) > bufferSize || bytes == 0) ? bufferSize : (bytes - output.size());
bytesToRead =
((bytes - output.size()) > bufferSize || bytes == 0) ? bufferSize : (bytes - output.size());
}
if (output.empty()) {
@@ -159,9 +165,9 @@ std::vector<unsigned char> Connection::read(size_t bytes, bool interruptible, st
}
return output;
}
}
std::optional<unsigned char> Connection::readSingleByte(bool interruptible) {
std::optional<unsigned char> Connection::readSingleByte(bool interruptible) {
auto bytes = this->read(1, interruptible, 300);
if (!bytes.empty()) {
@@ -169,23 +175,23 @@ std::optional<unsigned char> Connection::readSingleByte(bool interruptible) {
}
return std::nullopt;
}
}
void Connection::write(const std::vector<unsigned char>& buffer) {
void Connection::write(const std::vector<unsigned char>& buffer) {
Logger::debug("Writing packet: " + std::string(buffer.begin(), buffer.end()));
if (::write(this->socketFileDescriptor, buffer.data(), buffer.size()) == -1) {
if (errno == EPIPE || errno == ECONNRESET) {
// Connection was closed
throw ClientDisconnected();
}
} else {
throw ClientCommunicationError("Failed to write " + std::to_string(buffer.size())
+ " bytes to GDP client socket - error no: " + std::to_string(errno));
+ " bytes to GDP client socket - error no: "
+ std::to_string(errno));
}
}
}
void Connection::disableReadInterrupts() {
void Connection::disableReadInterrupts() {
if (::epoll_ctl(
this->eventFileDescriptor,
EPOLL_CTL_DEL,
@@ -196,9 +202,9 @@ void Connection::disableReadInterrupts() {
}
this->readInterruptEnabled = false;
}
}
void Connection::enableReadInterrupts() {
void Connection::enableReadInterrupts() {
auto interruptFileDescriptor = this->interruptEventNotifier->getFileDescriptor();
struct epoll_event event = {};
event.events = EPOLLIN;
@@ -209,4 +215,5 @@ void Connection::enableReadInterrupts() {
}
this->readInterruptEnabled = true;
}
}

View File

@@ -12,20 +12,21 @@
#include "src/Exceptions/Exception.hpp"
#include "src/Exceptions/InvalidConfig.hpp"
using namespace Bloom::DebugServers::Gdb;
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::DebugServers::Gdb::ResponsePackets;
using namespace Bloom::DebugServers::Gdb::Exceptions;
using namespace Bloom::Events;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb
{
using namespace CommandPackets;
using namespace ResponsePackets;
using namespace Exceptions;
using namespace Bloom::Events;
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetRegister;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetBreakpoint;
using Bloom::Targets::TargetRegister;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetBreakpoint;
void GdbRspDebugServer::handleGdbPacket(CommandPacket& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPacket& packet) {
auto packetData = packet.getData();
auto packetString = std::string(packetData.begin(), packetData.end());
@@ -47,9 +48,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPacket& packet) {
// Respond with an empty packet
this->clientConnection->writePacket(ResponsePacket({0}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::SupportedFeaturesQuery& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::SupportedFeaturesQuery& packet) {
Logger::debug("Handling QuerySupport packet");
if (!packet.isFeatureSupported(Feature::HARDWARE_BREAKPOINTS)
@@ -66,9 +67,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::SupportedFeaturesQuery&
});
this->clientConnection->writePacket(response);
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadRegisters& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadRegisters& packet) {
Logger::debug("Handling ReadRegisters packet");
try {
@@ -94,7 +95,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadRegisters& packet) {
std::sort(
registerSet.begin(),
registerSet.end(),
[this] (const TargetRegister& registerA, const TargetRegister& registerB) {
[this](const TargetRegister& registerA, const TargetRegister& registerB) {
return this->getRegisterNumberFromTargetRegisterDescriptor(registerA.descriptor) <
this->getRegisterNumberFromTargetRegisterDescriptor(registerB.descriptor);
}
@@ -109,7 +110,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadRegisters& packet) {
for (auto& reg : registerSet) {
std::reverse(reg.value.begin(), reg.value.end());
const auto gdbRegisterNumber = this->getRegisterNumberFromTargetRegisterDescriptor(reg.descriptor).value();
const auto gdbRegisterNumber = this->getRegisterNumberFromTargetRegisterDescriptor(
reg.descriptor
).value();
const auto& gdbRegisterDescriptor = this->getRegisterDescriptorFromNumber(gdbRegisterNumber);
if (reg.value.size() < gdbRegisterDescriptor.size) {
@@ -128,9 +131,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadRegisters& packet) {
Logger::error("Failed to read general registers - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteRegister& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteRegister& packet) {
Logger::debug("Handling WriteRegister packet");
try {
@@ -165,9 +168,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteRegister& packet) {
Logger::error("Failed to write registers - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::ContinueExecution& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::ContinueExecution& packet) {
Logger::debug("Handling ContinueExecution packet");
try {
@@ -178,9 +181,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ContinueExecution& packe
Logger::error("Failed to continue execution on target - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::StepExecution& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::StepExecution& packet) {
Logger::debug("Handling StepExecution packet");
try {
@@ -191,9 +194,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::StepExecution& packet) {
Logger::error("Failed to step execution on target - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadMemory& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadMemory& packet) {
Logger::debug("Handling ReadMemory packet");
try {
@@ -210,9 +213,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadMemory& packet) {
Logger::error("Failed to read memory from target - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteMemory& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteMemory& packet) {
Logger::debug("Handling WriteMemory packet");
try {
@@ -226,9 +229,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteMemory& packet) {
Logger::error("Failed to write memory two target - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::SetBreakpoint& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::SetBreakpoint& packet) {
Logger::debug("Handling SetBreakpoint packet");
try {
@@ -242,9 +245,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::SetBreakpoint& packet) {
Logger::error("Failed to set breakpoint on target - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::RemoveBreakpoint& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::RemoveBreakpoint& packet) {
Logger::debug("Removing breakpoint at address " + std::to_string(packet.address));
try {
@@ -258,9 +261,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::RemoveBreakpoint& packet
Logger::error("Failed to remove breakpoint on target - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::handleGdbPacket(CommandPackets::InterruptExecution& packet) {
void GdbRspDebugServer::handleGdbPacket(CommandPackets::InterruptExecution& packet) {
Logger::debug("Handling InterruptExecution packet");
try {
@@ -272,9 +275,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::InterruptExecution& pack
Logger::error("Failed to interrupt execution - " + exception.getMessage());
this->clientConnection->writePacket(ResponsePacket({'E', '0', '1'}));
}
}
}
void GdbRspDebugServer::init() {
void GdbRspDebugServer::init() {
auto ipAddress = this->debugServerConfig.jsonObject.find("ipAddress")->toString().toStdString();
auto configPortJsonValue = this->debugServerConfig.jsonObject.find("port");
auto configPortValue = configPortJsonValue->isString()
@@ -294,7 +297,9 @@ void GdbRspDebugServer::init() {
if (::inet_pton(AF_INET, this->listeningAddress.c_str(), &(this->socketAddress.sin_addr)) == 0) {
// Invalid IP address
throw InvalidConfig("Invalid IP address provided in config file: (\"" + this->listeningAddress + "\")");
throw InvalidConfig(
"Invalid IP address provided in config file: (\"" + this->listeningAddress + "\")"
);
}
int socketFileDescriptor;
@@ -355,17 +360,17 @@ void GdbRspDebugServer::init() {
this->eventListener->registerCallbackForEventType<Events::TargetExecutionStopped>(
std::bind(&GdbRspDebugServer::onTargetExecutionStopped, this, std::placeholders::_1)
);
}
}
void GdbRspDebugServer::close() {
void GdbRspDebugServer::close() {
this->closeClientConnection();
if (this->serverSocketFileDescriptor > 0) {
::close(this->serverSocketFileDescriptor);
}
}
}
void GdbRspDebugServer::serve() {
void GdbRspDebugServer::serve() {
try {
if (!this->clientConnection.has_value()) {
Logger::info("Waiting for GDB RSP connection");
@@ -403,7 +408,9 @@ void GdbRspDebugServer::serve() {
return;
} catch (const ClientCommunicationError& exception) {
Logger::error("GDB RSP client communication error - " + exception.getMessage() + " - closing connection");
Logger::error(
"GDB RSP client communication error - " + exception.getMessage() + " - closing connection"
);
this->closeClientConnection();
return;
@@ -422,9 +429,9 @@ void GdbRspDebugServer::serve() {
Logger::debug("GDB RSP interrupted");
return;
}
}
}
void GdbRspDebugServer::waitForConnection() {
void GdbRspDebugServer::waitForConnection() {
if (::listen(this->serverSocketFileDescriptor, 3) != 0) {
throw Exception("Failed to listen on server socket");
}
@@ -451,18 +458,19 @@ void GdbRspDebugServer::waitForConnection() {
this->clientConnection = Connection(this->interruptEventNotifier);
}
}
}
void GdbRspDebugServer::onTargetControllerStateReported(const Events::TargetControllerStateReported& event) {
void GdbRspDebugServer::onTargetControllerStateReported(const Events::TargetControllerStateReported& event) {
if (event.state == TargetControllerState::SUSPENDED && this->clientConnection.has_value()) {
Logger::warning("Terminating debug session - TargetController suspended unexpectedly");
this->closeClientConnection();
}
}
}
void GdbRspDebugServer::onTargetExecutionStopped(const Events::TargetExecutionStopped&) {
void GdbRspDebugServer::onTargetExecutionStopped(const Events::TargetExecutionStopped&) {
if (this->clientConnection.has_value() && this->clientConnection->waitingForBreak) {
this->clientConnection->writePacket(TargetStopped(Signal::TRAP));
this->clientConnection->waitingForBreak = false;
}
}
}

View File

@@ -1,8 +1,8 @@
#include "SupportedFeaturesResponse.hpp"
using namespace Bloom::DebugServers::Gdb::ResponsePackets;
std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
namespace Bloom::DebugServers::Gdb::ResponsePackets
{
std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
std::string output = "qSupported:";
auto gdbFeatureMapping = getGdbFeatureToNameMapping();
@@ -12,6 +12,7 @@ std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
if (featureString.has_value()) {
if (supportedFeature.second.has_value()) {
output.append(featureString.value() + "=" + supportedFeature.second.value() + ";");
} else {
output.append(featureString.value() + "+;");
}
@@ -20,4 +21,5 @@ std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
}
return std::vector<unsigned char>(output.begin(), output.end());
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void AtmelIce::init() {
void AtmelIce::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -39,23 +40,25 @@ void AtmelIce::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void AtmelIce::close() {
void AtmelIce::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string AtmelIce::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string AtmelIce::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -63,30 +66,35 @@ std::string AtmelIce::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void AtmelIce::startSession() {
using namespace CommandFrames::HouseKeeping;
void AtmelIce::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with Atmel-ICE!");
}
this->sessionStarted = true;
}
}
void AtmelIce::endSession() {
using namespace CommandFrames::HouseKeeping;
void AtmelIce::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with Atmel-ICE!");
}
this->sessionStarted = false;
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void CuriosityNano::init() {
void CuriosityNano::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -31,23 +32,25 @@ void CuriosityNano::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void CuriosityNano::close() {
void CuriosityNano::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string CuriosityNano::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string CuriosityNano::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -55,30 +58,35 @@ std::string CuriosityNano::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void CuriosityNano::startSession() {
using namespace CommandFrames::HouseKeeping;
void CuriosityNano::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with Curiosity Nano!");
}
this->sessionStarted = true;
}
}
void CuriosityNano::endSession() {
using namespace CommandFrames::HouseKeeping;
void CuriosityNano::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with Curiosity Nano!");
}
this->sessionStarted = false;
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void MplabPickit4::init() {
void MplabPickit4::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -32,23 +33,25 @@ void MplabPickit4::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void MplabPickit4::close() {
void MplabPickit4::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string MplabPickit4::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string MplabPickit4::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -56,30 +59,35 @@ std::string MplabPickit4::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void MplabPickit4::startSession() {
using namespace CommandFrames::HouseKeeping;
void MplabPickit4::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with MPLAB PICkit 4!");
}
this->sessionStarted = true;
}
}
void MplabPickit4::endSession() {
using namespace CommandFrames::HouseKeeping;
void MplabPickit4::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with MPLAB PICkit 4!");
}
this->sessionStarted = false;
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void MplabSnap::init() {
void MplabSnap::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -31,23 +32,25 @@ void MplabSnap::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void MplabSnap::close() {
void MplabSnap::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string MplabSnap::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string MplabSnap::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -55,30 +58,35 @@ std::string MplabSnap::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void MplabSnap::startSession() {
using namespace CommandFrames::HouseKeeping;
void MplabSnap::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with MPLAB Snap!");
}
this->sessionStarted = true;
}
}
void MplabSnap::endSession() {
using namespace CommandFrames::HouseKeeping;
void MplabSnap::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with MPLAB Snap!");
}
this->sessionStarted = false;
}
}

View File

@@ -3,13 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
using Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::EdbgAvr8Interface;
void PowerDebugger::init() {
void PowerDebugger::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -39,23 +38,25 @@ void PowerDebugger::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void PowerDebugger::close() {
void PowerDebugger::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string PowerDebugger::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string PowerDebugger::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -63,14 +64,16 @@ std::string PowerDebugger::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void PowerDebugger::startSession() {
using namespace CommandFrames::HouseKeeping;
void PowerDebugger::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure(
"Failed to start session with the Power Debugger - device returned failed response ID"
@@ -78,17 +81,22 @@ void PowerDebugger::startSession() {
}
this->sessionStarted = true;
}
}
void PowerDebugger::endSession() {
using namespace CommandFrames::HouseKeeping;
void PowerDebugger::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with the Power Debugger - device returned failed response ID");
throw DeviceFailure(
"Failed to end session with the Power Debugger - device returned failed response ID"
);
}
this->sessionStarted = false;
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void XplainedMini::init() {
void XplainedMini::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -31,23 +32,25 @@ void XplainedMini::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void XplainedMini::close() {
void XplainedMini::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string XplainedMini::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string XplainedMini::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -55,30 +58,35 @@ std::string XplainedMini::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void XplainedMini::startSession() {
using namespace CommandFrames::HouseKeeping;
void XplainedMini::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with Xplained Mini!");
}
this->sessionStarted = true;
}
}
void XplainedMini::endSession() {
using namespace CommandFrames::HouseKeeping;
void XplainedMini::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with Xplained Mini!");
}
this->sessionStarted = false;
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void XplainedNano::init() {
void XplainedNano::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -31,23 +32,25 @@ void XplainedNano::init() {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true);
}
}
void XplainedNano::close() {
void XplainedNano::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string XplainedNano::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string XplainedNano::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -55,30 +58,35 @@ std::string XplainedNano::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void XplainedNano::startSession() {
using namespace CommandFrames::HouseKeeping;
void XplainedNano::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with Xplained Nano!");
}
this->sessionStarted = true;
}
}
void XplainedNano::endSession() {
using namespace CommandFrames::HouseKeeping;
void XplainedNano::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with Xplained Nano!");
}
this->sessionStarted = false;
}
}

View File

@@ -3,11 +3,12 @@
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers
{
using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void XplainedPro::init() {
void XplainedPro::init() {
UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number
@@ -40,23 +41,25 @@ void XplainedPro::init() {
*/
this->edbgAvr8Interface->setMaximumMemoryAccessSizePerRequest(256);
this->setInitialised(true);
}
}
void XplainedPro::close() {
void XplainedPro::close() {
if (this->sessionStarted) {
this->endSession();
}
this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close();
}
}
std::string XplainedPro::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string XplainedPro::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::Discovery::Query(CommandFrames::Discovery::QueryContext::SERIAL_NUMBER)
Query(QueryContext::SERIAL_NUMBER)
);
if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) {
if (response.getResponseId() != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
);
@@ -64,30 +67,35 @@ std::string XplainedPro::getSerialNumber() {
auto data = response.getPayloadData();
return std::string(data.begin(), data.end());
}
}
void XplainedPro::startSession() {
using namespace CommandFrames::HouseKeeping;
void XplainedPro::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession()
StartSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with Xplained Pro!");
}
this->sessionStarted = true;
}
}
void XplainedPro::endSession() {
using namespace CommandFrames::HouseKeeping;
void XplainedPro::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession()
EndSession()
);
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) {
if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with Xplained Pro!");
}
this->sessionStarted = false;
}
}

View File

@@ -6,10 +6,11 @@
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Response.hpp"
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
{
using namespace Bloom::Exceptions;
void CmsisDapInterface::sendCommand(const Command& cmsisDapCommand) {
void CmsisDapInterface::sendCommand(const Command& cmsisDapCommand) {
if (this->msSendCommandDelay.count() > 0) {
using namespace std::chrono;
std::int64_t now = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
@@ -23,9 +24,9 @@ void CmsisDapInterface::sendCommand(const Command& cmsisDapCommand) {
}
this->getUsbHidInterface().write(static_cast<std::vector<unsigned char>>(cmsisDapCommand));
}
}
std::unique_ptr<Response> CmsisDapInterface::getResponse() {
std::unique_ptr<Response> CmsisDapInterface::getResponse() {
auto rawResponse = this->getUsbHidInterface().read(10000);
if (rawResponse.empty()) {
@@ -35,9 +36,9 @@ std::unique_ptr<Response> CmsisDapInterface::getResponse() {
auto response = std::make_unique<Response>(Response());
response->init(rawResponse);
return response;
}
}
std::unique_ptr<Response> CmsisDapInterface::sendCommandAndWaitForResponse(const Command& cmsisDapCommand) {
std::unique_ptr<Response> CmsisDapInterface::sendCommandAndWaitForResponse(const Command& cmsisDapCommand) {
this->sendCommand(cmsisDapCommand);
auto response = this->getResponse();
@@ -47,4 +48,5 @@ std::unique_ptr<Response> CmsisDapInterface::sendCommandAndWaitForResponse(const
}
return response;
}
}

View File

@@ -1,11 +1,12 @@
#include "Command.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
Command::operator std::vector<unsigned char> () const {
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
{
Command::operator std::vector<unsigned char>() const {
auto rawCommand = std::vector<unsigned char>(1, this->getCommandId());
auto commandData = this->getData();
rawCommand.insert(rawCommand.end(), commandData.begin(), commandData.end());
return rawCommand;
}
}

View File

@@ -2,13 +2,14 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
void Response::init(const std::vector<unsigned char>& rawResponse) {
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
{
void Response::init(const std::vector<unsigned char>& rawResponse) {
if (rawResponse.empty()) {
throw Exceptions::Exception("Failed to process CMSIS-DAP response - invalid response");
}
this->setResponseId(rawResponse[0]);
this->setData(std::vector<unsigned char>(rawResponse.begin() + 1, rawResponse.end()));
}
}

View File

@@ -1,8 +1,8 @@
#include "AvrCommand.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
std::vector<unsigned char> AvrCommand::getData() const {
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
std::vector<unsigned char> AvrCommand::getData() const {
std::vector<unsigned char> data;
auto commandPacket = this->getCommandPacket();
std::size_t commandPacketSize = commandPacket.size();
@@ -11,12 +11,13 @@ std::vector<unsigned char> AvrCommand::getData() const {
data[0] = static_cast<unsigned char>((this->getFragmentNumber() << 4) | this->getFragmentCount());
// Size byte
data[1] = (unsigned char) (commandPacketSize >> 8);
data[2] = (unsigned char) (commandPacketSize & 0xFF);
data[1] = static_cast<unsigned char>(commandPacketSize >> 8);
data[2] = static_cast<unsigned char>(commandPacketSize & 0xFF);
if (commandPacketSize > 0) {
data.insert(data.begin() + 3, commandPacket.begin(), commandPacket.end());
}
return data;
}
}

View File

@@ -2,17 +2,18 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void AvrEvent::init(const std::vector<unsigned char>& rawResponse) {
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.");
}
auto& responseData = this->getData();
const auto& responseData = this->getData();
if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID)
@@ -46,4 +47,5 @@ void AvrEvent::init(const std::vector<unsigned char>& rawResponse) {
if (!eventData.empty()) {
this->eventId = eventData[0];
}
}
}

View File

@@ -2,17 +2,18 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
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.");
}
auto& responseData = this->getData();
const auto& responseData = this->getData();
if (responseData.empty()) {
// All AVR responses should contain at least one byte (the fragment info byte)
@@ -25,11 +26,11 @@ void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
return;
}
this->setFragmentCount(static_cast<std::uint8_t>(responseData[0] & 0x0Fu));
this->setFragmentCount(static_cast<std::uint8_t>(responseData[0] & 0x0FU));
this->setFragmentNumber(static_cast<std::uint8_t>(responseData[0] >> 4));
// Response size is two bytes, MSB
std::size_t responsePacketSize = static_cast<std::size_t>((responseData[1] << 8u) + responseData[2]);
const auto responsePacketSize = static_cast<std::size_t>((responseData[1] << 8U) + responseData[2]);
std::vector<unsigned char> responsePacket;
responsePacket.resize(responsePacketSize);
@@ -38,4 +39,5 @@ void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
}
this->setResponsePacket(responsePacket);
}
}

View File

@@ -3,9 +3,9 @@
#include <bitset>
#include <cmath>
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic;
std::vector<unsigned char> ReadMemory::getPayload() const {
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic
{
std::vector<unsigned char> ReadMemory::getPayload() const {
/*
* The read memory command consists of 11/11 + (this->bytes / 8) bytes:
* 1. Command ID (0x21 for the general read memory command, 0x22 for reading with a mask)
@@ -53,4 +53,5 @@ std::vector<unsigned char> ReadMemory::getPayload() const {
}
return output;
}
}

View File

@@ -2,9 +2,9 @@
#include <math.h>
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
std::vector<AvrCommand> AvrCommandFrame::generateAvrCommands(std::size_t maximumCommandPacketSize) const {
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
std::vector<AvrCommand> AvrCommandFrame::generateAvrCommands(std::size_t maximumCommandPacketSize) const {
auto rawCommandFrame = static_cast<std::vector<unsigned char>>(*this);
std::size_t commandFrameSize = rawCommandFrame.size();
auto commandsRequired = static_cast<std::size_t>(
@@ -35,9 +35,9 @@ std::vector<AvrCommand> AvrCommandFrame::generateAvrCommands(std::size_t maximum
}
return avrCommands;
}
}
AvrCommandFrame::operator std::vector<unsigned char> () const {
AvrCommandFrame::operator std::vector<unsigned char>() const {
auto data = this->getPayload();
auto dataSize = data.size();
@@ -60,4 +60,5 @@ AvrCommandFrame::operator std::vector<unsigned char> () const {
}
return rawCommand;
}
}

View File

@@ -36,21 +36,22 @@
// AVR events
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Events/AVR8Generic/BreakEvent.hpp"
using namespace Bloom::Targets::Microchip::Avr;
using namespace Bloom::Targets::Microchip::Avr::Avr8Bit;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Targets::Microchip::Avr;
using namespace Avr8Bit;
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetMemoryType;
using Bloom::Targets::TargetMemoryBuffer;
using Bloom::Targets::TargetRegister;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetRegisters;
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetMemoryType;
using Bloom::Targets::TargetMemoryBuffer;
using Bloom::Targets::TargetRegister;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetRegisters;
void EdbgAvr8Interface::configure(const TargetConfig& targetConfig) {
void EdbgAvr8Interface::configure(const TargetConfig& targetConfig) {
auto physicalInterface = targetConfig.jsonObject.find("physicalInterface")->toString().toLower().toStdString();
auto availablePhysicalInterfaces = this->getPhysicalInterfacesByName();
@@ -91,9 +92,9 @@ void EdbgAvr8Interface::configure(const TargetConfig& targetConfig) {
"disableDebugWirePreDisconnect"
)->toBool();
}
}
}
void EdbgAvr8Interface::setTargetParameters(const Avr8Bit::TargetParameters& config) {
void EdbgAvr8Interface::setTargetParameters(const Avr8Bit::TargetParameters& config) {
this->targetParameters = config;
if (!config.stackPointerRegisterLowAddress.has_value()) {
@@ -118,7 +119,8 @@ void EdbgAvr8Interface::setTargetParameters(const Avr8Bit::TargetParameters& con
throw DeviceInitializationFailure("Flash page size for target ("
+ std::to_string(config.flashPageSize.value())
+ " bytes) exceeds maximum memory access size for EdbgAvr8Interface ("
+ std::to_string(this->maximumMemoryAccessSizePerRequest.value()) + " bytes)."
+ std::to_string(this->maximumMemoryAccessSizePerRequest.value())
+ " bytes)."
);
}
@@ -153,9 +155,9 @@ void EdbgAvr8Interface::setTargetParameters(const Avr8Bit::TargetParameters& con
break;
}
}
}
}
void EdbgAvr8Interface::init() {
void EdbgAvr8Interface::init() {
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
// Default PDI clock to 4MHz
// TODO: Make this adjustable via a target config parameter
@@ -189,9 +191,9 @@ void EdbgAvr8Interface::init() {
Avr8EdbgParameters::PHYSICAL_INTERFACE,
getAvr8PhysicalInterfaceToIdMapping().at(this->physicalInterface)
);
}
}
void EdbgAvr8Interface::stop() {
void EdbgAvr8Interface::stop() {
auto commandFrame = CommandFrames::Avr8Generic::Stop();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -202,9 +204,9 @@ void EdbgAvr8Interface::stop() {
if (this->getTargetState() == TargetState::RUNNING) {
this->waitForStoppedEvent();
}
}
}
void EdbgAvr8Interface::run() {
void EdbgAvr8Interface::run() {
this->clearEvents();
auto commandFrame = CommandFrames::Avr8Generic::Run();
@@ -214,11 +216,10 @@ void EdbgAvr8Interface::run() {
}
this->targetState = TargetState::RUNNING;
}
}
void EdbgAvr8Interface::runTo(std::uint32_t address) {
void EdbgAvr8Interface::runTo(std::uint32_t address) {
this->clearEvents();
Logger::debug("Running to address: " + std::to_string(address));
auto commandFrame = CommandFrames::Avr8Generic::RunTo(address);
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -227,9 +228,9 @@ void EdbgAvr8Interface::runTo(std::uint32_t address) {
}
this->targetState = TargetState::RUNNING;
}
}
void EdbgAvr8Interface::step() {
void EdbgAvr8Interface::step() {
auto commandFrame = CommandFrames::Avr8Generic::Step();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -238,18 +239,18 @@ void EdbgAvr8Interface::step() {
}
this->targetState = TargetState::RUNNING;
}
}
void EdbgAvr8Interface::reset() {
void EdbgAvr8Interface::reset() {
auto commandFrame = CommandFrames::Avr8Generic::Reset();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Reset target command failed", response);
}
}
}
void EdbgAvr8Interface::activate() {
void EdbgAvr8Interface::activate() {
if (!this->physicalInterfaceActivated) {
this->activatePhysical();
}
@@ -257,16 +258,18 @@ void EdbgAvr8Interface::activate() {
if (!this->targetAttached) {
this->attach();
}
}
}
void EdbgAvr8Interface::deactivate() {
void EdbgAvr8Interface::deactivate() {
if (this->targetAttached) {
if (this->physicalInterface == PhysicalInterface::DEBUG_WIRE && this->disableDebugWireOnDeactivate) {
try {
this->disableDebugWire();
Logger::warning("Successfully disabled debugWire on the AVR8 target - this is only temporary - "
"the debugWire module has lost control of the RESET pin. Bloom will no longer be able to interface "
"with the target until the next power cycle.");
Logger::warning(
"Successfully disabled debugWire on the AVR8 target - this is only temporary - "
"the debugWire module has lost control of the RESET pin. Bloom will no longer be able to "
"interface with the target until the next power cycle."
);
} catch (const Exception& exception) {
// Failing to disable debugWire should never prevent us from proceeding with target deactivation.
@@ -284,9 +287,9 @@ void EdbgAvr8Interface::deactivate() {
if (this->physicalInterfaceActivated) {
this->deactivatePhysical();
}
}
}
std::uint32_t EdbgAvr8Interface::getProgramCounter() {
std::uint32_t EdbgAvr8Interface::getProgramCounter() {
if (this->targetState != TargetState::STOPPED) {
this->stop();
}
@@ -298,9 +301,9 @@ std::uint32_t EdbgAvr8Interface::getProgramCounter() {
}
return response.extractProgramCounter();
}
}
void EdbgAvr8Interface::setProgramCounter(std::uint32_t programCounter) {
void EdbgAvr8Interface::setProgramCounter(std::uint32_t programCounter) {
if (this->targetState != TargetState::STOPPED) {
this->stop();
}
@@ -314,9 +317,9 @@ void EdbgAvr8Interface::setProgramCounter(std::uint32_t programCounter) {
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Set program counter command failed", response);
}
}
}
TargetSignature EdbgAvr8Interface::getDeviceId() {
TargetSignature EdbgAvr8Interface::getDeviceId() {
if (this->configVariant == Avr8ConfigVariant::UPDI) {
/*
* When using the UPDI physical interface, the 'Get device ID' command behaves in an odd manner, where it
@@ -350,46 +353,47 @@ TargetSignature EdbgAvr8Interface::getDeviceId() {
}
return response.extractSignature(this->physicalInterface);
}
}
void EdbgAvr8Interface::setBreakpoint(std::uint32_t address) {
void EdbgAvr8Interface::setBreakpoint(std::uint32_t address) {
auto commandFrame = CommandFrames::Avr8Generic::SetSoftwareBreakpoints({address});
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Set software breakpoint command failed", response);
}
}
}
void EdbgAvr8Interface::clearBreakpoint(std::uint32_t address) {
void EdbgAvr8Interface::clearBreakpoint(std::uint32_t address) {
auto commandFrame = CommandFrames::Avr8Generic::ClearSoftwareBreakpoints({address});
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Clear software breakpoint command failed", response);
}
}
}
void EdbgAvr8Interface::clearAllBreakpoints() {
void EdbgAvr8Interface::clearAllBreakpoints() {
auto commandFrame = CommandFrames::Avr8Generic::ClearAllSoftwareBreakpoints();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Clear all software breakpoints command failed", response);
}
}
}
TargetRegisters EdbgAvr8Interface::readRegisters(const TargetRegisterDescriptors& descriptors) {
TargetRegisters EdbgAvr8Interface::readRegisters(const TargetRegisterDescriptors& descriptors) {
/*
* This function needs to be fast. Insight eagerly requests the values of all known registers that it can present
* to the user. It does this on numerous occasions (target stopped, user clicked refresh, etc). This means we will
* be frequently loading over 100 register values in a single instance.
* This function needs to be fast. Insight eagerly requests the values of all known registers that it can
* present to the user. It does this on numerous occasions (target stopped, user clicked refresh, etc). This
* means we will be frequently loading over 100 register values in a single instance.
*
* For the above reason, we do not read each register value individually. That would take far too long if we have
* over 100 registers to read. Instead, we group the register descriptors into collections by register type, and
* resolve the address range for each collection. We then perform a single read operation for each collection
* and hold the memory buffer in a random access container (std::vector). Finally, we extract the data for
* each register descriptor, from the memory buffer, and construct the relevant TargetRegister object.
* For the above reason, we do not read each register value individually. That would take far too long if we
* have over 100 registers to read. Instead, we group the register descriptors into collections by register
* type, and resolve the address range for each collection. We then perform a single read operation for
* each collection and hold the memory buffer in a random access container (std::vector). Finally, we extract
* the data for each register descriptor, from the memory buffer, and construct the relevant TargetRegister
* object.
*
* TODO: We should be grouping the register descriptors by memory type, as opposed to register type. This
* isn't much of a problem ATM, as currently, we only work with registers that are stored in the data
@@ -445,24 +449,24 @@ TargetRegisters EdbgAvr8Interface::readRegisters(const TargetRegisterDescriptors
* Now that we have our address ranges and grouped descriptors, we can perform a single read call for each
* register type.
*/
for (const auto& [registerType, descriptors] : descriptorsByType) {
for (const auto&[registerType, descriptors] : descriptorsByType) {
const auto& addressRange = addressRangeByType[registerType];
const auto startAddress = addressRange.first;
const auto endAddress = addressRange.second;
const auto bufferSize = (endAddress - startAddress) + 1;
const auto memoryType = (registerType != TargetRegisterType::GENERAL_PURPOSE_REGISTER) ? Avr8MemoryType::SRAM : (
this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI
? Avr8MemoryType::REGISTER_FILE : Avr8MemoryType::SRAM
);
const auto memoryType = (registerType != TargetRegisterType::GENERAL_PURPOSE_REGISTER) ?
Avr8MemoryType::SRAM
: (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI
? Avr8MemoryType::REGISTER_FILE : Avr8MemoryType::SRAM);
/*
* When reading the entire range, we must avoid any attempts to access the OCD data register (OCDDR), as the
* debug tool will reject the command and respond with a 0x36 error code (invalid address error).
* When reading the entire range, we must avoid any attempts to access the OCD data register (OCDDR), as
* the debug tool will reject the command and respond with a 0x36 error code (invalid address error).
*
* For this reason, we specify the OCDDR address as an excluded address. This will mean
* the EdbgAvr8Interface::readMemory() function will employ the masked read memory command, as opposed to the
* general read memory command. The masked read memory command allows us to specify which addresses to
* the EdbgAvr8Interface::readMemory() function will employ the masked read memory command, as opposed to
* the general read memory command. The masked read memory command allows us to specify which addresses to
* read and which ones to ignore. For ignored addresses, the debug tool will just return a 0x00 byte.
* For more info, see section 7.1.22 titled 'Memory Read Masked', in the EDBG protocol document.
*
@@ -495,7 +499,7 @@ TargetRegisters EdbgAvr8Interface::readRegisters(const TargetRegisterDescriptors
if (flatMemoryBuffer.size() != bufferSize) {
throw Exception(
"Failed to read memory within register type address range (" + std::to_string(startAddress)
+ " - " + std::to_string(endAddress) +"). Expected " + std::to_string(bufferSize)
+ " - " + std::to_string(endAddress) + "). Expected " + std::to_string(bufferSize)
+ " bytes, got " + std::to_string(flatMemoryBuffer.size())
);
}
@@ -522,9 +526,9 @@ TargetRegisters EdbgAvr8Interface::readRegisters(const TargetRegisterDescriptors
}
return output;
}
}
void EdbgAvr8Interface::writeRegisters(const Targets::TargetRegisters& registers) {
void EdbgAvr8Interface::writeRegisters(const Targets::TargetRegisters& registers) {
for (const auto& reg : registers) {
const auto& registerDescriptor = reg.descriptor;
auto registerValue = reg.value;
@@ -561,14 +565,14 @@ void EdbgAvr8Interface::writeRegisters(const Targets::TargetRegisters& registers
registerValue
);
}
}
}
TargetMemoryBuffer EdbgAvr8Interface::readMemory(
TargetMemoryBuffer EdbgAvr8Interface::readMemory(
TargetMemoryType memoryType,
std::uint32_t startAddress,
std::uint32_t bytes,
const std::set<Targets::TargetMemoryAddressRange>& excludedAddressRanges
) {
) {
auto avr8MemoryType = Avr8MemoryType::SRAM;
switch (memoryType) {
@@ -580,7 +584,8 @@ TargetMemoryBuffer EdbgAvr8Interface::readMemory(
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
avr8MemoryType = Avr8MemoryType::FLASH_PAGE;
} else if (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI) {
} else if (this->configVariant == Avr8ConfigVariant::XMEGA
|| this->configVariant == Avr8ConfigVariant::UPDI) {
avr8MemoryType = Avr8MemoryType::APPL_FLASH;
} else {
@@ -617,9 +622,13 @@ TargetMemoryBuffer EdbgAvr8Interface::readMemory(
}
return this->readMemory(avr8MemoryType, startAddress, bytes, excludedAddresses);
}
}
void EdbgAvr8Interface::writeMemory(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer) {
void EdbgAvr8Interface::writeMemory(
TargetMemoryType memoryType,
std::uint32_t startAddress,
const TargetMemoryBuffer& buffer
) {
auto avr8MemoryType = Avr8MemoryType::SRAM;
switch (memoryType) {
@@ -635,7 +644,8 @@ void EdbgAvr8Interface::writeMemory(TargetMemoryType memoryType, std::uint32_t s
avr8MemoryType = Avr8MemoryType::FLASH_PAGE;
// TODO: Enable programming mode
} else if (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI) {
} else if (this->configVariant == Avr8ConfigVariant::XMEGA
|| this->configVariant == Avr8ConfigVariant::UPDI) {
avr8MemoryType = Avr8MemoryType::APPL_FLASH;
} else {
@@ -652,9 +662,9 @@ void EdbgAvr8Interface::writeMemory(TargetMemoryType memoryType, std::uint32_t s
}
return this->writeMemory(avr8MemoryType, startAddress, buffer);
}
}
TargetState EdbgAvr8Interface::getTargetState() {
TargetState EdbgAvr8Interface::getTargetState() {
/*
* We are not informed when a target goes from a stopped state to a running state, so there is no need
* to query the tool when we already know the target has stopped.
@@ -667,18 +677,18 @@ TargetState EdbgAvr8Interface::getTargetState() {
}
return this->targetState;
}
}
void EdbgAvr8Interface::setParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value) {
void EdbgAvr8Interface::setParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value) {
auto commandFrame = CommandFrames::Avr8Generic::SetParameter(parameter, value);
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("Failed to set parameter on device!", response);
}
}
}
std::vector<unsigned char> EdbgAvr8Interface::getParameter(const Avr8EdbgParameter& parameter, std::uint8_t size) {
std::vector<unsigned char> EdbgAvr8Interface::getParameter(const Avr8EdbgParameter& parameter, std::uint8_t size) {
auto commandFrame = CommandFrames::Avr8Generic::GetParameter(parameter, size);
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -687,9 +697,9 @@ std::vector<unsigned char> EdbgAvr8Interface::getParameter(const Avr8EdbgParamet
}
return response.getPayloadData();
}
}
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
if (this->targetParameters.flashPageSize.has_value()) {
Logger::debug("Setting DEVICE_FLASH_PAGE_SIZE AVR8 parameter");
this->setParameter(
@@ -772,8 +782,8 @@ void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
/*
* All addresses for registers that reside in the mapped IO memory segment include the mapped IO segment offset
* (start address). But the EDBG protocol requires *some* of these addresses to be stripped of this offset before
* sending them as target parameters.
* (start address). But the EDBG protocol requires *some* of these addresses to be stripped of this offset
* before sending them as target parameters.
*
* This applies to the following addresses:
*
@@ -836,9 +846,9 @@ void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
)
);
}
}
}
void EdbgAvr8Interface::setPdiParameters() {
void EdbgAvr8Interface::setPdiParameters() {
if (!this->targetParameters.appSectionPdiOffset.has_value()) {
throw DeviceInitializationFailure("Missing required parameter: APPL_BASE_ADDR");
}
@@ -978,26 +988,27 @@ void EdbgAvr8Interface::setPdiParameters() {
Avr8EdbgParameters::DEVICE_XMEGA_NVM_BASE,
this->targetParameters.nvmBaseAddress.value()
);
}
}
void EdbgAvr8Interface::setUpdiParameters() {
void EdbgAvr8Interface::setUpdiParameters() {
if (!this->targetParameters.signatureSegmentStartAddress.has_value()) {
throw DeviceInitializationFailure("Missing required parameter: SIGNATURE BASE ADDRESS");
}
if (this->targetParameters.programMemoryUpdiStartAddress.has_value()) {
/*
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be limited
* to two bytes in size, as opposed to the four byte size for the debugWire, JTAG and PDI equivalent fields.
* This is why, I suspect, another field was required for the most significant byte of the program memory base
* address (DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB).
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be
* limited to two bytes in size, as opposed to the four byte size for the debugWire, JTAG and PDI
* equivalent fields. This is why, I suspect, another field was required for the most significant byte of
* the program memory base address (DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB).
*
* The additional DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB field is only one byte in size, so it brings the total
* capacity for the program memory base address to three bytes. Because of this, we ensure that all TDFs, for
* targets that support UPDI, specify an address that does not exceed the maximum value of a 24 bit unsigned
* integer. This is done in our TDF validation script (see src/Targets/TargetDescription/README.md for more).
* capacity for the program memory base address to three bytes. Because of this, we ensure that all TDFs,
* for targets that support UPDI, specify an address that does not exceed the maximum value of a 24 bit
* unsigned integer. This is done in our TDF validation script (see src/Targets/TargetDescription/README.md
* for more).
*/
auto programMemBaseAddress = this->targetParameters.programMemoryUpdiStartAddress.value();
const auto programMemBaseAddress = this->targetParameters.programMemoryUpdiStartAddress.value();
Logger::debug("Setting DEVICE_UPDI_PROGMEM_BASE_ADDR AVR8 parameter");
this->setParameter(
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR,
@@ -1116,9 +1127,9 @@ void EdbgAvr8Interface::setUpdiParameters() {
this->targetParameters.programMemoryUpdiStartAddress.value_or(0) > 0xFFFF ?
static_cast<std::uint8_t>(1) : static_cast<std::uint8_t>(0)
);
}
}
void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
auto commandFrame = CommandFrames::Avr8Generic::ActivatePhysical(applyExternalReset);
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -1134,9 +1145,9 @@ void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
}
this->physicalInterfaceActivated = true;
}
}
void EdbgAvr8Interface::deactivatePhysical() {
void EdbgAvr8Interface::deactivatePhysical() {
auto commandFrame = CommandFrames::Avr8Generic::DeactivatePhysical();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -1145,12 +1156,12 @@ void EdbgAvr8Interface::deactivatePhysical() {
}
this->physicalInterfaceActivated = false;
}
}
void EdbgAvr8Interface::attach() {
void EdbgAvr8Interface::attach() {
/*
* When attaching an ATmega target that is connected via JTAG, we must not set the breakAfterAttach flag, as this
* results in a timeout.
* When attaching an ATmega target that is connected via JTAG, we must not set the breakAfterAttach flag, as
* this results in a timeout.
*
* However, in this case the attach command seems to _sometimes_ halt the target anyway, regardless of the
* value of the breakAfterAttach flag. So we still expect a stop event to be received shortly after issuing
@@ -1172,11 +1183,13 @@ void EdbgAvr8Interface::attach() {
this->waitForStoppedEvent();
} catch (const Exception& exception) {
Logger::error("Execution on AVR8 target could not be halted post attach - " + exception.getMessage());
Logger::error(
"Execution on AVR8 target could not be halted post attach - " + exception.getMessage()
);
}
}
}
void EdbgAvr8Interface::detach() {
void EdbgAvr8Interface::detach() {
auto commandFrame = CommandFrames::Avr8Generic::Detach();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
@@ -1185,9 +1198,9 @@ void EdbgAvr8Interface::detach() {
}
this->targetAttached = false;
}
}
std::unique_ptr<AvrEvent> EdbgAvr8Interface::getAvrEvent() {
std::unique_ptr<AvrEvent> EdbgAvr8Interface::getAvrEvent() {
auto event = this->edbgInterface.requestAvrEvent();
if (!event.has_value()) {
@@ -1207,18 +1220,18 @@ std::unique_ptr<AvrEvent> EdbgAvr8Interface::getAvrEvent() {
return std::make_unique<AvrEvent>(event.value());
}
}
}
}
void EdbgAvr8Interface::clearEvents() {
void EdbgAvr8Interface::clearEvents() {
while (this->getAvrEvent() != nullptr) {}
}
}
TargetMemoryBuffer EdbgAvr8Interface::readMemory(
TargetMemoryBuffer EdbgAvr8Interface::readMemory(
Avr8MemoryType type,
std::uint32_t startAddress,
std::uint32_t bytes,
const std::set<std::uint32_t>& excludedAddresses
) {
) {
if (!excludedAddresses.empty() && (this->avoidMaskedMemoryRead || type != Avr8MemoryType::SRAM)) {
/*
* Driver-side masked memory read.
@@ -1330,10 +1343,11 @@ TargetMemoryBuffer EdbgAvr8Interface::readMemory(
* aaaabbbbccccdddd
* ^
* But now we'll only be reading 4 bytes from start address 0x04, meaning we won't be reading
* that 4th byte (0x08). So we need to account for this by adding the difference of the requested start
* address and the aligned start address to the number of bytes to read, to ensure that we're reading
* all of the bytes that we're interested in. But this will throw off the aligned bytes!! So we need
* to also account for this by aligning the additional bytes before adding them to alignedBytesToRead.
* that 4th byte (0x08). So we need to account for this by adding the difference of the requested
* start address and the aligned start address to the number of bytes to read, to ensure that we're
* reading all of the bytes that we're interested in. But this will throw off the aligned bytes!!
* So we need to also account for this by aligning the additional bytes before adding them to
* alignedBytesToRead.
*
* However, we could simply get away with just adding the bytes without aligning
* them (alignedBytesToRead += (address - alignedAddress);), as the subsequent recursive call will
@@ -1404,7 +1418,8 @@ TargetMemoryBuffer EdbgAvr8Interface::readMemory(
if (type != Avr8MemoryType::FLASH_PAGE) {
/*
* EDBG AVR8 debug tools behave in a really weird way when responding with more than two packets
* for a single read (non-flash) memory command. The data they return in this case appears to be of little use.
* for a single read (non-flash) memory command. The data they return in this case appears to be of little
* use.
*
* To address this, we make sure we only issue read memory commands that will result in no more than two
* response packets. For calls that require more than this, we simply split them into numerous calls.
@@ -1421,14 +1436,16 @@ TargetMemoryBuffer EdbgAvr8Interface::readMemory(
if (totalResponsePackets > 2) {
/*
* This call to readMemory() will result in more than two response packets, so split it into multiple calls
* that will result in no more than two response packets per call.
* This call to readMemory() will result in more than two response packets, so split it into multiple
* calls that will result in no more than two response packets per call.
*/
auto output = std::vector<unsigned char>();
for (float i = 1; i <= totalReadsRequired; i++) {
auto bytesToRead = static_cast<std::uint32_t>((bytes - output.size()) > (singlePacketSize * 2) ?
(singlePacketSize * 2) : bytes - output.size());
auto bytesToRead = static_cast<std::uint32_t>(
(bytes - output.size()) > (singlePacketSize * 2) ? (singlePacketSize * 2)
: bytes - output.size()
);
auto data = this->readMemory(
type,
static_cast<std::uint32_t>(startAddress + output.size()),
@@ -1454,9 +1471,9 @@ TargetMemoryBuffer EdbgAvr8Interface::readMemory(
}
return response.getMemoryBuffer();
}
}
void EdbgAvr8Interface::writeMemory(Avr8MemoryType type, std::uint32_t address, const TargetMemoryBuffer& buffer) {
void EdbgAvr8Interface::writeMemory(Avr8MemoryType type, std::uint32_t address, const TargetMemoryBuffer& buffer) {
if (type == Avr8MemoryType::FLASH_PAGE) {
// TODO: Implement support for writing to flash
throw Exception("Writing to flash memory is not supported.");
@@ -1471,9 +1488,9 @@ void EdbgAvr8Interface::writeMemory(Avr8MemoryType type, std::uint32_t address,
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Write memory command failed", response);
}
}
}
void EdbgAvr8Interface::refreshTargetState() {
void EdbgAvr8Interface::refreshTargetState() {
auto avrEvent = this->getAvrEvent();
if (avrEvent != nullptr && avrEvent->getEventId() == AvrEventId::AVR8_BREAK_EVENT) {
@@ -1488,18 +1505,18 @@ void EdbgAvr8Interface::refreshTargetState() {
}
this->targetState = TargetState::RUNNING;
}
}
void EdbgAvr8Interface::disableDebugWire() {
void EdbgAvr8Interface::disableDebugWire() {
auto commandFrame = CommandFrames::Avr8Generic::DisableDebugWire();
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(commandFrame);
if (response.getResponseId() == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Disable debugWire command failed", response);
}
}
}
void EdbgAvr8Interface::waitForStoppedEvent() {
void EdbgAvr8Interface::waitForStoppedEvent() {
auto breakEvent = this->waitForAvrEvent<BreakEvent>();
if (breakEvent == nullptr) {
@@ -1507,4 +1524,5 @@ void EdbgAvr8Interface::waitForStoppedEvent() {
}
this->targetState = TargetState::STOPPED;
}
}

View File

@@ -2,13 +2,15 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Targets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void BreakEvent::init(const AvrEvent& event) {
using Bloom::Targets::TargetBreakCause;
void BreakEvent::init(const AvrEvent& event) {
AvrEvent::init(event);
auto& data = this->getEventData();
const auto& data = this->getEventData();
if (data.size() < 8) {
/*
@@ -22,8 +24,11 @@ void BreakEvent::init(const AvrEvent& event) {
}
// Program counter consists of 4 bytes
this->programCounter = static_cast<std::uint32_t>((data[4] << 24) | (data[3] << 16) | (data[2] << 8) | data[1]) * 2;
this->programCounter = static_cast<std::uint32_t>(
(data[4] << 24) | (data[3] << 16) | (data[2] << 8) | data[1]
) * 2;
// Break cause is 1 byte, where 0x01 is 'program breakpoint' and 0x00 'unspecified'
this->breakCause = data[7] == 0x01 ? TargetBreakCause::BREAKPOINT : TargetBreakCause::UNKNOWN;
}
}

View File

@@ -2,22 +2,23 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void AvrResponseFrame::initFromAvrResponses(const std::vector<AvrResponse>& avrResponses) {
void AvrResponseFrame::initFromAvrResponses(const std::vector<AvrResponse>& avrResponses) {
// Build a raw frame buffer from the AVRResponse objects and just call initFromRawFrame()
std::vector<unsigned char> rawFrame;
for (auto& avrResponse : avrResponses) {
for (const auto& avrResponse : avrResponses) {
auto responsePacket = avrResponse.getResponsePacket();
rawFrame.insert(rawFrame.end(), responsePacket.begin(), responsePacket.end());
}
return this->initFromRawFrame(rawFrame);
}
}
void AvrResponseFrame::initFromRawFrame(const std::vector<unsigned char>& rawFrame) {
void AvrResponseFrame::initFromRawFrame(const std::vector<unsigned char>& rawFrame) {
if (rawFrame.size() < 4) {
// All AVR response frames must consist of at least four bytes (SOF, sequence ID (two bytes) and
// a protocol handler ID)
@@ -34,4 +35,5 @@ void AvrResponseFrame::initFromRawFrame(const std::vector<unsigned char>& rawFra
auto& payload = this->getPayload();
payload.insert(payload.begin(), rawFrame.begin() + 4, rawFrame.end());
}
}

View File

@@ -4,15 +4,13 @@
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
using namespace Bloom::DebugToolDrivers;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg;
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg
{
using namespace Bloom::Exceptions;
Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForResponse(
Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForResponse(
const Protocols::CmsisDap::Edbg::Avr::AvrCommandFrame& avrCommandFrame
) {
) {
// An AVR command frame can be split into multiple CMSIS-DAP commands. Each command
// containing a fragment of the AvrCommandFrame.
@@ -25,8 +23,8 @@ Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForRespon
// Send command to device
auto response = this->sendCommandAndWaitForResponse(avrCommand);
if (&avrCommand ==& avrCommands.back()) {
return* response;
if (&avrCommand == &avrCommands.back()) {
return *response;
}
}
@@ -34,9 +32,9 @@ Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForRespon
throw DeviceCommunicationFailure(
"Cannot send AVR command frame - failed to generate CMSIS-DAP Vendor (AVR) commands"
);
}
}
Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() {
Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() {
auto cmsisResponse = this->getResponse();
if (cmsisResponse->getResponseId() == 0x81) {
@@ -44,12 +42,12 @@ Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() {
auto avrResponse = Protocols::CmsisDap::Edbg::Avr::AvrResponse();
avrResponse.init(*cmsisResponse);
return avrResponse;
} else {
}
throw DeviceCommunicationFailure("Unexpected response to AvrResponseCommand from device");
}
}
std::optional<Protocols::CmsisDap::Edbg::Avr::AvrEvent> EdbgInterface::requestAvrEvent() {
std::optional<Protocols::CmsisDap::Edbg::Avr::AvrEvent> EdbgInterface::requestAvrEvent() {
this->sendCommand(AvrEventCommand());
auto cmsisResponse = this->getResponse();
@@ -57,13 +55,15 @@ 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;
} else {
return avrEvent.getEventDataSize() > 0 ? std::optional(avrEvent) : std::nullopt;
}
throw DeviceCommunicationFailure("Unexpected response to AvrEventCommand from device");
}
}
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestAvrResponses() {
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestAvrResponses() {
using Protocols::CmsisDap::Edbg::Avr::AvrResponseCommand;
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> responses;
AvrResponseCommand responseCommand;
@@ -84,9 +84,12 @@ std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestA
}
if (response.getFragmentCount() == 0 && response.getFragmentNumber() == 0) {
throw DeviceCommunicationFailure("Failed to fetch AVRResponse objects - unexpected empty response");
throw DeviceCommunicationFailure(
"Failed to fetch AVRResponse objects - unexpected empty response"
);
}
} else if (response.getFragmentNumber() == 0) {
if (response.getFragmentNumber() == 0) {
// End of response data ( &this packet can be ignored)
break;
}
@@ -95,4 +98,5 @@ std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestA
}
return responses;
}
}

View File

@@ -5,10 +5,11 @@
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
using namespace Bloom::Usb;
using namespace Bloom::Exceptions;
namespace Bloom::Usb
{
using namespace Bloom::Exceptions;
void HidInterface::init() {
void HidInterface::init() {
if (this->libUsbDevice == nullptr) {
throw DeviceInitializationFailure("Cannot initialise interface without libusb device pointer.");
}
@@ -25,7 +26,8 @@ void HidInterface::init() {
if (hidDevice->input_ep_max_packet_size < 1) {
throw DeviceInitializationFailure(
"Invalid max packet size for USB endpoint, on interface " + std::to_string(this->getNumber())
"Invalid max packet size for USB endpoint, on interface "
+ std::to_string(this->getNumber())
);
}
@@ -33,9 +35,9 @@ void HidInterface::init() {
this->setInputReportSize(static_cast<std::size_t>(hidDevice->input_ep_max_packet_size));
this->libUsbDeviceHandle = hidDevice->device_handle;
this->initialised = true;
}
}
void HidInterface::close() {
void HidInterface::close() {
auto* hidDevice = this->getHidDevice();
if (hidDevice != nullptr) {
@@ -47,9 +49,9 @@ void HidInterface::close() {
hid_exit();
Interface::close();
}
}
std::vector<unsigned char> HidInterface::read(unsigned int timeout) {
std::vector<unsigned char> HidInterface::read(unsigned int timeout) {
std::vector<unsigned char> output;
auto readSize = this->getInputReportSize();
@@ -67,9 +69,9 @@ std::vector<unsigned char> HidInterface::read(unsigned int timeout) {
output.resize(totalByteCount);
return output;
}
}
void HidInterface::write(std::vector<unsigned char> buffer) {
void HidInterface::write(std::vector<unsigned char> buffer) {
if (buffer.size() > this->getInputReportSize()) {
throw DeviceCommunicationFailure(
"Cannot send data via HID interface - data exceeds maximum packet size."
@@ -92,9 +94,9 @@ void HidInterface::write(std::vector<unsigned char> buffer) {
+ " bytes to HID interface. Bytes written: " + std::to_string(transferred));
throw DeviceCommunicationFailure("Failed to write data to HID interface.");
}
}
}
std::size_t HidInterface::read(unsigned char* buffer, std::size_t maxLength, unsigned int timeout) {
std::size_t HidInterface::read(unsigned char* buffer, std::size_t maxLength, unsigned int timeout) {
int transferred;
if ((transferred = hid_read_timeout(
@@ -108,10 +110,13 @@ std::size_t HidInterface::read(unsigned char* buffer, std::size_t maxLength, uns
}
return static_cast<std::size_t>(transferred);
}
}
std::string HidInterface::getDevicePathByInterfaceNumber(const std::uint16_t& interfaceNumber) {
hid_device_info* hidDeviceInfoList = hid_enumerate(this->getVendorId(), this->getProductId());
std::string HidInterface::getDevicePathByInterfaceNumber(const std::uint16_t& interfaceNumber) {
hid_device_info* hidDeviceInfoList = hid_enumerate(
this->getVendorId(),
this->getProductId()
);
while (hidDeviceInfoList != nullptr) {
if (hidDeviceInfoList->interface_number == interfaceNumber) {
@@ -128,4 +133,5 @@ std::string HidInterface::getDevicePathByInterfaceNumber(const std::uint16_t& in
auto path = std::string(hidDeviceInfoList->path);
hid_free_enumeration(hidDeviceInfoList);
return path;
}
}

View File

@@ -1,16 +1,16 @@
#include "Interface.hpp"
#include <libusb-1.0/libusb.h>
#include <chrono>
#include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::Usb;
using namespace Bloom::Exceptions;
namespace Bloom::Usb
{
using namespace Bloom::Exceptions;
void Interface::init() {
void Interface::init() {
if (this->libUsbDevice == nullptr) {
throw DeviceInitializationFailure("Cannot initialise interface without libusb device pointer.");
}
@@ -20,17 +20,17 @@ void Interface::init() {
}
this->initialised = true;
}
}
void Interface::close() {
void Interface::close() {
if (this->libUsbDeviceHandle != nullptr) {
this->release();
}
this->initialised = false;
}
}
void Interface::claim() {
void Interface::claim() {
int interfaceNumber = this->getNumber();
this->detachKernelDriver();
@@ -42,9 +42,9 @@ void Interface::claim() {
}
this->claimed = true;
}
}
void Interface::detachKernelDriver() {
void Interface::detachKernelDriver() {
int interfaceNumber = this->getNumber();
int libUsbStatusCode;
@@ -59,21 +59,22 @@ void Interface::detachKernelDriver() {
throw DeviceInitializationFailure("Failed to check for active kernel driver on USB interface.");
}
}
}
}
void Interface::release() {
void Interface::release() {
if (this->isClaimed()) {
if (libusb_release_interface(this->libUsbDeviceHandle, this->getNumber()) != 0) {
throw DeviceFailure(
"Failed to release interface {" + std::to_string(this->getNumber()) + "} on USB device\n"
"Failed to release interface {" + std::to_string(this->getNumber())
+ "} on USB device\n"
);
}
this->claimed = false;
}
}
}
int Interface::read(unsigned char* buffer, unsigned char endPoint, size_t length, size_t timeout) {
int Interface::read(unsigned char* buffer, unsigned char endPoint, size_t length, size_t timeout) {
int totalTransferred = 0;
int transferred = 0;
int libUsbStatusCode = 0;
@@ -98,9 +99,9 @@ int Interface::read(unsigned char* buffer, unsigned char endPoint, size_t length
}
return transferred;
}
}
void Interface::write(unsigned char* buffer, unsigned char endPoint, int length) {
void Interface::write(unsigned char* buffer, unsigned char endPoint, int length) {
int transferred = 0;
int libUsbStatusCode = 0;
@@ -118,4 +119,5 @@ void Interface::write(unsigned char* buffer, unsigned char endPoint, int length)
"Failed to read from USB device. Error code returned: " + std::to_string(libUsbStatusCode)
);
}
}
}

View File

@@ -3,18 +3,20 @@
#include "src/Logger/Logger.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using Bloom::Usb::UsbDevice;
using namespace Bloom::Exceptions;
namespace Bloom::Usb
{
using namespace Bloom::Exceptions;
void UsbDevice::init() {
void UsbDevice::init() {
libusb_init(&this->libUsbContext);
// libusb_set_option(this->libUsbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
auto devices = this->findMatchingDevices();
if (devices.empty()) {
throw DeviceInitializationFailure("Failed to find USB device with matching vendor & product ID.");
}
} else if (devices.size() > 1) {
if (devices.size() > 1) {
// TODO: implement support for multiple devices (maybe via serial number?)
throw DeviceInitializationFailure(
"Numerous devices of matching vendor & product ID found.\n"
@@ -23,57 +25,59 @@ void UsbDevice::init() {
}
// For now, just use the first device found.
auto device = devices.front();
auto* device = devices.front();
this->setLibUsbDevice(device);
int libUsbStatusCode;
const int libUsbStatusCode = libusb_open(libUsbDevice, &this->libUsbDeviceHandle);
// Obtain a device handle from libusb
if ((libUsbStatusCode = libusb_open(libUsbDevice, &this->libUsbDeviceHandle)) < 0) {
if (libUsbStatusCode < 0) {
throw DeviceInitializationFailure(
"Failed to open USB device - error code " + std::to_string(libUsbStatusCode) + " returned."
);
}
}
}
void UsbDevice::setConfiguration(int configIndex) {
void UsbDevice::setConfiguration(int configIndex) {
libusb_config_descriptor* configDescriptor = {};
int libUsbStatusCode;
int libUsbStatusCode = libusb_get_config_descriptor(this->libUsbDevice, 0, &configDescriptor);
if ((libUsbStatusCode = libusb_get_config_descriptor(this->libUsbDevice, 0, &configDescriptor))) {
if (libUsbStatusCode < 0) {
throw DeviceInitializationFailure(
"Failed to obtain USB configuration descriptor - error code " + std::to_string(libUsbStatusCode)
+ " returned."
);
}
if ((libUsbStatusCode = libusb_set_configuration(this->libUsbDeviceHandle, configDescriptor->bConfigurationValue))) {
libUsbStatusCode = libusb_set_configuration(this->libUsbDeviceHandle, configDescriptor->bConfigurationValue);
if (libUsbStatusCode < 0) {
throw DeviceInitializationFailure(
"Failed to set USB configuration - error code " + std::to_string(libUsbStatusCode) + " returned."
);
}
libusb_free_config_descriptor(configDescriptor);
}
}
std::vector<libusb_device*> UsbDevice::findMatchingDevices(
std::vector<libusb_device*> UsbDevice::findMatchingDevices(
std::optional<std::uint16_t> vendorId, std::optional<std::uint16_t> productId
) {
auto libUsbContext = this->libUsbContext;
) {
auto* libUsbContext = this->libUsbContext;
libusb_device** devices = nullptr;
libusb_device* device;
std::vector<libusb_device*> matchedDevices;
ssize_t i = 0, libUsbStatusCode;
auto vendorIdToMatch = vendorId.value_or(this->vendorId);
auto productIdToMatch = productId.value_or(this->productId);
if ((libUsbStatusCode = libusb_get_device_list(libUsbContext, &devices)) < 0) {
ssize_t libUsbStatusCode = libusb_get_device_list(libUsbContext, &devices);
if (libUsbStatusCode < 0) {
throw DeviceInitializationFailure(
"Failed to retrieve USB devices - return code: '" + std::to_string(libUsbStatusCode) + "'"
);
}
ssize_t i = 0;
while ((device = devices[i++]) != nullptr) {
struct libusb_device_descriptor desc = {};
@@ -90,9 +94,9 @@ std::vector<libusb_device*> UsbDevice::findMatchingDevices(
libusb_free_device_list(devices, 1);
return matchedDevices;
}
}
void UsbDevice::close() {
void UsbDevice::close() {
if (this->libUsbDeviceHandle != nullptr) {
libusb_close(this->libUsbDeviceHandle);
this->libUsbDeviceHandle = nullptr;
@@ -101,4 +105,5 @@ void UsbDevice::close() {
if (this->libUsbContext != nullptr) {
libusb_exit(this->libUsbContext);
}
}
}

View File

@@ -2,14 +2,15 @@
#include "src/Logger/Logger.hpp"
using namespace Bloom;
using namespace Bloom::Events;
namespace Bloom
{
using namespace Bloom::Events;
std::set<Events::EventType> EventListener::getRegisteredEventTypes() {
std::set<Events::EventType> EventListener::getRegisteredEventTypes() {
return this->registeredEventTypes.getValue();
}
}
void EventListener::registerEvent(SharedGenericEventPointer event) {
void EventListener::registerEvent(SharedGenericEventPointer event) {
Logger::debug("Event \"" + event->getName() + "\" (" + std::to_string(event->id)
+ ") registered for listener " + this->name);
auto queueLock = this->eventQueueByEventType.acquireLock();
@@ -21,15 +22,15 @@ void EventListener::registerEvent(SharedGenericEventPointer event) {
if (this->interruptEventNotifier != nullptr && this->interruptEventNotifier->isInitialised()) {
this->interruptEventNotifier->notify();
}
}
}
void EventListener::waitAndDispatch(int msTimeout) {
void EventListener::waitAndDispatch(int msTimeout) {
auto queueLock = this->eventQueueByEventType.acquireLock();
auto& eventQueueByType = this->eventQueueByEventType.getReference();
auto registeredEventTypes = this->getRegisteredEventTypes();
std::optional<SharedGenericEventPointer> event;
auto eventsFound = [&registeredEventTypes, &event, &eventQueueByType] () -> bool {
auto eventsFound = [&registeredEventTypes, &event, &eventQueueByType]() -> bool {
for (auto& eventQueue: eventQueueByType) {
if (registeredEventTypes.contains(eventQueue.first) && !eventQueue.second.empty()) {
return true;
@@ -52,10 +53,11 @@ void EventListener::waitAndDispatch(int msTimeout) {
queueLock.unlock();
this->dispatchCurrentEvents();
}
}
void EventListener::dispatchEvent(const SharedGenericEventPointer& event) {
void EventListener::dispatchEvent(const SharedGenericEventPointer& event) {
Logger::debug("Dispatching event " + event->getName() + " (" + std::to_string(event->id) + ").");
// Dispatch the event to all registered handlers
auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
auto& callbacks = this->eventTypeToCallbacksMapping.getReference().find(event->getType())->second;
@@ -64,17 +66,17 @@ void EventListener::dispatchEvent(const SharedGenericEventPointer& event) {
for (auto& callback : callbacks) {
callback(*(event.get()));
}
}
}
void EventListener::dispatchCurrentEvents() {
void EventListener::dispatchCurrentEvents() {
auto events = this->getEvents();
for (const auto& event: events) {
dispatchEvent(event);
}
}
}
std::vector<SharedGenericEventPointer> EventListener::getEvents() {
std::vector<SharedGenericEventPointer> EventListener::getEvents() {
auto queueLock = this->eventQueueByEventType.acquireLock();
auto& eventQueueByType = this->eventQueueByEventType.getReference();
std::vector<SharedGenericEventPointer> output;
@@ -86,14 +88,19 @@ std::vector<SharedGenericEventPointer> EventListener::getEvents() {
}
}
std::sort(output.begin(), output.end(), [] (const SharedGenericEventPointer& a, const SharedGenericEventPointer& b) {
std::sort(
output.begin(),
output.end(),
[](const SharedGenericEventPointer& a, const SharedGenericEventPointer& b) {
return a->id < b->id;
});
}
);
return output;
}
}
void EventListener::clearAllCallbacks() {
void EventListener::clearAllCallbacks() {
auto lock = this->eventTypeToCallbacksMapping.acquireLock();
this->eventTypeToCallbacksMapping.getReference().clear();
}
}

View File

@@ -1,35 +1,36 @@
#include "EventManager.hpp"
using namespace Bloom;
void EventManager::registerListener(std::shared_ptr<EventListener> listener) {
namespace Bloom
{
void EventManager::registerListener(std::shared_ptr<EventListener> listener) {
auto registerListenersLock = std::unique_lock(this->registerListenerMutex);
this->registeredListeners.insert(std::pair(listener->getId(), std::move(listener)));
}
}
void EventManager::deregisterListener(size_t listenerId) {
void EventManager::deregisterListener(size_t listenerId) {
auto registerListenersLock = std::unique_lock(this->registerListenerMutex);
this->registeredListeners.erase(listenerId);
}
}
void EventManager::triggerEvent(const std::shared_ptr<const Events::Event>& event) {
void EventManager::triggerEvent(const std::shared_ptr<const Events::Event>& event) {
auto registerListenersLock = std::unique_lock(this->registerListenerMutex);
for(const auto& [listenerId, listener] : this->registeredListeners) {
for (const auto&[listenerId, listener] : this->registeredListeners) {
if (listener->isEventTypeRegistered(event->getType())) {
listener->registerEvent(event);
}
}
}
}
bool EventManager::isEventTypeListenedFor(Events::EventType eventType) {
bool EventManager::isEventTypeListenedFor(Events::EventType eventType) {
auto registerListenersLock = std::unique_lock(this->registerListenerMutex);
for(const auto& [listenerId, listener] : this->registeredListeners) {
for (const auto&[listenerId, listener] : this->registeredListeners) {
if (listener->isEventTypeRegistered(eventType)) {
return true;
}
}
return false;
}
}

View File

@@ -7,9 +7,9 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom;
std::string Paths::applicationDirPath() {
namespace Bloom
{
std::string Paths::applicationDirPath() {
auto pathCharArray = std::array<char, PATH_MAX>();
if (readlink("/proc/self/exe", pathCharArray.data(), PATH_MAX) < 0) {
@@ -17,4 +17,5 @@ std::string Paths::applicationDirPath() {
}
return std::filesystem::path(std::string(pathCharArray.begin(), pathCharArray.end())).parent_path();
}
}

View File

@@ -10,10 +10,11 @@
#include "src/Application.hpp"
#include "InsightWorker/Tasks/QueryLatestVersionNumber.hpp"
using namespace Bloom;
using namespace Bloom::Exceptions;
namespace Bloom
{
using namespace Bloom::Exceptions;
void Insight::run() {
void Insight::run() {
try {
this->startup();
@@ -32,9 +33,9 @@ void Insight::run() {
}
this->shutdown();
}
}
void Insight::startup() {
void Insight::startup() {
Logger::info("Starting Insight");
this->setThreadState(ThreadState::STARTING);
this->eventManager.registerListener(this->eventListener);
@@ -146,9 +147,9 @@ void Insight::startup() {
});
this->mainWindow->show();
}
}
void Insight::shutdown() {
void Insight::shutdown() {
if (this->getThreadState() == ThreadState::STOPPED) {
return;
}
@@ -163,9 +164,9 @@ void Insight::shutdown() {
this->application.exit(0);
this->setThreadState(ThreadState::STOPPED);
}
}
void Insight::checkBloomVersion() {
void Insight::checkBloomVersion() {
auto currentVersionNumber = Application::VERSION;
auto* versionQueryTask = new QueryLatestVersionNumber(
@@ -187,26 +188,27 @@ void Insight::checkBloomVersion() {
);
this->insightWorker->queueTask(versionQueryTask);
}
}
void Insight::onShutdownApplicationEvent(const Events::ShutdownApplication&) {
void Insight::onShutdownApplicationEvent(const Events::ShutdownApplication&) {
/*
* Once Insight shuts down, control of the main thread will be returned to Application::run(), which
* will pickup the ShutdownApplication event and proceed with the shutdown.
*/
this->shutdown();
}
}
void Insight::onTargetControllerThreadStateChangedEvent(const Events::TargetControllerThreadStateChanged& event) {
void Insight::onTargetControllerThreadStateChangedEvent(const Events::TargetControllerThreadStateChanged& event) {
if (event.getState() == ThreadState::STOPPED) {
// Something horrible has happened with the TargetController - Insight is useless without the TargetController
this->shutdown();
}
}
}
void Insight::onDebugServerThreadStateChangedEvent(const Events::DebugServerThreadStateChanged& event) {
void Insight::onDebugServerThreadStateChangedEvent(const Events::DebugServerThreadStateChanged& event) {
if (event.getState() == ThreadState::STOPPED) {
// Something horrible has happened with the DebugServer
this->shutdown();
}
}
}

View File

@@ -6,22 +6,23 @@
#include "src/Helpers/Thread.hpp"
#include "src/Logger/Logger.hpp"
using namespace Bloom;
using namespace Bloom::Exceptions;
namespace Bloom
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetState;
InsightWorker::InsightWorker(EventManager& eventManager): eventManager(eventManager) {}
InsightWorker::InsightWorker(EventManager& eventManager): eventManager(eventManager) {}
void InsightWorker::queueTask(InsightWorkerTask* task) {
void InsightWorker::queueTask(InsightWorkerTask* task) {
auto taskQueueLock = this->queuedTasks.acquireLock();
task->moveToThread(this->thread());
task->setParent(this);
this->queuedTasks.getReference().push(task);
emit this->taskQueued();
}
}
void InsightWorker::startup() {
void InsightWorker::startup() {
Logger::debug("Starting InsightWorker thread");
this->eventManager.registerListener(this->eventListener);
@@ -52,13 +53,13 @@ void InsightWorker::startup() {
);
emit this->ready();
}
}
void InsightWorker::requestPinStates(int variantId) {
void InsightWorker::requestPinStates(int variantId) {
this->targetControllerConsole.requestPinStates(variantId);
}
}
std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() {
std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() {
auto task = std::optional<InsightWorkerTask*>();
auto& queuedTasks = this->queuedTasks.getReference();
@@ -70,29 +71,30 @@ std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() {
}
return task;
}
}
void InsightWorker::onTargetStoppedEvent(const Events::TargetExecutionStopped& event) {
void InsightWorker::onTargetStoppedEvent(const Events::TargetExecutionStopped& event) {
/*
* When we report a target halt to Insight, Insight will immediately seek more data from the target (such as GPIO
* pin states). This can be problematic for cases where the target had halted due to a conditional breakpoint.
* When we report a target halt to Insight, Insight will immediately seek more data from the target (such as
* GPIO pin states). This can be problematic for cases where the target had halted due to a conditional
* breakpoint.
*
* For conditional breakpoints, a software breakpoint is employed to halt target execution and give the debug
* client an opportunity to check the condition. In cases where the condition is not met, the client will
* immediately request for execution to be resumed. It's important that Insight does not get in the way of this
* process, as it could end up slowing things down significantly.
*
* For the above reason, we don't want to report any target halts to Insight, unless we can be sure that the client
* isn't going to immediately resume execution upon checking the condition.
* For the above reason, we don't want to report any target halts to Insight, unless we can be sure that the
* client isn't going to immediately resume execution upon checking the condition.
*
* We do this by providing a time window for the TargetExecutionResumed event. If the event is triggered within
* that time window, we won't report the target halt to Insight, thus preventing Insight from needlessly seeking
* data from the target and slowing things down.
* that time window, we won't report the target halt to Insight, thus preventing Insight from needlessly
* seeking data from the target and slowing things down.
*
* This isn't the best approach, TBH, as it introduces a delay to Insight's response to the target halting. The
* problem is, we cannot differentiate a conditional breakpoint with a software breakpoint, so this seems to be the
* only way. It would be nice if the debug client gave us some form of indication of whether the breakpoint is a
* conditional one.
* problem is, we cannot differentiate a conditional breakpoint with a software breakpoint, so this seems to be
* the only way. It would be nice if the debug client gave us some form of indication of whether the breakpoint
* is a conditional one.
*/
auto resumedEvent = this->eventListener->waitForEvent<Events::TargetExecutionResumed>(
std::chrono::milliseconds(650)
@@ -102,17 +104,17 @@ void InsightWorker::onTargetStoppedEvent(const Events::TargetExecutionStopped& e
emit this->targetStateUpdated(TargetState::STOPPED);
emit this->targetProgramCounterUpdated(event.programCounter);
}
}
}
void InsightWorker::onTargetResumedEvent(const Events::TargetExecutionResumed& event) {
void InsightWorker::onTargetResumedEvent(const Events::TargetExecutionResumed& event) {
emit this->targetStateUpdated(TargetState::RUNNING);
}
}
void InsightWorker::onTargetRegistersWrittenEvent(const Events::RegistersWrittenToTarget& event) {
void InsightWorker::onTargetRegistersWrittenEvent(const Events::RegistersWrittenToTarget& event) {
emit this->targetRegistersWritten(event.registers, event.createdTimestamp);
}
}
void InsightWorker::onTargetControllerStateReportedEvent(const Events::TargetControllerStateReported& event) {
void InsightWorker::onTargetControllerStateReportedEvent(const Events::TargetControllerStateReported& event) {
if (this->lastTargetControllerState == TargetControllerState::ACTIVE
&& event.state == TargetControllerState::SUSPENDED
) {
@@ -129,12 +131,13 @@ void InsightWorker::onTargetControllerStateReportedEvent(const Events::TargetCon
}
}
this->lastTargetControllerState = event.state;
}
}
void InsightWorker::executeTasks() {
void InsightWorker::executeTasks() {
auto task = std::optional<InsightWorkerTask*>();
while ((task = this->getQueuedTask()).has_value()) {
task.value()->execute(this->targetControllerConsole);
}
}
}

View File

@@ -2,9 +2,9 @@
#include "src/Logger/Logger.hpp"
using namespace Bloom;
void InsightWorkerTask::execute(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void InsightWorkerTask::execute(TargetControllerConsole& targetControllerConsole) {
try {
this->state = InsightWorkerTaskState::STARTED;
emit this->started();
@@ -17,4 +17,5 @@ void InsightWorkerTask::execute(TargetControllerConsole& targetControllerConsole
Logger::error("InsightWorker task failed - " + std::string(exception.what()));
emit this->failed(QString::fromStdString(exception.what()));
}
}
}

View File

@@ -9,9 +9,9 @@
#include "src/Helpers/Paths.hpp"
using namespace Bloom;
void QueryLatestVersionNumber::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void QueryLatestVersionNumber::run(TargetControllerConsole& targetControllerConsole) {
auto* networkAccessManager = new QNetworkAccessManager(this);
auto queryVersionEndpointUrl = QUrl(QString::fromStdString(Paths::homeDomainName() + "/latest-version"));
queryVersionEndpointUrl.setScheme("http");
@@ -31,4 +31,5 @@ void QueryLatestVersionNumber::run(TargetControllerConsole& targetControllerCons
);
}
});
}
}

View File

@@ -1,7 +1,8 @@
#include "ReadStackPointer.hpp"
using namespace Bloom;
void ReadStackPointer::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void ReadStackPointer::run(TargetControllerConsole& targetControllerConsole) {
emit this->stackPointerRead(targetControllerConsole.getStackPointer());
}
}

View File

@@ -1,8 +1,8 @@
#include "ReadTargetMemory.hpp"
using namespace Bloom;
void ReadTargetMemory::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void ReadTargetMemory::run(TargetControllerConsole& targetControllerConsole) {
emit this->targetMemoryRead(
targetControllerConsole.readMemory(
this->memoryType,
@@ -11,4 +11,5 @@ void ReadTargetMemory::run(TargetControllerConsole& targetControllerConsole) {
this->excludedAddressRanges
)
);
}
}

View File

@@ -1,7 +1,8 @@
#include "ReadTargetRegisters.hpp"
using namespace Bloom;
void ReadTargetRegisters::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void ReadTargetRegisters::run(TargetControllerConsole& targetControllerConsole) {
emit this->targetRegistersRead(targetControllerConsole.readRegisters(this->descriptors));
}
}

View File

@@ -1,7 +1,8 @@
#include "RefreshTargetPinStates.hpp"
using namespace Bloom;
void RefreshTargetPinStates::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void RefreshTargetPinStates::run(TargetControllerConsole& targetControllerConsole) {
emit this->targetPinStatesRetrieved(targetControllerConsole.getPinStates(this->variantId));
}
}

View File

@@ -1,7 +1,8 @@
#include "SetTargetPinState.hpp"
using namespace Bloom;
void SetTargetPinState::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void SetTargetPinState::run(TargetControllerConsole& targetControllerConsole) {
targetControllerConsole.setPinState(this->pinDescriptor, this->pinState);
}
}

View File

@@ -1,7 +1,8 @@
#include "WriteTargetRegister.hpp"
using namespace Bloom;
void WriteTargetRegister::run(TargetControllerConsole& targetControllerConsole) {
namespace Bloom
{
void WriteTargetRegister::run(TargetControllerConsole& targetControllerConsole) {
targetControllerConsole.writeRegisters({this->targetRegister});
}
}

View File

@@ -6,10 +6,11 @@
#include "src/Helpers/Paths.hpp"
#include "src/Application.hpp"
using namespace Bloom;
using namespace Exceptions;
namespace Bloom
{
using namespace Exceptions;
AboutWindow::AboutWindow(QWidget* parent): QObject(parent) {
AboutWindow::AboutWindow(QWidget* parent): QObject(parent) {
auto aboutWindowUiFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui"
@@ -39,4 +40,5 @@ AboutWindow::AboutWindow(QWidget* parent): QObject(parent) {
if (versionLabel != nullptr) {
versionLabel->setText("Bloom v" + QString::fromStdString(Application::VERSION.toString()));
}
}
}

View File

@@ -1,16 +1,17 @@
#include "BloomProxyStyle.hpp"
using namespace Bloom;
int BloomProxyStyle::styleHint(
namespace Bloom
{
int BloomProxyStyle::styleHint(
StyleHint hint,
const QStyleOption* option,
const QWidget* widget,
QStyleHintReturn* returnData
) const {
) const {
if (hint == QStyle::SH_ComboBox_Popup) {
return 0;
}
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
}

View File

@@ -15,31 +15,32 @@
#include "src/Helpers/Paths.hpp"
#include "src/Targets/TargetDescriptor.hpp"
using namespace Bloom;
using namespace Bloom::Exceptions;
using namespace Bloom::Widgets;
namespace Bloom
{
using namespace Bloom::Exceptions;
using namespace Bloom::Widgets;
using Bloom::Targets::TargetDescriptor;
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetPinState;
using Bloom::Targets::TargetVariant;
using Bloom::Targets::TargetPackage;
using Bloom::Targets::TargetPinDescriptor;
using Bloom::Targets::TargetMemoryType;
using Bloom::Targets::TargetDescriptor;
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetPinState;
using Bloom::Targets::TargetVariant;
using Bloom::Targets::TargetPackage;
using Bloom::Targets::TargetPinDescriptor;
using Bloom::Targets::TargetMemoryType;
InsightWindow::InsightWindow(
InsightWindow::InsightWindow(
InsightWorker& insightWorker,
const EnvironmentConfig& environmentConfig,
const InsightConfig& insightConfig,
InsightProjectSettings& insightProjectSettings
):
QMainWindow(nullptr),
insightWorker(insightWorker),
environmentConfig(environmentConfig),
targetConfig(environmentConfig.targetConfig),
insightConfig(insightConfig),
insightProjectSettings(insightProjectSettings)
{
)
: QMainWindow(nullptr)
, insightWorker(insightWorker)
, environmentConfig(environmentConfig)
, targetConfig(environmentConfig.targetConfig)
, insightConfig(insightConfig)
, insightProjectSettings(insightProjectSettings)
{
this->setObjectName("main-window");
this->setWindowTitle("Bloom Insight");
@@ -212,34 +213,34 @@ InsightWindow::InsightWindow(
this,
&InsightWindow::onTargetProgramCounterUpdate
);
}
}
void InsightWindow::init(TargetDescriptor targetDescriptor) {
void InsightWindow::init(TargetDescriptor targetDescriptor) {
this->targetDescriptor = std::move(targetDescriptor);
this->activate();
}
}
void InsightWindow::resizeEvent(QResizeEvent* event) {
void InsightWindow::resizeEvent(QResizeEvent* event) {
const auto windowSize = this->size();
this->windowContainer->setFixedSize(windowSize);
this->layoutContainer->setFixedSize(windowSize);
this->adjustPanels();
}
}
void InsightWindow::showEvent(QShowEvent* event) {
void InsightWindow::showEvent(QShowEvent* event) {
this->adjustPanels();
this->adjustMinimumSize();
}
}
void InsightWindow::closeEvent(QCloseEvent* event) {
void InsightWindow::closeEvent(QCloseEvent* event) {
this->insightProjectSettings.mainWindowSize = this->size();
return QMainWindow::closeEvent(event);
}
}
bool InsightWindow::isVariantSupported(const TargetVariant& variant) {
bool InsightWindow::isVariantSupported(const TargetVariant& variant) {
const auto pinCount = variant.pinDescriptorsByNumber.size();
/*
@@ -273,18 +274,18 @@ bool InsightWindow::isVariantSupported(const TargetVariant& variant) {
}
return false;
}
}
void InsightWindow::setUiDisabled(bool disable) {
void InsightWindow::setUiDisabled(bool disable) {
this->uiDisabled = disable;
if (this->refreshIoInspectionButton != nullptr) {
this->refreshIoInspectionButton->setDisabled(disable);
this->refreshIoInspectionButton->repaint();
}
}
}
void InsightWindow::activate() {
void InsightWindow::activate() {
this->targetNameLabel->setText(QString::fromStdString(this->targetDescriptor.name));
this->targetIdLabel->setText("0x" + QString::fromStdString(this->targetDescriptor.id).remove("0x").toUpper());
@@ -315,9 +316,9 @@ void InsightWindow::activate() {
this->setUiDisabled(this->targetState != TargetState::STOPPED);
this->activated = true;
}
}
void InsightWindow::populateVariantMenu() {
void InsightWindow::populateVariantMenu() {
/*
* We don't want to present the user with duplicate target variants.
*
@@ -379,9 +380,9 @@ void InsightWindow::populateVariantMenu() {
this->variantMenu->addAction(variantAction);
processedVariants.push_back(targetVariant);
}
}
}
void InsightWindow::selectDefaultVariant() {
void InsightWindow::selectDefaultVariant() {
if (this->supportedVariantsByName.empty()) {
return;
}
@@ -414,9 +415,9 @@ void InsightWindow::selectDefaultVariant() {
*/
this->selectVariant(&(this->supportedVariantsByName.begin()->second));
}
}
}
void InsightWindow::selectVariant(const TargetVariant* variant) {
void InsightWindow::selectVariant(const TargetVariant* variant) {
if (!this->isVariantSupported(*variant)) {
Logger::error("Attempted to select unsupported target variant.");
return;
@@ -471,9 +472,9 @@ void InsightWindow::selectVariant(const TargetVariant* variant) {
this->adjustMinimumSize();
this->targetPackageWidget->show();
}
}
}
void InsightWindow::createPanes() {
void InsightWindow::createPanes() {
// Target registers pane
auto* leftPanelLayout = this->leftPanel->layout();
this->targetRegistersSidePane = new TargetRegistersPaneWidget(
@@ -529,9 +530,9 @@ void InsightWindow::createPanes() {
this->eepromInspectionButton->setChecked(false);
this->eepromInspectionButton->setDisabled(false);
}
}
}
void InsightWindow::destroyPanes() {
void InsightWindow::destroyPanes() {
if (this->targetRegistersSidePane != nullptr) {
this->targetRegistersSidePane->deactivate();
this->targetRegistersSidePane->deleteLater();
@@ -541,8 +542,8 @@ void InsightWindow::destroyPanes() {
}
/*
* Before we destroy the memory inspection pane widgets, we take a copy of their current settings (memory regions,
* hex viewer settings, etc), in order to persist them through debug sessions.
* Before we destroy the memory inspection pane widgets, we take a copy of their current settings (memory
* regions, hex viewer settings, etc), in order to persist them through debug sessions.
*/
if (this->ramInspectionPane != nullptr) {
this->ramInspectionPane->deactivate();
@@ -563,9 +564,9 @@ void InsightWindow::destroyPanes() {
this->eepromInspectionButton->setChecked(false);
this->eepromInspectionButton->setDisabled(true);
}
}
}
void InsightWindow::deactivate() {
void InsightWindow::deactivate() {
if (this->selectedVariant != nullptr) {
this->previouslySelectedVariant = *(this->selectedVariant);
this->selectedVariant = nullptr;
@@ -596,9 +597,9 @@ void InsightWindow::deactivate() {
this->setUiDisabled(true);
this->activated = false;
}
}
void InsightWindow::adjustPanels() {
void InsightWindow::adjustPanels() {
const auto targetPackageWidgetSize = (this->targetPackageWidget != nullptr)
? this->targetPackageWidget->size() : QSize();
const auto containerSize = this->container->size();
@@ -624,9 +625,9 @@ void InsightWindow::adjustPanels() {
(containerSize.height() / 2) - this->bottomMenuBar->height()
)
);
}
}
void InsightWindow::adjustMinimumSize() {
void InsightWindow::adjustMinimumSize() {
auto minSize = QSize(800, 500);
if (this->targetPackageWidget != nullptr) {
@@ -639,22 +640,22 @@ void InsightWindow::adjustMinimumSize() {
}
this->setMinimumSize(minSize);
}
}
void InsightWindow::onTargetControllerSuspended() {
void InsightWindow::onTargetControllerSuspended() {
if (this->activated) {
this->deactivate();
}
}
}
void InsightWindow::onTargetControllerResumed(const TargetDescriptor& targetDescriptor) {
void InsightWindow::onTargetControllerResumed(const TargetDescriptor& targetDescriptor) {
if (!this->activated) {
this->targetDescriptor = targetDescriptor;
this->activate();
}
}
}
void InsightWindow::onTargetStateUpdate(TargetState newState) {
void InsightWindow::onTargetStateUpdate(TargetState newState) {
this->targetState = newState;
if (newState == TargetState::RUNNING) {
@@ -669,15 +670,15 @@ void InsightWindow::onTargetStateUpdate(TargetState newState) {
} else {
this->targetStatusLabel->setText("Unknown");
}
}
}
void InsightWindow::onTargetProgramCounterUpdate(quint32 programCounter) {
void InsightWindow::onTargetProgramCounterUpdate(quint32 programCounter) {
this->programCounterValueLabel->setText(
"0x" + QString::number(programCounter, 16).toUpper() + " (" + QString::number(programCounter) + ")"
);
}
}
void InsightWindow::refresh() {
void InsightWindow::refresh() {
if (this->targetState != TargetState::STOPPED || this->selectedVariant == nullptr) {
return;
}
@@ -705,9 +706,9 @@ void InsightWindow::refresh() {
this->setUiDisabled(false);
});
}
}
}
void InsightWindow::openReportIssuesUrl() {
void InsightWindow::openReportIssuesUrl() {
auto url = QUrl(QString::fromStdString(Paths::homeDomainName() + "/report-issue"));
/*
* The https://bloom.oscillate.io/report-issue URL just redirects to the Bloom GitHub issue page.
@@ -730,28 +731,30 @@ void InsightWindow::openReportIssuesUrl() {
url.setQuery(urlQuery);
QDesktopServices::openUrl(url);
}
}
void InsightWindow::openGettingStartedUrl() {
QDesktopServices::openUrl(QUrl(QString::fromStdString(Paths::homeDomainName() + "/docs/getting-started")));
}
void InsightWindow::openGettingStartedUrl() {
QDesktopServices::openUrl(
QUrl(QString::fromStdString(Paths::homeDomainName() + "/docs/getting-started"))
);
}
void InsightWindow::openAboutWindow() {
void InsightWindow::openAboutWindow() {
if (this->aboutWindowWidget == nullptr) {
this->aboutWindowWidget = new AboutWindow(this);
}
this->aboutWindowWidget->show();
}
}
void InsightWindow::toggleTargetRegistersPane() {
void InsightWindow::toggleTargetRegistersPane() {
if (this->targetRegistersSidePane->activated) {
this->targetRegistersSidePane->deactivate();
this->targetRegistersButton->setChecked(false);
/*
* Given that the target registers side pane is currently the only pane in the left panel, the panel will be
* empty so no need to leave it visible.
* Given that the target registers side pane is currently the only pane in the left panel, the panel
* will be empty so no need to leave it visible.
*/
this->leftPanel->setVisible(false);
@@ -760,9 +763,9 @@ void InsightWindow::toggleTargetRegistersPane() {
this->targetRegistersButton->setChecked(true);
this->leftPanel->setVisible(true);
}
}
}
void InsightWindow::toggleRamInspectionPane() {
void InsightWindow::toggleRamInspectionPane() {
if (this->ramInspectionPane->activated) {
this->ramInspectionPane->deactivate();
this->bottomPanel->hide();
@@ -779,9 +782,9 @@ void InsightWindow::toggleRamInspectionPane() {
}
this->adjustMinimumSize();
}
}
void InsightWindow::toggleEepromInspectionPane() {
void InsightWindow::toggleEepromInspectionPane() {
if (this->eepromInspectionPane->activated) {
this->eepromInspectionPane->deactivate();
this->bottomPanel->hide();
@@ -798,4 +801,5 @@ void InsightWindow::toggleEepromInspectionPane() {
}
this->adjustMinimumSize();
}
}

View File

@@ -12,10 +12,11 @@
#include "Widgets/ExpandingHeightScrollAreaWidget.hpp"
#include "Widgets/TargetWidgets/TargetPackageWidgetContainer.hpp"
using namespace Bloom;
using namespace Bloom::Widgets;
namespace Bloom
{
using namespace Bloom::Widgets;
UiLoader::UiLoader(QObject* parent): QUiLoader(parent) {
UiLoader::UiLoader(QObject* parent): QUiLoader(parent) {
this->customWidgetConstructorsByWidgetName = decltype(this->customWidgetConstructorsByWidgetName) {
{
"PanelWidget",
@@ -90,13 +91,14 @@ UiLoader::UiLoader(QObject* parent): QUiLoader(parent) {
}
},
};
}
}
QWidget* UiLoader::createWidget(const QString& className, QWidget* parent, const QString& name) {
QWidget* UiLoader::createWidget(const QString& className, QWidget* parent, const QString& name) {
if (this->customWidgetConstructorsByWidgetName.contains(className)) {
// This is a custom widget - call the mapped constructor
return this->customWidgetConstructorsByWidgetName.at(className)(parent, name);
}
return QUiLoader::createWidget(className, parent, name);
}
}

View File

@@ -1,8 +1,8 @@
#include "ClickableWidget.hpp"
using namespace Bloom::Widgets;
void ClickableWidget::mouseReleaseEvent(QMouseEvent* event) {
namespace Bloom::Widgets
{
void ClickableWidget::mouseReleaseEvent(QMouseEvent* event) {
if (event->button() == Qt::MouseButton::LeftButton) {
emit this->clicked();
@@ -11,12 +11,13 @@ void ClickableWidget::mouseReleaseEvent(QMouseEvent* event) {
}
QWidget::mouseReleaseEvent(event);
}
}
void ClickableWidget::mouseDoubleClickEvent(QMouseEvent* event) {
void ClickableWidget::mouseDoubleClickEvent(QMouseEvent* event) {
if (event->button() == Qt::MouseButton::LeftButton) {
emit this->doubleClicked();
}
QWidget::mouseDoubleClickEvent(event);
}
}

View File

@@ -7,15 +7,15 @@
#include "src/Helpers/Paths.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Bloom::Exceptions::Exception;
using Bloom::Exceptions::Exception;
ErrorDialogue::ErrorDialogue(
ErrorDialogue::ErrorDialogue(
const QString& windowTitle,
const QString& errorMessage,
QWidget* parent
): QDialog(parent) {
): QDialog(parent) {
this->setObjectName("error-dialogue");
this->setAttribute(Qt::WA_DeleteOnClose, true);
this->setWindowTitle(windowTitle);
@@ -45,7 +45,9 @@ ErrorDialogue::ErrorDialogue(
auto uiLoader = UiLoader(this);
this->container = uiLoader.load(&dialogueUiFile, this);
this->errorMessageDescriptionLabel = this->container->findChild<QLabel*>("error-message-description-label");
this->errorMessageDescriptionLabel = this->container->findChild<QLabel*>(
"error-message-description-label"
);
this->okButton = this->container->findChild<QPushButton*>("ok-btn");
this->container->setContentsMargins(15, 10, 15, 15);
@@ -53,12 +55,16 @@ ErrorDialogue::ErrorDialogue(
this->errorMessageDescriptionLabel->setText(errorMessage);
QObject::connect(this->okButton, &QPushButton::clicked, this, &QDialog::close);
}
}
void ErrorDialogue::showEvent(QShowEvent* event) {
void ErrorDialogue::showEvent(QShowEvent* event) {
const auto containerSize = this->container->sizeHint();
const auto windowSize = QSize(std::max(containerSize.width(), 500), std::max(containerSize.height(), 100));
const auto windowSize = QSize(
std::max(containerSize.width(), 500),
std::max(containerSize.height(), 100)
);
this->setFixedSize(windowSize);
this->container->setFixedSize(windowSize);
}
}

View File

@@ -1,18 +1,18 @@
#include "LabeledSeparator.hpp"
using namespace Bloom::Widgets;
LabeledSeparator::LabeledSeparator(QString title, QWidget* parent): title(std::move(title)), QWidget(parent) {
namespace Bloom::Widgets
{
LabeledSeparator::LabeledSeparator(QString title, QWidget* parent): title(std::move(title)), QWidget(parent) {
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
this->setFixedHeight(LabeledSeparator::DEFAULT_HEIGHT);
}
}
void LabeledSeparator::paintEvent(QPaintEvent* event) {
void LabeledSeparator::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void LabeledSeparator::drawWidget(QPainter& painter) {
void LabeledSeparator::drawWidget(QPainter& painter) {
const auto fontMetrics = painter.fontMetrics();
const auto titleSize = fontMetrics.size(Qt::TextFlag::TextSingleLine, this->title);
const auto titleRect = QRect(
@@ -32,4 +32,5 @@ void LabeledSeparator::drawWidget(QPainter& painter) {
painter.setPen(this->lineColor);
painter.drawLine(line);
}
}

View File

@@ -2,14 +2,14 @@
#include <QLayout>
using namespace Bloom::Widgets;
PanelWidget::PanelWidget(QWidget* parent): QFrame(parent) {
namespace Bloom::Widgets
{
PanelWidget::PanelWidget(QWidget* parent): QFrame(parent) {
this->setMouseTracking(false);
this->setAttribute(Qt::WA_Hover, true);
}
}
void PanelWidget::setMinimumResize(int minimumResize) {
void PanelWidget::setMinimumResize(int minimumResize) {
this->minimumResize = minimumResize;
const auto currentSize = this->size();
@@ -20,9 +20,9 @@ void PanelWidget::setMinimumResize(int minimumResize) {
} else if (this->panelType == PanelWidgetType::BOTTOM && currentSize.height() < this->minimumResize) {
this->setFixedHeight(this->minimumResize);
}
}
}
void PanelWidget::setMaximumResize(int maximumResize) {
void PanelWidget::setMaximumResize(int maximumResize) {
this->maximumResize = maximumResize;
const auto currentSize = this->size();
@@ -33,9 +33,9 @@ void PanelWidget::setMaximumResize(int maximumResize) {
} else if (this->panelType == PanelWidgetType::BOTTOM && currentSize.height() > this->maximumResize) {
this->setFixedHeight(this->maximumResize);
}
}
}
void PanelWidget::setPanelType(PanelWidgetType panelType) {
void PanelWidget::setPanelType(PanelWidgetType panelType) {
this->panelType = panelType;
if (this->panelType == PanelWidgetType::LEFT) {
@@ -46,9 +46,9 @@ void PanelWidget::setPanelType(PanelWidgetType panelType) {
this->resizeCursor = Qt::SplitVCursor;
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
}
}
}
bool PanelWidget::event(QEvent* event) {
bool PanelWidget::event(QEvent* event) {
if (event->type() == QEvent::Type::HoverMove) {
auto hoverEvent = static_cast<QHoverEvent*>(event);
if (this->resizingActive || this->isPositionWithinHandleArea(hoverEvent->position().toPoint())) {
@@ -60,9 +60,9 @@ bool PanelWidget::event(QEvent* event) {
}
return QFrame::event(event);
}
}
void PanelWidget::mousePressEvent(QMouseEvent* event) {
void PanelWidget::mousePressEvent(QMouseEvent* event) {
const auto position = event->pos();
if (event->buttons() & Qt::LeftButton && this->isPositionWithinHandleArea(position)) {
@@ -79,17 +79,17 @@ void PanelWidget::mousePressEvent(QMouseEvent* event) {
}
}
}
}
}
void PanelWidget::mouseReleaseEvent(QMouseEvent* event) {
void PanelWidget::mouseReleaseEvent(QMouseEvent* event) {
if (this->resizingActive) {
this->resizingActive = false;
this->resizingOffset = 0;
this->setCursor(Qt::ArrowCursor);
}
}
}
void PanelWidget::mouseMoveEvent(QMouseEvent* event) {
void PanelWidget::mouseMoveEvent(QMouseEvent* event) {
if (this->resizingActive) {
const auto position = event->pos();
@@ -110,9 +110,9 @@ void PanelWidget::mouseMoveEvent(QMouseEvent* event) {
);
}
}
}
}
std::pair<QPoint, QPoint> PanelWidget::getHandleArea() const {
std::pair<QPoint, QPoint> PanelWidget::getHandleArea() const {
const auto currentSize = this->size();
if (this->panelType == PanelWidgetType::LEFT) {
@@ -127,13 +127,14 @@ std::pair<QPoint, QPoint> PanelWidget::getHandleArea() const {
QPoint(currentSize.width(), this->handleSize)
);
}
}
}
bool PanelWidget::isPositionWithinHandleArea(const QPoint& position) const {
bool PanelWidget::isPositionWithinHandleArea(const QPoint& position) const {
const auto handleArea = this->getHandleArea();
return (
position.x() >= handleArea.first.x() && position.x() <= handleArea.second.x()
&& position.y() >= handleArea.first.y() && position.y() <= handleArea.second.y()
);
}
}

View File

@@ -2,9 +2,9 @@
#include <QPainter>
using namespace Bloom::Widgets;
void RotatableLabel::paintEvent(QPaintEvent* event) {
namespace Bloom::Widgets
{
void RotatableLabel::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
static auto containerSize = this->getContainerSize();
static auto textSize = QLabel::minimumSizeHint();
@@ -22,9 +22,9 @@ void RotatableLabel::paintEvent(QPaintEvent* event) {
);
painter.restore();
}
}
QSize RotatableLabel::getContainerSize() const {
QSize RotatableLabel::getContainerSize() const {
auto size = QSize();
auto textSize = QLabel::sizeHint();
@@ -58,4 +58,5 @@ QSize RotatableLabel::getContainerSize() const {
}
return size;
}
}

View File

@@ -2,14 +2,14 @@
#include <QMenu>
using namespace Bloom::Widgets;
SvgToolButton::SvgToolButton(QWidget* parent): QToolButton(parent) {
namespace Bloom::Widgets
{
SvgToolButton::SvgToolButton(QWidget* parent): QToolButton(parent) {
this->setButtonWidth(10);
this->setButtonHeight(10);
}
}
void SvgToolButton::childEvent(QChildEvent* childEvent) {
void SvgToolButton::childEvent(QChildEvent* childEvent) {
if ((childEvent->added() || childEvent->polished()) && childEvent->child()->isWidgetType()) {
/*
* If a menu widget has been added as a child to this SvgToolButton, associate the menu with the button
@@ -20,4 +20,5 @@ void SvgToolButton::childEvent(QChildEvent* childEvent) {
this->setMenu(menuWidget);
}
}
}
}

View File

@@ -3,13 +3,13 @@
#include <QPainter>
#include <cmath>
using namespace Bloom::Widgets;
SvgWidget::SvgWidget(QWidget* parent): QFrame(parent) {
namespace Bloom::Widgets
{
SvgWidget::SvgWidget(QWidget* parent): QFrame(parent) {
this->renderer.setAspectRatioMode(Qt::AspectRatioMode::KeepAspectRatioByExpanding);
}
}
void SvgWidget::startSpin() {
void SvgWidget::startSpin() {
if (this->spinningAnimation == nullptr) {
this->spinningAnimation = new QPropertyAnimation(this, "angle", this);
this->spinningAnimation->setDuration(2000);
@@ -22,16 +22,16 @@ void SvgWidget::startSpin() {
}
this->spinningAnimation->start();
}
}
void SvgWidget::stopSpin() {
void SvgWidget::stopSpin() {
if (this->spinningAnimation != nullptr) {
this->spinningAnimation->stop();
this->setAngle(0);
}
}
}
void SvgWidget::paintEvent(QPaintEvent* paintEvent) {
void SvgWidget::paintEvent(QPaintEvent* paintEvent) {
auto painter = QPainter(this);
auto svgSize = this->renderer.defaultSize();
auto margins = this->contentsMargins();
@@ -52,14 +52,18 @@ void SvgWidget::paintEvent(QPaintEvent* paintEvent) {
}
this->renderer.render(&painter, QRectF(
std::ceil(static_cast<float>(containerSize.width() - svgSize.width()) / 2 + static_cast<float>(margins.left())),
std::ceil(static_cast<float>(containerSize.height() - svgSize.height()) / 2 + static_cast<float>(margins.top())),
std::ceil(
static_cast<float>(containerSize.width() - svgSize.width()) / 2 + static_cast<float>(margins.left())
),
std::ceil(
static_cast<float>(containerSize.height() - svgSize.height()) / 2 + static_cast<float>(margins.top())
),
svgSize.width(),
svgSize.height()
));
}
}
void SvgWidget::changeEvent(QEvent* event) {
void SvgWidget::changeEvent(QEvent* event) {
if (event->type() == QEvent::EnabledChange && !this->disabledSvgFilePath.isEmpty()) {
if (!this->isEnabled()) {
this->renderer.load(this->disabledSvgFilePath);
@@ -70,4 +74,5 @@ void SvgWidget::changeEvent(QEvent* event) {
this->repaint();
}
}
}

View File

@@ -4,14 +4,14 @@
#include "ByteItem.hpp"
using namespace Bloom::Widgets;
AnnotationItem::AnnotationItem(
namespace Bloom::Widgets
{
AnnotationItem::AnnotationItem(
std::uint32_t startAddress,
std::size_t size,
QString labelText,
AnnotationItemPosition position
):
):
QGraphicsItem(nullptr),
startAddress(startAddress),
size(size),
@@ -20,30 +20,30 @@ AnnotationItem::AnnotationItem(
position(position),
width(static_cast<int>((ByteItem::WIDTH + ByteItem::RIGHT_MARGIN) * size - ByteItem::RIGHT_MARGIN)),
height(position == AnnotationItemPosition::TOP ? AnnotationItem::TOP_HEIGHT : AnnotationItem::BOTTOM_HEIGHT
) {
) {
this->setAcceptHoverEvents(true);
this->setToolTip(this->labelText);
}
}
AnnotationItem::AnnotationItem(
AnnotationItem::AnnotationItem(
const Targets::TargetMemoryAddressRange& addressRange,
const QString& labelText,
AnnotationItemPosition position
): AnnotationItem(
): AnnotationItem(
addressRange.startAddress,
addressRange.endAddress - addressRange.startAddress + 1,
labelText,
position
) {}
) {}
AnnotationItem::AnnotationItem(const FocusedMemoryRegion& focusedMemoryRegion, AnnotationItemPosition position)
: AnnotationItem(
AnnotationItem::AnnotationItem(const FocusedMemoryRegion& focusedMemoryRegion, AnnotationItemPosition position)
: AnnotationItem(
focusedMemoryRegion.addressRange,
focusedMemoryRegion.name,
position
) {}
) {}
void AnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
void AnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
auto lineColor = this->getLineColor();
auto labelFontColor = this->getLabelFontColor();
@@ -60,11 +60,16 @@ void AnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* op
auto labelSize = fontMetrics.size(Qt::TextSingleLine, this->labelText);
if (labelSize.width() > this->width) {
labelSize.setWidth(this->width);
this->labelText = fontMetrics.elidedText(this->labelText, Qt::TextElideMode::ElideRight, this->width);
this->labelText = fontMetrics.elidedText(
this->labelText,
Qt::TextElideMode::ElideRight,
this->width
);
}
constexpr auto verticalLineLength = 5;
const auto verticalLineYStart = this->position == AnnotationItemPosition::BOTTOM ? 0 : AnnotationItem::TOP_HEIGHT;
const auto verticalLineYStart = this->position == AnnotationItemPosition::BOTTOM ? 0
: AnnotationItem::TOP_HEIGHT;
const auto verticalLineYEnd = this->position == AnnotationItemPosition::BOTTOM ?
verticalLineLength : AnnotationItem::TOP_HEIGHT - verticalLineLength;
@@ -109,4 +114,5 @@ void AnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* op
painter->setPen(labelFontColor);
painter->drawText(labelRect, Qt::AlignCenter, this->labelText);
}
}

View File

@@ -1,10 +1,10 @@
#include "ByteAddressContainer.hpp"
using namespace Bloom::Widgets;
void ByteAddressContainer::adjustAddressLabels(
namespace Bloom::Widgets
{
void ByteAddressContainer::adjustAddressLabels(
const std::map<std::size_t, std::vector<ByteItem*>>& byteItemsByRowIndex
) {
) {
static const auto margins = QMargins(0, 10, 0, 0);
const auto newRowCount = byteItemsByRowIndex.size();
@@ -46,9 +46,9 @@ void ByteAddressContainer::adjustAddressLabels(
}
this->update();
}
}
void ByteAddressContainer::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
void ByteAddressContainer::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
static const auto backgroundColor = QColor(0x35, 0x36, 0x33);
static const auto borderColor = QColor(0x41, 0x42, 0x3F);
@@ -68,4 +68,5 @@ void ByteAddressContainer::paint(QPainter* painter, const QStyleOptionGraphicsIt
ByteAddressContainer::WIDTH - 1,
static_cast<int>(this->boundingRect().height())
);
}
}

View File

@@ -1,20 +1,22 @@
#include "ByteAddressItem.hpp"
#include <QPainter>
#include <QStyle>
using namespace Bloom::Widgets;
void ByteAddressItem::setAddressHex(const QString& addressHex) {
namespace Bloom::Widgets
{
void ByteAddressItem::setAddressHex(const QString& addressHex) {
this->setCacheMode(
QGraphicsItem::CacheMode::ItemCoordinateCache,
QSize(ByteAddressItem::WIDTH, ByteAddressItem::HEIGHT)
);
this->addressHex = addressHex;
}
}
void ByteAddressItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
painter->setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void ByteAddressItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
painter->setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
static const auto widgetRect = this->boundingRect();
static auto fontColor = QColor(0x8F, 0x91, 0x92);
@@ -25,4 +27,5 @@ void ByteAddressItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
painter->setFont(font);
painter->setPen(fontColor);
painter->drawText(widgetRect, Qt::AlignCenter, this->addressHex);
}
}

View File

@@ -1,11 +1,10 @@
#include "ByteItem.hpp"
#include <QPainter>
#include <QStyle>
using namespace Bloom::Widgets;
ByteItem::ByteItem(
namespace Bloom::Widgets
{
ByteItem::ByteItem(
std::size_t byteIndex,
std::uint32_t address,
std::optional<std::uint32_t>& currentStackPointer,
@@ -13,29 +12,35 @@ ByteItem::ByteItem(
std::optional<AnnotationItem*>& hoveredAnnotationItem,
std::set<std::uint32_t>& highlightedAddresses,
const HexViewerWidgetSettings& settings
):
QGraphicsItem(nullptr),
byteIndex(byteIndex),
address(address),
currentStackPointer(currentStackPointer),
hoveredByteItem(hoveredByteItem),
hoveredAnnotationItem(hoveredAnnotationItem),
highlightedAddresses(highlightedAddresses),
settings(settings)
{
)
: QGraphicsItem(nullptr)
, byteIndex(byteIndex)
, address(address)
, currentStackPointer(currentStackPointer)
, hoveredByteItem(hoveredByteItem)
, hoveredAnnotationItem(hoveredAnnotationItem)
, highlightedAddresses(highlightedAddresses)
, settings(settings)
{
this->setCacheMode(
QGraphicsItem::CacheMode::ItemCoordinateCache,
QSize(ByteItem::WIDTH, ByteItem::HEIGHT)
);
this->setAcceptHoverEvents(true);
this->addressHex = "0x" + QString::number(this->address, 16).rightJustified(8, '0').toUpper();
this->relativeAddressHex = "0x" + QString::number(this->byteIndex, 16).rightJustified(8, '0').toUpper();
this->addressHex = "0x" + QString::number(this->address, 16).rightJustified(
8,
'0'
).toUpper();
this->relativeAddressHex = "0x" + QString::number(this->byteIndex, 16).rightJustified(
8,
'0'
).toUpper();
this->setSelected(false);
}
}
void ByteItem::setValue(unsigned char value) {
void ByteItem::setValue(unsigned char value) {
this->valueChanged = this->valueInitialised && this->value != value;
this->value = value;
@@ -45,10 +50,13 @@ void ByteItem::setValue(unsigned char value) {
this->valueInitialised = this->excludedMemoryRegion == nullptr;
this->update();
}
}
void ByteItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
painter->setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void ByteItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
painter->setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
painter->setPen(Qt::PenStyle::NoPen);
// TODO: This code could do with some tidying. It's getting quite messy.
@@ -163,4 +171,5 @@ void ByteItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
static const auto placeholderString = QString("??");
painter->drawText(widgetRect, Qt::AlignCenter, placeholderString);
}
}
}

View File

@@ -1,10 +1,10 @@
#include "ByteItemContainerGraphicsView.hpp"
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Bloom::Targets::TargetMemoryDescriptor;
using Bloom::Targets::TargetMemoryDescriptor;
ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
const TargetMemoryDescriptor& targetMemoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
@@ -12,7 +12,7 @@ ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
const HexViewerWidgetSettings& settings,
QLabel* hoveredAddressLabel,
QWidget* parent
): QGraphicsView(parent) {
): QGraphicsView(parent) {
this->setObjectName("graphics-view");
this->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
this->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
@@ -32,22 +32,23 @@ ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
this->setScene(this->scene);
}
}
void ByteItemContainerGraphicsView::scrollToByteItemAtAddress(std::uint32_t address) {
void ByteItemContainerGraphicsView::scrollToByteItemAtAddress(std::uint32_t address) {
this->centerOn(this->scene->getByteItemPositionByAddress(address));
}
}
bool ByteItemContainerGraphicsView::event(QEvent* event) {
bool ByteItemContainerGraphicsView::event(QEvent* event) {
const auto eventType = event->type();
if (eventType == QEvent::Type::EnabledChange) {
this->scene->setEnabled(this->isEnabled());
}
return QGraphicsView::event(event);
}
}
void ByteItemContainerGraphicsView::resizeEvent(QResizeEvent* event) {
void ByteItemContainerGraphicsView::resizeEvent(QResizeEvent* event) {
QGraphicsView::resizeEvent(event);
this->scene->adjustSize();
}
}

View File

@@ -2,11 +2,11 @@
#include <cmath>
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Bloom::Targets::TargetMemoryDescriptor;
using Bloom::Targets::TargetMemoryDescriptor;
ByteItemGraphicsScene::ByteItemGraphicsScene(
ByteItemGraphicsScene::ByteItemGraphicsScene(
const TargetMemoryDescriptor& targetMemoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
@@ -14,16 +14,16 @@ ByteItemGraphicsScene::ByteItemGraphicsScene(
const HexViewerWidgetSettings& settings,
QLabel* hoveredAddressLabel,
QGraphicsView* parent
):
QGraphicsScene(parent),
targetMemoryDescriptor(targetMemoryDescriptor),
focusedMemoryRegions(focusedMemoryRegions),
excludedMemoryRegions(excludedMemoryRegions),
insightWorker(insightWorker),
settings(settings),
hoveredAddressLabel(hoveredAddressLabel),
parent(parent)
{
)
: QGraphicsScene(parent)
, targetMemoryDescriptor(targetMemoryDescriptor)
, focusedMemoryRegions(focusedMemoryRegions)
, excludedMemoryRegions(excludedMemoryRegions)
, insightWorker(insightWorker)
, settings(settings)
, hoveredAddressLabel(hoveredAddressLabel)
, parent(parent)
{
this->setObjectName("byte-widget-container");
this->byteAddressContainer = new ByteAddressContainer();
@@ -62,28 +62,28 @@ ByteItemGraphicsScene::ByteItemGraphicsScene(
this->refreshRegions();
this->adjustSize();
}
}
void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buffer) {
void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buffer) {
for (auto& [address, byteWidget] : this->byteItemsByAddress) {
byteWidget->setValue(buffer.at(byteWidget->byteIndex));
}
this->updateAnnotationValues(buffer);
this->lastValueBuffer = buffer;
}
}
void ByteItemGraphicsScene::updateStackPointer(std::uint32_t stackPointer) {
void ByteItemGraphicsScene::updateStackPointer(std::uint32_t stackPointer) {
this->currentStackPointer = stackPointer;
this->invalidateChildItemCaches();
}
}
void ByteItemGraphicsScene::setHighlightedAddresses(const std::set<std::uint32_t>& highlightedAddresses) {
void ByteItemGraphicsScene::setHighlightedAddresses(const std::set<std::uint32_t>& highlightedAddresses) {
this->highlightedAddresses = highlightedAddresses;
this->invalidateChildItemCaches();
}
}
void ByteItemGraphicsScene::refreshRegions() {
void ByteItemGraphicsScene::refreshRegions() {
for (auto& [byteAddress, byteWidget] : this->byteItemsByAddress) {
byteWidget->focusedMemoryRegion = nullptr;
byteWidget->excludedMemoryRegion = nullptr;
@@ -139,22 +139,22 @@ void ByteItemGraphicsScene::refreshRegions() {
}
this->adjustSize(true);
}
}
void ByteItemGraphicsScene::adjustSize(bool forced) {
void ByteItemGraphicsScene::adjustSize(bool forced) {
const auto width = this->getSceneWidth();
const auto columnCount = static_cast<std::size_t>(
std::floor(
(width - this->margins.left() - this->margins.right() - ByteAddressContainer::WIDTH + ByteItem::RIGHT_MARGIN)
/ (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN)
(width - this->margins.left() - this->margins.right() - ByteAddressContainer::WIDTH
+ ByteItem::RIGHT_MARGIN) / (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN)
)
);
const auto rowCount = static_cast<int>(
std::ceil(static_cast<double>(this->byteItemsByAddress.size()) / static_cast<double>(columnCount))
);
// Don't bother recalculating the byte item & annotation positions if the number of rows & columns have not changed.
// Don't bother recalculating the byte & annotation positions if the number of rows & columns haven't changed.
if (this->byteItemsByAddress.empty()
|| (
!forced
@@ -193,9 +193,9 @@ void ByteItemGraphicsScene::adjustSize(bool forced) {
}
this->update();
}
}
void ByteItemGraphicsScene::setEnabled(bool enabled) {
void ByteItemGraphicsScene::setEnabled(bool enabled) {
if (this->enabled != enabled) {
this->enabled = enabled;
@@ -211,9 +211,9 @@ void ByteItemGraphicsScene::setEnabled(bool enabled) {
this->byteAddressContainer->update();
this->update();
}
}
}
void ByteItemGraphicsScene::invalidateChildItemCaches() {
void ByteItemGraphicsScene::invalidateChildItemCaches() {
for (auto& [address, byteWidget] : this->byteItemsByAddress) {
byteWidget->update();
}
@@ -221,25 +221,25 @@ void ByteItemGraphicsScene::invalidateChildItemCaches() {
for (auto* annotationItem : this->annotationItems) {
annotationItem->update();
}
}
}
QPointF ByteItemGraphicsScene::getByteItemPositionByAddress(std::uint32_t address) {
QPointF ByteItemGraphicsScene::getByteItemPositionByAddress(std::uint32_t address) {
if (this->byteItemsByAddress.contains(address)) {
return this->byteItemsByAddress.at(address)->pos();
}
return QPointF();
}
}
bool ByteItemGraphicsScene::event(QEvent* event) {
bool ByteItemGraphicsScene::event(QEvent* event) {
if (event->type() == QEvent::Type::GraphicsSceneLeave && this->hoveredByteWidget.has_value()) {
this->onByteWidgetLeave();
}
return QGraphicsScene::event(event);
}
}
void ByteItemGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) {
void ByteItemGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) {
auto hoveredItems = this->items(mouseEvent->scenePos());
ByteItem* hoveredByteItem = nullptr;
AnnotationItem* hoveredAnnotationItem = nullptr;
@@ -266,9 +266,9 @@ void ByteItemGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent)
if (this->hoveredAnnotationItem.has_value()) {
this->onAnnotationItemLeave();
}
}
}
void ByteItemGraphicsScene::updateAnnotationValues(const Targets::TargetMemoryBuffer& buffer) {
void ByteItemGraphicsScene::updateAnnotationValues(const Targets::TargetMemoryBuffer& buffer) {
const auto memoryStartAddress = this->targetMemoryDescriptor.addressRange.startAddress;
for (auto* valueAnnotationItem : this->valueAnnotationItems) {
if (valueAnnotationItem->size > buffer.size()) {
@@ -283,13 +283,13 @@ void ByteItemGraphicsScene::updateAnnotationValues(const Targets::TargetMemoryBu
buffer.begin() + relativeEndAddress + 1
));
}
}
}
void ByteItemGraphicsScene::adjustByteItemPositions() {
void ByteItemGraphicsScene::adjustByteItemPositions() {
const auto columnCount = static_cast<std::size_t>(
std::floor(
(this->getSceneWidth() - this->margins.left() - this->margins.right() - ByteAddressContainer::WIDTH + ByteItem::RIGHT_MARGIN)
/ (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN)
(this->getSceneWidth() - this->margins.left() - this->margins.right() - ByteAddressContainer::WIDTH
+ ByteItem::RIGHT_MARGIN) / (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN)
)
);
@@ -359,7 +359,9 @@ void ByteItemGraphicsScene::adjustByteItemPositions() {
byteWidget->setPos(
static_cast<int>(
columnIndex * (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN) + this->margins.left() + ByteAddressContainer::WIDTH),
columnIndex * (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN) + this->margins.left()
+ ByteAddressContainer::WIDTH
),
rowYPosition
);
@@ -376,9 +378,9 @@ void ByteItemGraphicsScene::adjustByteItemPositions() {
this->byteItemsByColumnIndex = std::move(byteWidgetsByColumnIndex);
this->byteAddressContainer->adjustAddressLabels(this->byteItemsByRowIndex);
}
}
void ByteItemGraphicsScene::adjustAnnotationItemPositions() {
void ByteItemGraphicsScene::adjustAnnotationItemPositions() {
if (this->byteItemsByAddress.empty() || !this->settings.displayAnnotations) {
return;
}
@@ -404,14 +406,14 @@ void ByteItemGraphicsScene::adjustAnnotationItemPositions() {
);
}
}
}
}
void ByteItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
void ByteItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
using Targets::TargetState;
this->targetState = newState;
}
}
void ByteItemGraphicsScene::onByteWidgetEnter(ByteItem* widget) {
void ByteItemGraphicsScene::onByteWidgetEnter(ByteItem* widget) {
if (this->hoveredByteWidget.has_value()) {
if (this->hoveredByteWidget.value() == widget) {
// This byte item is already marked as hovered
@@ -439,9 +441,9 @@ void ByteItemGraphicsScene::onByteWidgetEnter(ByteItem* widget) {
} else {
widget->update();
}
}
}
void ByteItemGraphicsScene::onByteWidgetLeave() {
void ByteItemGraphicsScene::onByteWidgetLeave() {
auto* byteItem = this->hoveredByteWidget.value();
this->hoveredByteWidget = std::nullopt;
@@ -459,9 +461,9 @@ void ByteItemGraphicsScene::onByteWidgetLeave() {
} else {
byteItem->update();
}
}
}
void ByteItemGraphicsScene::onAnnotationItemEnter(AnnotationItem* annotationItem) {
void ByteItemGraphicsScene::onAnnotationItemEnter(AnnotationItem* annotationItem) {
if (this->hoveredAnnotationItem.has_value()) {
if (this->hoveredAnnotationItem.value() == annotationItem) {
return;
@@ -479,9 +481,9 @@ void ByteItemGraphicsScene::onAnnotationItemEnter(AnnotationItem* annotationItem
) {
this->byteItemsByAddress.at(byteItemAddress)->update();
}
}
}
void ByteItemGraphicsScene::onAnnotationItemLeave() {
void ByteItemGraphicsScene::onAnnotationItemLeave() {
auto* annotationItem = this->hoveredAnnotationItem.value();
this->hoveredAnnotationItem = std::nullopt;
@@ -492,4 +494,5 @@ void ByteItemGraphicsScene::onAnnotationItemLeave() {
) {
this->byteItemsByAddress.at(byteItemAddress)->update();
}
}
}

View File

@@ -5,26 +5,27 @@
#include "src/Helpers/Paths.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::Widgets;
using namespace Bloom::Exceptions;
namespace Bloom::Widgets
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetMemoryDescriptor;
using Bloom::Targets::TargetMemoryDescriptor;
HexViewerWidget::HexViewerWidget(
HexViewerWidget::HexViewerWidget(
const TargetMemoryDescriptor& targetMemoryDescriptor,
HexViewerWidgetSettings& settings,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
InsightWorker& insightWorker,
QWidget* parent
):
QWidget(parent),
targetMemoryDescriptor(targetMemoryDescriptor),
settings(settings),
focusedMemoryRegions(focusedMemoryRegions),
excludedMemoryRegions(excludedMemoryRegions),
insightWorker(insightWorker)
{
)
: QWidget(parent)
, targetMemoryDescriptor(targetMemoryDescriptor)
, settings(settings)
, focusedMemoryRegions(focusedMemoryRegions)
, excludedMemoryRegions(excludedMemoryRegions)
, insightWorker(insightWorker)
{
this->setObjectName("hex-viewer-widget");
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
@@ -48,7 +49,9 @@ HexViewerWidget::HexViewerWidget(
this->bottomBar = this->container->findChild<QWidget*>("bottom-bar");
this->refreshButton = this->toolBar->findChild<SvgToolButton*>("refresh-memory-btn");
this->highlightStackMemoryButton = this->toolBar->findChild<SvgToolButton*>("highlight-stack-memory-btn");
this->highlightStackMemoryButton = this->toolBar->findChild<SvgToolButton*>(
"highlight-stack-memory-btn"
);
this->highlightHoveredRowAndColumnButton = this->toolBar->findChild<SvgToolButton*>(
"highlight-hovered-rows-columns-btn"
);
@@ -161,74 +164,74 @@ HexViewerWidget::HexViewerWidget(
);
this->show();
}
}
void HexViewerWidget::updateValues(const Targets::TargetMemoryBuffer& buffer) {
void HexViewerWidget::updateValues(const Targets::TargetMemoryBuffer& buffer) {
this->byteItemGraphicsScene->updateValues(buffer);
}
}
void HexViewerWidget::refreshRegions() {
void HexViewerWidget::refreshRegions() {
this->byteItemGraphicsScene->refreshRegions();
}
}
void HexViewerWidget::setStackPointer(std::uint32_t stackPointer) {
void HexViewerWidget::setStackPointer(std::uint32_t stackPointer) {
this->byteItemGraphicsScene->updateStackPointer(stackPointer);
}
}
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
this->container->setFixedSize(
this->width(),
this->height()
);
this->byteItemGraphicsView->setFixedSize(this->byteItemGraphicsViewContainer->size());
}
}
void HexViewerWidget::showEvent(QShowEvent* event) {
void HexViewerWidget::showEvent(QShowEvent* event) {
this->byteItemGraphicsView->setFixedSize(this->byteItemGraphicsViewContainer->size());
}
}
void HexViewerWidget::onTargetStateChanged(Targets::TargetState newState) {
void HexViewerWidget::onTargetStateChanged(Targets::TargetState newState) {
using Targets::TargetState;
this->targetState = newState;
}
}
void HexViewerWidget::setStackMemoryHighlightingEnabled(bool enabled) {
void HexViewerWidget::setStackMemoryHighlightingEnabled(bool enabled) {
this->highlightStackMemoryButton->setChecked(enabled);
this->settings.highlightStackMemory = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
}
void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) {
void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) {
this->highlightHoveredRowAndColumnButton->setChecked(enabled);
this->settings.highlightHoveredRowAndCol = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
}
void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) {
void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) {
this->highlightFocusedMemoryButton->setChecked(enabled);
this->settings.highlightFocusedMemory = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
}
void HexViewerWidget::setAnnotationsEnabled(bool enabled) {
void HexViewerWidget::setAnnotationsEnabled(bool enabled) {
this->displayAnnotationsButton->setChecked(enabled);
this->settings.displayAnnotations = enabled;
this->byteItemGraphicsScene->adjustSize(true);
}
}
void HexViewerWidget::setDisplayAsciiEnabled(bool enabled) {
void HexViewerWidget::setDisplayAsciiEnabled(bool enabled) {
this->displayAsciiButton->setChecked(enabled);
this->settings.displayAsciiValues = enabled;
this->byteItemGraphicsScene->invalidateChildItemCaches();
}
}
void HexViewerWidget::onGoToAddressInputChanged() {
void HexViewerWidget::onGoToAddressInputChanged() {
auto addressConversionOk = false;
const auto address = this->goToAddressInput->text().toUInt(&addressConversionOk, 16);
@@ -241,4 +244,5 @@ void HexViewerWidget::onGoToAddressInputChanged() {
}
this->byteItemGraphicsScene->setHighlightedAddresses({});
}
}

View File

@@ -2,17 +2,17 @@
#include <algorithm>
using namespace Bloom::Widgets;
ValueAnnotationItem::ValueAnnotationItem(const FocusedMemoryRegion& focusedMemoryRegion)
namespace Bloom::Widgets
{
ValueAnnotationItem::ValueAnnotationItem(const FocusedMemoryRegion& focusedMemoryRegion)
: AnnotationItem(focusedMemoryRegion, AnnotationItemPosition::TOP)
, focusedMemoryRegion(focusedMemoryRegion)
, endianness(focusedMemoryRegion.endianness)
{
{
this->labelText = QString(ValueAnnotationItem::DEFAULT_LABEL_TEXT);
}
}
void ValueAnnotationItem::setValue(const Targets::TargetMemoryBuffer& value) {
void ValueAnnotationItem::setValue(const Targets::TargetMemoryBuffer& value) {
this->value = value;
if (this->endianness == Targets::TargetMemoryEndianness::LITTLE) {
@@ -21,17 +21,17 @@ void ValueAnnotationItem::setValue(const Targets::TargetMemoryBuffer& value) {
this->refreshLabelText();
this->setToolTip(this->labelText);
}
}
void ValueAnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
void ValueAnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
auto font = painter->font();
font.setItalic(true);
painter->setFont(font);
AnnotationItem::paint(painter, option, widget);
}
}
void ValueAnnotationItem::refreshLabelText() {
void ValueAnnotationItem::refreshLabelText() {
this->update();
if (this->value.empty()) {
@@ -109,4 +109,5 @@ void ValueAnnotationItem::refreshLabelText() {
this->labelText = QString(ValueAnnotationItem::DEFAULT_LABEL_TEXT);
}
}
}
}

View File

@@ -6,16 +6,13 @@
#include "src/Exceptions/Exception.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
using namespace Bloom;
using namespace Bloom::Widgets;
using Targets::TargetMemoryAddressRange;
ExcludedRegionItem::ExcludedRegionItem(
namespace Bloom::Widgets
{
ExcludedRegionItem::ExcludedRegionItem(
const ExcludedMemoryRegion& region,
const Targets::TargetMemoryDescriptor& memoryDescriptor,
QWidget* parent
): memoryRegion(region), RegionItem(region, memoryDescriptor, parent) {
): memoryRegion(region), RegionItem(region, memoryDescriptor, parent) {
auto formUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane"
@@ -31,9 +28,11 @@ ExcludedRegionItem::ExcludedRegionItem(
this->formWidget = uiLoader.load(&formUiFile, this);
this->initFormInputs();
}
}
void ExcludedRegionItem::applyChanges() {
using Targets::TargetMemoryAddressRange;
void ExcludedRegionItem::applyChanges() {
this->memoryRegion.name = this->nameInput->text();
const auto inputAddressRange = TargetMemoryAddressRange(
@@ -41,6 +40,8 @@ void ExcludedRegionItem::applyChanges() {
this->endAddressInput->text().toUInt(nullptr, 16)
);
this->memoryRegion.addressRangeInputType = this->getSelectedAddressInputType();
this->memoryRegion.addressRange = this->memoryRegion.addressRangeInputType == MemoryRegionAddressInputType::RELATIVE ?
this->memoryRegion.addressRange =
this->memoryRegion.addressRangeInputType == MemoryRegionAddressInputType::RELATIVE ?
this->convertRelativeToAbsoluteAddressRange(inputAddressRange) : inputAddressRange;
}
}

View File

@@ -6,16 +6,15 @@
#include "src/Exceptions/Exception.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
using namespace Bloom;
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Targets::TargetMemoryAddressRange;
using Targets::TargetMemoryAddressRange;
FocusedRegionItem::FocusedRegionItem(
FocusedRegionItem::FocusedRegionItem(
const FocusedMemoryRegion& region,
const Targets::TargetMemoryDescriptor& memoryDescriptor,
QWidget* parent
): memoryRegion(region), RegionItem(region, memoryDescriptor, parent) {
): memoryRegion(region), RegionItem(region, memoryDescriptor, parent) {
auto formUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane"
@@ -31,9 +30,9 @@ FocusedRegionItem::FocusedRegionItem(
this->formWidget = uiLoader.load(&formUiFile, this);
this->initFormInputs();
}
}
void FocusedRegionItem::applyChanges() {
void FocusedRegionItem::applyChanges() {
this->memoryRegion.name = this->nameInput->text();
const auto inputAddressRange = TargetMemoryAddressRange(
@@ -47,7 +46,9 @@ void FocusedRegionItem::applyChanges() {
auto selectedDataTypeOptionName = this->dataTypeInput->currentData().toString();
if (FocusedRegionItem::dataTypeOptionsByName.contains(selectedDataTypeOptionName)) {
this->memoryRegion.dataType = FocusedRegionItem::dataTypeOptionsByName.at(selectedDataTypeOptionName).dataType;
this->memoryRegion.dataType = FocusedRegionItem::dataTypeOptionsByName.at(
selectedDataTypeOptionName
).dataType;
}
auto selectedEndiannessOptionName = this->endiannessInput->currentData().toString();
@@ -56,9 +57,9 @@ void FocusedRegionItem::applyChanges() {
selectedEndiannessOptionName
).endianness;
}
}
}
void FocusedRegionItem::initFormInputs() {
void FocusedRegionItem::initFormInputs() {
RegionItem::initFormInputs();
const auto& region = this->memoryRegion;
@@ -75,11 +76,15 @@ void FocusedRegionItem::initFormInputs() {
switch (region.dataType) {
case MemoryRegionDataType::UNSIGNED_INTEGER: {
this->dataTypeInput->setCurrentText(FocusedRegionItem::dataTypeOptionsByName.at("unsigned_integer").text);
this->dataTypeInput->setCurrentText(
FocusedRegionItem::dataTypeOptionsByName.at("unsigned_integer").text
);
break;
}
case MemoryRegionDataType::SIGNED_INTEGER: {
this->dataTypeInput->setCurrentText(FocusedRegionItem::dataTypeOptionsByName.at("signed_integer").text);
this->dataTypeInput->setCurrentText(
FocusedRegionItem::dataTypeOptionsByName.at("signed_integer").text
);
break;
}
case MemoryRegionDataType::ASCII_STRING: {
@@ -101,4 +106,5 @@ void FocusedRegionItem::initFormInputs() {
break;
}
}
}
}

View File

@@ -10,22 +10,21 @@
#include "src/Helpers/Paths.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom;
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Bloom::Exceptions::Exception;
using Bloom::Exceptions::Exception;
MemoryRegionManagerWindow::MemoryRegionManagerWindow(
MemoryRegionManagerWindow::MemoryRegionManagerWindow(
const Targets::TargetMemoryDescriptor& memoryDescriptor,
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
QWidget* parent
):
QWidget(parent),
memoryDescriptor(memoryDescriptor),
focusedMemoryRegions(focusedMemoryRegions),
excludedMemoryRegions(excludedMemoryRegions)
{
)
: QWidget(parent)
, memoryDescriptor(memoryDescriptor)
, focusedMemoryRegions(focusedMemoryRegions)
, excludedMemoryRegions(excludedMemoryRegions)
{
this->setWindowFlag(Qt::Window);
this->setObjectName("memory-region-manager-window");
this->setWindowTitle(
@@ -118,9 +117,9 @@ MemoryRegionManagerWindow::MemoryRegionManagerWindow(
// Position the inspection window at the center of the main Insight window
this->move(parent->window()->geometry().center() - this->rect().center());
this->show();
}
}
void MemoryRegionManagerWindow::refreshRegions() {
void MemoryRegionManagerWindow::refreshRegions() {
this->clearRegions();
for (const auto& focusedRegion: this->focusedMemoryRegions) {
@@ -132,9 +131,9 @@ void MemoryRegionManagerWindow::refreshRegions() {
}
this->sortRegionItems();
}
}
void MemoryRegionManagerWindow::showEvent(QShowEvent* event) {
void MemoryRegionManagerWindow::showEvent(QShowEvent* event) {
if (this->selectedRegion == nullptr && this->regionItemScrollAreaViewportLayout->count() > 0) {
auto* firstRegionItem = qobject_cast<RegionItem*>(
this->regionItemScrollAreaViewportLayout->itemAt(0)->widget()
@@ -144,9 +143,9 @@ void MemoryRegionManagerWindow::showEvent(QShowEvent* event) {
firstRegionItem->setSelected(true);
}
}
}
}
void MemoryRegionManagerWindow::clearRegions() {
void MemoryRegionManagerWindow::clearRegions() {
this->selectedRegion = nullptr;
for (auto* focusedRegionItem: this->focusedRegionItems) {
@@ -165,9 +164,9 @@ void MemoryRegionManagerWindow::clearRegions() {
this->focusedRegionItems.clear();
this->excludedRegionItems.clear();
}
}
void MemoryRegionManagerWindow::sortRegionItems() {
void MemoryRegionManagerWindow::sortRegionItems() {
/*
* This isn't very pretty.
*
@@ -192,42 +191,60 @@ void MemoryRegionManagerWindow::sortRegionItems() {
for (auto* regionItem: sortedRegionItems) {
this->regionItemScrollAreaViewportLayout->addWidget(regionItem);
}
}
}
FocusedRegionItem* MemoryRegionManagerWindow::addFocusedRegion(const FocusedMemoryRegion& region) {
auto* focusedRegionItem = new FocusedRegionItem(region, this->memoryDescriptor, this->regionItemScrollAreaViewport);
FocusedRegionItem* MemoryRegionManagerWindow::addFocusedRegion(const FocusedMemoryRegion& region) {
auto* focusedRegionItem = new FocusedRegionItem(
region,
this->memoryDescriptor,
this->regionItemScrollAreaViewport
);
this->focusedRegionItems.insert(focusedRegionItem);
this->regionItemScrollAreaViewportLayout->addWidget(focusedRegionItem);
this->stackedFormLayout->addWidget(focusedRegionItem->getFormWidget());
QObject::connect(focusedRegionItem, &RegionItem::selected, this, &MemoryRegionManagerWindow::onRegionSelected);
QObject::connect(
focusedRegionItem,
&RegionItem::selected,
this,
&MemoryRegionManagerWindow::onRegionSelected
);
return focusedRegionItem;
}
}
ExcludedRegionItem* MemoryRegionManagerWindow::addExcludedRegion(const ExcludedMemoryRegion& region) {
auto* excludedRegionItem = new ExcludedRegionItem(region, this->memoryDescriptor, this->regionItemScrollAreaViewport);
ExcludedRegionItem* MemoryRegionManagerWindow::addExcludedRegion(const ExcludedMemoryRegion& region) {
auto* excludedRegionItem = new ExcludedRegionItem(
region,
this->memoryDescriptor,
this->regionItemScrollAreaViewport
);
this->excludedRegionItems.insert(excludedRegionItem);
this->regionItemScrollAreaViewportLayout->addWidget(excludedRegionItem);
this->stackedFormLayout->addWidget(excludedRegionItem->getFormWidget());
QObject::connect(excludedRegionItem, &RegionItem::selected, this, &MemoryRegionManagerWindow::onRegionSelected);
QObject::connect(
excludedRegionItem,
&RegionItem::selected,
this,
&MemoryRegionManagerWindow::onRegionSelected
);
return excludedRegionItem;
}
}
void MemoryRegionManagerWindow::onRegionSelected(RegionItem* selectedRegion) {
void MemoryRegionManagerWindow::onRegionSelected(RegionItem* selectedRegion) {
if (this->selectedRegion != nullptr && this->selectedRegion != selectedRegion) {
this->selectedRegion->setSelected(false);
}
this->selectedRegion = selectedRegion;
this->stackedFormLayout->setCurrentWidget(this->selectedRegion->getFormWidget());
}
}
void MemoryRegionManagerWindow::onNewFocusedRegionTrigger() {
void MemoryRegionManagerWindow::onNewFocusedRegionTrigger() {
using Targets::TargetMemoryAddressRange;
auto* region = this->addFocusedRegion(FocusedMemoryRegion(
@@ -239,9 +256,9 @@ void MemoryRegionManagerWindow::onNewFocusedRegionTrigger() {
));
region->setSelected(true);
}
}
void MemoryRegionManagerWindow::onNewExcludedRegionTrigger() {
void MemoryRegionManagerWindow::onNewExcludedRegionTrigger() {
using Targets::TargetMemoryAddressRange;
auto* region = this->addExcludedRegion(ExcludedMemoryRegion(
@@ -253,9 +270,9 @@ void MemoryRegionManagerWindow::onNewExcludedRegionTrigger() {
));
region->setSelected(true);
}
}
void MemoryRegionManagerWindow::onDeleteRegionTrigger() {
void MemoryRegionManagerWindow::onDeleteRegionTrigger() {
if (this->selectedRegion == nullptr) {
return;
}
@@ -293,9 +310,9 @@ void MemoryRegionManagerWindow::onDeleteRegionTrigger() {
regionItem->setSelected(true);
}
}
}
}
void MemoryRegionManagerWindow::applyChanges() {
void MemoryRegionManagerWindow::applyChanges() {
auto processedFocusedMemoryRegions = std::vector<FocusedMemoryRegion>();
auto processedExcludedMemoryRegions = std::vector<ExcludedMemoryRegion>();
@@ -383,10 +400,11 @@ void MemoryRegionManagerWindow::applyChanges() {
this->excludedMemoryRegions = std::move(processedExcludedMemoryRegions);
this->close();
emit this->changesApplied();
}
}
void MemoryRegionManagerWindow::openHelpPage() {
void MemoryRegionManagerWindow::openHelpPage() {
QDesktopServices::openUrl(
QUrl(QString::fromStdString(Paths::homeDomainName() + "/docs/manage-memory-regions"))
);
}
}

View File

@@ -3,16 +3,15 @@
#include <QHBoxLayout>
#include <QString>
using namespace Bloom;
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Targets::TargetMemoryAddressRange;
using Targets::TargetMemoryAddressRange;
RegionItem::RegionItem(
RegionItem::RegionItem(
const MemoryRegion& region,
const Targets::TargetMemoryDescriptor& memoryDescriptor,
QWidget* parent
): memoryDescriptor(memoryDescriptor), ClickableWidget(parent) {
): memoryDescriptor(memoryDescriptor), ClickableWidget(parent) {
this->setObjectName("region-item");
this->setFixedHeight(50);
this->layout->setContentsMargins(5, 5, 5, 0);
@@ -61,9 +60,9 @@ RegionItem::RegionItem(
QObject::connect(this, &ClickableWidget::rightClicked, this, onClick);
this->setSelected(false);
}
}
void RegionItem::setSelected(bool selected) {
void RegionItem::setSelected(bool selected) {
this->setProperty("selected", selected);
this->style()->unpolish(this);
this->style()->polish(this);
@@ -71,9 +70,9 @@ void RegionItem::setSelected(bool selected) {
if (selected) {
emit this->selected(this);
}
}
}
QStringList RegionItem::getValidationFailures() const {
QStringList RegionItem::getValidationFailures() const {
auto validationFailures = QStringList();
if (this->nameInput->text().isEmpty()) {
@@ -105,8 +104,9 @@ QStringList RegionItem::getValidationFailures() const {
);
const auto absoluteAddressRange = addressType == MemoryRegionAddressInputType::RELATIVE ?
this->convertRelativeToAbsoluteAddressRange(TargetMemoryAddressRange(startAddress, endAddress))
: TargetMemoryAddressRange(startAddress, endAddress);
this->convertRelativeToAbsoluteAddressRange(
TargetMemoryAddressRange(startAddress, endAddress)
) : TargetMemoryAddressRange(startAddress, endAddress);
if (absoluteAddressRange.startAddress < memoryAddressRange.startAddress
|| absoluteAddressRange.startAddress > memoryAddressRange.endAddress
@@ -125,9 +125,9 @@ QStringList RegionItem::getValidationFailures() const {
}
return validationFailures;
}
}
void RegionItem::initFormInputs() {
void RegionItem::initFormInputs() {
const auto& region = this->getMemoryRegion();
this->nameInput = this->formWidget->findChild<TextInput*>("name-input");
@@ -137,7 +137,9 @@ void RegionItem::initFormInputs() {
this->sizeInput = this->formWidget->findChild<TextInput*>("size-input");
this->nameInput->setText(region.name);
this->sizeInput->setText(QString::number((region.addressRange.endAddress - region.addressRange.startAddress) + 1));
this->sizeInput->setText(
QString::number((region.addressRange.endAddress - region.addressRange.startAddress) + 1)
);
for (const auto& [optionName, option] : RegionItem::addressRangeTypeOptionsByName) {
this->addressTypeInput->addItem(option.text, optionName);
@@ -147,50 +149,58 @@ void RegionItem::initFormInputs() {
auto relativeAddressRange = this->convertAbsoluteToRelativeAddressRange(region.addressRange);
this->addressTypeInput->setCurrentText(RegionItem::addressRangeTypeOptionsByName.at("relative").text);
this->startAddressInput->setText("0x" + QString::number(relativeAddressRange.startAddress, 16).toUpper());
this->endAddressInput->setText("0x" + QString::number(relativeAddressRange.endAddress, 16).toUpper());
this->startAddressInput->setText(
"0x" + QString::number(relativeAddressRange.startAddress, 16).toUpper()
);
this->endAddressInput->setText(
"0x" + QString::number(relativeAddressRange.endAddress, 16).toUpper()
);
} else {
this->addressTypeInput->setCurrentText(RegionItem::addressRangeTypeOptionsByName.at("absolute").text);
this->startAddressInput->setText("0x" + QString::number(region.addressRange.startAddress, 16).toUpper());
this->endAddressInput->setText("0x" + QString::number(region.addressRange.endAddress, 16).toUpper());
this->startAddressInput->setText(
"0x" + QString::number(region.addressRange.startAddress, 16).toUpper()
);
this->endAddressInput->setText(
"0x" + QString::number(region.addressRange.endAddress, 16).toUpper()
);
}
QObject::connect(this->startAddressInput, &QLineEdit::textEdited, this, &RegionItem::onAddressRangeInputChange);
QObject::connect(this->endAddressInput, &QLineEdit::textEdited, this, &RegionItem::onAddressRangeInputChange);
QObject::connect(this->sizeInput, &QLineEdit::textEdited, this, &RegionItem::onSizeInputChange);
QObject::connect(this->nameInput, &QLineEdit::textEdited, this, &RegionItem::onNameInputChange);
}
}
MemoryRegionAddressInputType RegionItem::getSelectedAddressInputType() const {
MemoryRegionAddressInputType RegionItem::getSelectedAddressInputType() const {
auto selectedAddressTypeOptionName = this->addressTypeInput->currentData().toString();
if (RegionItem::addressRangeTypeOptionsByName.contains(selectedAddressTypeOptionName)) {
return RegionItem::addressRangeTypeOptionsByName.at(selectedAddressTypeOptionName).addressType;
}
return MemoryRegionAddressInputType::ABSOLUTE;
}
}
TargetMemoryAddressRange RegionItem::convertAbsoluteToRelativeAddressRange(
TargetMemoryAddressRange RegionItem::convertAbsoluteToRelativeAddressRange(
const TargetMemoryAddressRange& absoluteAddressRange
) const {
) const {
return TargetMemoryAddressRange(
absoluteAddressRange.startAddress - this->memoryDescriptor.addressRange.startAddress,
absoluteAddressRange.endAddress - this->memoryDescriptor.addressRange.startAddress
);
}
}
TargetMemoryAddressRange RegionItem::convertRelativeToAbsoluteAddressRange(
TargetMemoryAddressRange RegionItem::convertRelativeToAbsoluteAddressRange(
const TargetMemoryAddressRange& relativeAddressRange
) const {
) const {
return TargetMemoryAddressRange(
relativeAddressRange.startAddress + this->memoryDescriptor.addressRange.startAddress,
relativeAddressRange.endAddress + this->memoryDescriptor.addressRange.startAddress
);
}
}
void RegionItem::onAddressRangeInputChange() {
void RegionItem::onAddressRangeInputChange() {
bool startAddressConversionOk = false;
bool endAddressConversionOk = false;
std::uint32_t startAddress = this->startAddressInput->text().toUInt(&startAddressConversionOk, 16);
@@ -199,9 +209,9 @@ void RegionItem::onAddressRangeInputChange() {
if (startAddressConversionOk && endAddressConversionOk && startAddress <= endAddress) {
this->sizeInput->setText(QString::number((endAddress - startAddress) + 1));
}
}
}
void RegionItem::onSizeInputChange() {
void RegionItem::onSizeInputChange() {
bool startAddressConversionOk = false;
bool sizeConversionOk = false;
std::uint32_t startAddress = this->startAddressInput->text().toUInt(&startAddressConversionOk, 16);
@@ -210,10 +220,11 @@ void RegionItem::onSizeInputChange() {
if (startAddressConversionOk && sizeConversionOk && size > 0) {
this->endAddressInput->setText("0x" + QString::number((startAddress + size) - 1, 16).toUpper());
}
}
}
void RegionItem::onNameInputChange() {
void RegionItem::onNameInputChange() {
auto newName = this->nameInput->text();
newName.truncate(RegionItem::NAME_LABEL_MAX_LENGTH);
this->nameLabel->setText(newName);
}
}

View File

@@ -4,19 +4,19 @@
#include <QScrollArea>
#include <QMargins>
using namespace Bloom::Widgets;
BitBodyWidget::BitBodyWidget(
namespace Bloom::Widgets
{
BitBodyWidget::BitBodyWidget(
int bitIndex,
std::bitset<std::numeric_limits<unsigned char>::digits>::reference bit,
bool readOnly,
QWidget* parent
): ClickableWidget(parent), bitIndex(bitIndex), bit(bit), readOnly(readOnly) {
): ClickableWidget(parent), bitIndex(bitIndex), bit(bit), readOnly(readOnly) {
this->setFixedSize(BitBodyWidget::WIDTH, BitBodyWidget::HEIGHT);
this->setContentsMargins(0, 0, 0, 0);
}
}
bool BitBodyWidget::event(QEvent* event) {
bool BitBodyWidget::event(QEvent* event) {
if (this->isEnabled() && !this->readOnly) {
switch (event->type()) {
case QEvent::Enter: {
@@ -36,9 +36,9 @@ bool BitBodyWidget::event(QEvent* event) {
}
return QWidget::event(event);
}
}
void BitBodyWidget::mouseReleaseEvent(QMouseEvent* event) {
void BitBodyWidget::mouseReleaseEvent(QMouseEvent* event) {
if (this->isEnabled()) {
if (!this->readOnly && event->button() == Qt::MouseButton::LeftButton) {
this->bit = !this->bit;
@@ -47,15 +47,18 @@ void BitBodyWidget::mouseReleaseEvent(QMouseEvent* event) {
ClickableWidget::mouseReleaseEvent(event);
}
}
}
void BitBodyWidget::paintEvent(QPaintEvent* event) {
void BitBodyWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void BitBodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void BitBodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
auto bodyColor = QColor(this->bit == true ? "#7B5E38" : "#908D85");
@@ -75,4 +78,5 @@ void BitBodyWidget::drawWidget(QPainter& painter) {
BitBodyWidget::WIDTH,
BitBodyWidget::HEIGHT
);
}
}

View File

@@ -6,15 +6,15 @@
#include "BitBodyWidget.hpp"
using namespace Bloom::Widgets;
BitWidget::BitWidget(
namespace Bloom::Widgets
{
BitWidget::BitWidget(
int bitIndex,
int bitNumber,
std::bitset<std::numeric_limits<unsigned char>::digits>& bitset,
bool readOnly,
QWidget* parent
): QWidget(parent), bitIndex(bitIndex), bitNumber(bitNumber), bitset(bitset), readOnly(readOnly) {
): QWidget(parent), bitIndex(bitIndex), bitNumber(bitNumber), bitset(bitset), readOnly(readOnly) {
this->setFixedSize(BitWidget::WIDTH, BitWidget::HEIGHT);
auto* layout = new QVBoxLayout(this);
@@ -52,4 +52,5 @@ BitWidget::BitWidget(
emit this->bitChanged();
});
}
}
}

View File

@@ -8,10 +8,10 @@
#include "../TargetRegisterInspectorWindow.hpp"
using namespace Bloom::Widgets;
BitsetWidget::BitsetWidget(int byteNumber, unsigned char& byte, bool readOnly, QWidget* parent):
QWidget(parent), byteNumber(byteNumber), byte(byte), readOnly(readOnly) {
namespace Bloom::Widgets
{
BitsetWidget::BitsetWidget(int byteNumber, unsigned char& byte, bool readOnly, QWidget* parent)
: QWidget(parent), byteNumber(byteNumber), byte(byte), readOnly(readOnly) {
this->setObjectName("bitset-widget");
auto* bitLayout = new QHBoxLayout(this);
bitLayout->setSpacing(BitWidget::SPACING);
@@ -43,20 +43,20 @@ QWidget(parent), byteNumber(byteNumber), byte(byte), readOnly(readOnly) {
}
);
}
}
}
void BitsetWidget::updateValue() {
void BitsetWidget::updateValue() {
this->bitset = {this->byte};
this->update();
}
}
void BitsetWidget::paintEvent(QPaintEvent* event) {
void BitsetWidget::paintEvent(QPaintEvent* event) {
QWidget::paintEvent(event);
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void BitsetWidget::drawWidget(QPainter& painter) {
void BitsetWidget::drawWidget(QPainter& painter) {
auto byteHex = "0x" + QString::number(this->byte, 16).toUpper();
painter.setPen(QColor("#474747"));
@@ -105,4 +105,5 @@ void BitsetWidget::drawWidget(QPainter& painter) {
Qt::AlignCenter,
byteHex
);
}
}

View File

@@ -3,15 +3,16 @@
#include <QStyle>
#include <QVBoxLayout>
using namespace Bloom::Widgets;
CurrentItem::CurrentItem(
namespace Bloom::Widgets
{
CurrentItem::CurrentItem(
const Targets::TargetMemoryBuffer& registerValue,
QWidget* parent
): Item(registerValue, parent) {
): Item(registerValue, parent) {
this->setObjectName("current-item");
this->setFixedHeight(30);
this->titleLabel->setText("Current value");
this->layout->addWidget(titleLabel, 0, Qt::AlignmentFlag::AlignLeft);
this->layout->setContentsMargins(5, 0, 5, 0);
}
}

View File

@@ -2,10 +2,10 @@
#include <QStyle>
using namespace Bloom::Widgets;
Item::Item(const Targets::TargetMemoryBuffer& registerValue, QWidget* parent):
ClickableWidget(parent), registerValue(registerValue) {
namespace Bloom::Widgets
{
Item::Item(const Targets::TargetMemoryBuffer& registerValue, QWidget* parent)
: ClickableWidget(parent), registerValue(registerValue) {
auto onClick = [this] {
this->setSelected(true);
};
@@ -14,9 +14,9 @@ ClickableWidget(parent), registerValue(registerValue) {
QObject::connect(this, &ClickableWidget::rightClicked, this, onClick);
this->setSelected(false);
}
}
void Item::setSelected(bool selected) {
void Item::setSelected(bool selected) {
this->setProperty("selected", selected);
this->style()->unpolish(this);
this->style()->polish(this);
@@ -24,4 +24,5 @@ void Item::setSelected(bool selected) {
if (selected) {
emit this->selected(this);
}
}
}

View File

@@ -4,13 +4,13 @@
#include <QHBoxLayout>
#include <QByteArray>
using namespace Bloom::Widgets;
RegisterHistoryItem::RegisterHistoryItem(
namespace Bloom::Widgets
{
RegisterHistoryItem::RegisterHistoryItem(
const Targets::TargetMemoryBuffer& registerValue,
const QDateTime& changeDate,
QWidget* parent
): Item(registerValue, parent) {
): Item(registerValue, parent) {
this->setObjectName("register-history-item");
this->setFixedHeight(50);
this->layout->setContentsMargins(5, 8, 5, 0);
@@ -38,4 +38,5 @@ RegisterHistoryItem::RegisterHistoryItem(
this->layout->addWidget(this->dateLabel, 0, Qt::AlignmentFlag::AlignTop);
this->layout->addLayout(subLabelLayout);
this->layout->addStretch(1);
}
}

View File

@@ -12,19 +12,20 @@
#include "src/Helpers/DateTime.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::Widgets;
using namespace Bloom::Exceptions;
namespace Bloom::Widgets
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
RegisterHistoryWidget::RegisterHistoryWidget(
RegisterHistoryWidget::RegisterHistoryWidget(
const Targets::TargetRegisterDescriptor& registerDescriptor,
const Targets::TargetMemoryBuffer& currentValue,
InsightWorker& insightWorker,
QWidget* parent
): QWidget(parent), registerDescriptor(registerDescriptor), insightWorker(insightWorker) {
): QWidget(parent), registerDescriptor(registerDescriptor), insightWorker(insightWorker) {
this->setObjectName("target-register-history-widget");
this->setFixedWidth(300);
@@ -82,39 +83,39 @@ RegisterHistoryWidget::RegisterHistoryWidget(
this->itemContainerLayout->addWidget(separatorWidget);
this->show();
}
}
void RegisterHistoryWidget::updateCurrentItemValue(const Targets::TargetMemoryBuffer& registerValue) {
void RegisterHistoryWidget::updateCurrentItemValue(const Targets::TargetMemoryBuffer& registerValue) {
this->currentItem->registerValue = registerValue;
if (this->selectedItemWidget != nullptr && this->currentItem == this->selectedItemWidget) {
this->selectCurrentItem();
}
}
}
void RegisterHistoryWidget::selectCurrentItem() {
void RegisterHistoryWidget::selectCurrentItem() {
this->currentItem->setSelected(true);
}
}
void RegisterHistoryWidget::addItem(const Targets::TargetMemoryBuffer& registerValue, const QDateTime& changeDate) {
void RegisterHistoryWidget::addItem(const Targets::TargetMemoryBuffer& registerValue, const QDateTime& changeDate) {
auto* item = new RegisterHistoryItem(registerValue, changeDate, this->itemContainer);
QObject::connect(item, &Item::selected, this, &RegisterHistoryWidget::onItemSelectionChange);
this->itemContainerLayout->insertWidget(2, item);
}
}
void RegisterHistoryWidget::resizeEvent(QResizeEvent* event) {
void RegisterHistoryWidget::resizeEvent(QResizeEvent* event) {
this->container->setFixedSize(
this->width(),
this->height()
);
}
}
void RegisterHistoryWidget::onTargetStateChanged(Targets::TargetState newState) {
void RegisterHistoryWidget::onTargetStateChanged(Targets::TargetState newState) {
using Targets::TargetState;
this->targetState = newState;
}
}
void RegisterHistoryWidget::onItemSelectionChange(Item* newlySelectedWidget) {
void RegisterHistoryWidget::onItemSelectionChange(Item* newlySelectedWidget) {
if (this->selectedItemWidget != newlySelectedWidget) {
if (this->selectedItemWidget != nullptr) {
this->selectedItemWidget->setSelected(false);
@@ -124,13 +125,17 @@ void RegisterHistoryWidget::onItemSelectionChange(Item* newlySelectedWidget) {
}
emit this->historyItemSelected(newlySelectedWidget->registerValue);
}
}
void RegisterHistoryWidget::onRegistersWritten(Targets::TargetRegisters targetRegisters, const QDateTime& changeDate) {
void RegisterHistoryWidget::onRegistersWritten(
Targets::TargetRegisters targetRegisters,
const QDateTime& changeDate
) {
for (const auto& targetRegister : targetRegisters) {
if (targetRegister.descriptor == this->registerDescriptor) {
this->addItem(targetRegister.value, changeDate);
this->updateCurrentItemValue(targetRegister.value);
}
}
}
}

View File

@@ -14,26 +14,26 @@
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"
#include "src/Insight/InsightWorker/Tasks/WriteTargetRegister.hpp"
using namespace Bloom::Widgets;
namespace Bloom::Widgets
{
using Bloom::Exceptions::Exception;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetState;
using Bloom::Exceptions::Exception;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetState;
TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
const Targets::TargetRegisterDescriptor& registerDescriptor,
InsightWorker& insightWorker,
TargetState currentTargetState,
std::optional<Targets::TargetMemoryBuffer> registerValue,
const std::optional<Targets::TargetMemoryBuffer>& registerValue,
QWidget* parent
):
QWidget(parent),
registerDescriptor(registerDescriptor),
insightWorker(insightWorker),
registerValue(registerValue.value_or(Targets::TargetMemoryBuffer(registerDescriptor.size, 0)))
{
)
: QWidget(parent)
, registerDescriptor(registerDescriptor)
, insightWorker(insightWorker)
, registerValue(registerValue.value_or(Targets::TargetMemoryBuffer(registerDescriptor.size, 0)))
{
this->setWindowFlag(Qt::Window);
auto registerName = QString::fromStdString(this->registerDescriptor.name.value()).toUpper();
this->setObjectName("target-register-inspector-window");
@@ -41,13 +41,15 @@ TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
auto windowUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui"
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/"
"TargetRegisterInspectorWindow.ui"
)
);
auto windowStylesheet = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Stylesheets/TargetRegisterInspectorWindow.qss"
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Stylesheets/"
"TargetRegisterInspectorWindow.qss"
)
);
@@ -83,7 +85,9 @@ TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
this->contentContainer = this->container->findChild<QWidget*>("content-container");
this->registerValueContainer = this->container->findChild<QWidget*>("register-value-container");
this->registerValueTextInput = this->container->findChild<QLineEdit*>("register-value-text-input");
this->registerValueBitsetWidgetContainer = this->container->findChild<QWidget*>("register-value-bitset-widget-container");
this->registerValueBitsetWidgetContainer = this->container->findChild<QWidget*>(
"register-value-bitset-widget-container"
);
this->refreshValueButton = this->container->findChild<QPushButton*>("refresh-value-btn");
this->applyButton = this->container->findChild<QPushButton*>("apply-btn");
this->helpButton = this->container->findChild<QPushButton*>("help-btn");
@@ -92,7 +96,9 @@ TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
this->registerNameLabel->setText(registerName);
if (this->registerDescriptor.description.has_value()) {
this->registerDescriptionLabel->setText(QString::fromStdString(this->registerDescriptor.description.value()));
this->registerDescriptionLabel->setText(
QString::fromStdString(this->registerDescriptor.description.value())
);
this->registerDescriptionLabel->setVisible(true);
}
@@ -111,8 +117,12 @@ TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
registerValueContainer->setContentsMargins(15, 15, 15, 15);
registerDetailsContainer->setContentsMargins(15, 15, 15, 15);
auto* registerDetailsNameInput = registerDetailsContainer->findChild<QLineEdit*>("register-details-name-input");
auto* registerDetailsSizeInput = registerDetailsContainer->findChild<QLineEdit*>("register-details-size-input");
auto* registerDetailsNameInput = registerDetailsContainer->findChild<QLineEdit*>(
"register-details-name-input"
);
auto* registerDetailsSizeInput = registerDetailsContainer->findChild<QLineEdit*>(
"register-details-size-input"
);
auto* registerDetailsStartAddressInput = registerDetailsContainer->findChild<QLineEdit*>(
"register-details-start-address-input"
);
@@ -128,7 +138,9 @@ TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
this->registerValueTextInput->setDisabled(true);
this->applyButton->setVisible(false);
auto* readOnlyIndicatorLabel = this->registerValueContainer->findChild<QLabel*>("read-only-indicator-label");
auto* readOnlyIndicatorLabel = this->registerValueContainer->findChild<QLabel*>(
"read-only-indicator-label"
);
readOnlyIndicatorLabel->show();
}
@@ -216,19 +228,19 @@ TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
this->move(parent->window()->geometry().center() - this->rect().center());
this->show();
}
}
bool TargetRegisterInspectorWindow::registerSupported(const Targets::TargetRegisterDescriptor& descriptor) {
bool TargetRegisterInspectorWindow::registerSupported(const Targets::TargetRegisterDescriptor& descriptor) {
return (descriptor.size > 0 && descriptor.size <= 8);
}
}
void TargetRegisterInspectorWindow::setValue(const Targets::TargetMemoryBuffer& registerValue) {
void TargetRegisterInspectorWindow::setValue(const Targets::TargetMemoryBuffer& registerValue) {
this->registerValue = registerValue;
this->registerHistoryWidget->updateCurrentItemValue(this->registerValue);
this->registerHistoryWidget->selectCurrentItem();
}
}
void TargetRegisterInspectorWindow::onValueTextInputChanged(QString text) {
void TargetRegisterInspectorWindow::onValueTextInputChanged(QString text) {
if (text.isEmpty()) {
text = "0";
}
@@ -253,9 +265,9 @@ void TargetRegisterInspectorWindow::onValueTextInputChanged(QString text) {
for (auto& bitsetWidget : this->bitsetWidgets) {
bitsetWidget->updateValue();
}
}
}
void TargetRegisterInspectorWindow::onTargetStateChanged(TargetState newState) {
void TargetRegisterInspectorWindow::onTargetStateChanged(TargetState newState) {
if (newState != TargetState::STOPPED) {
this->registerValueTextInput->setDisabled(true);
this->registerValueBitsetWidgetContainer->setDisabled(true);
@@ -273,9 +285,11 @@ void TargetRegisterInspectorWindow::onTargetStateChanged(TargetState newState) {
}
this->targetState = newState;
}
}
void TargetRegisterInspectorWindow::onHistoryItemSelected(const Targets::TargetMemoryBuffer& selectedRegisterValue) {
void TargetRegisterInspectorWindow::onHistoryItemSelected(
const Targets::TargetMemoryBuffer& selectedRegisterValue
) {
this->registerValue = selectedRegisterValue;
this->updateValue();
@@ -285,29 +299,29 @@ void TargetRegisterInspectorWindow::onHistoryItemSelected(const Targets::TargetM
} else {
this->refreshValueButton->setVisible(false);
}
}
}
void TargetRegisterInspectorWindow::updateRegisterValueInputField() {
void TargetRegisterInspectorWindow::updateRegisterValueInputField() {
auto value = QByteArray(
reinterpret_cast<const char*>(this->registerValue.data()),
static_cast<qsizetype>(this->registerValue.size())
);
this->registerValueTextInput->setText("0x" + QString(value.toHex()).toUpper());
}
}
void TargetRegisterInspectorWindow::updateRegisterValueBitsetWidgets() {
void TargetRegisterInspectorWindow::updateRegisterValueBitsetWidgets() {
for (auto& bitsetWidget : this->bitsetWidgets) {
bitsetWidget->updateValue();
}
}
}
void TargetRegisterInspectorWindow::updateValue() {
void TargetRegisterInspectorWindow::updateValue() {
this->updateRegisterValueInputField();
this->updateRegisterValueBitsetWidgets();
}
}
void TargetRegisterInspectorWindow::refreshRegisterValue() {
void TargetRegisterInspectorWindow::refreshRegisterValue() {
this->registerValueContainer->setDisabled(true);
auto* readTargetRegisterTask = new ReadTargetRegisters({this->registerDescriptor});
@@ -336,11 +350,14 @@ void TargetRegisterInspectorWindow::refreshRegisterValue() {
);
this->insightWorker.queueTask(readTargetRegisterTask);
}
}
void TargetRegisterInspectorWindow::applyChanges() {
void TargetRegisterInspectorWindow::applyChanges() {
this->registerValueContainer->setDisabled(true);
const auto targetRegister = Targets::TargetRegister(this->registerDescriptor, this->registerValue);
const auto targetRegister = Targets::TargetRegister(
this->registerDescriptor,
this->registerValue
);
auto* writeRegisterTask = new WriteTargetRegister(targetRegister);
QObject::connect(writeRegisterTask, &InsightWorkerTask::completed, this, [this, targetRegister] {
@@ -366,8 +383,11 @@ void TargetRegisterInspectorWindow::applyChanges() {
});
this->insightWorker.queueTask(writeRegisterTask);
}
}
void TargetRegisterInspectorWindow::openHelpPage() {
QDesktopServices::openUrl(QUrl(QString::fromStdString(Paths::homeDomainName() + "/docs/register-inspection")));
void TargetRegisterInspectorWindow::openHelpPage() {
QDesktopServices::openUrl(
QUrl(QString::fromStdString(Paths::homeDomainName() + "/docs/register-inspection"))
);
}
}

View File

@@ -29,7 +29,7 @@ namespace Bloom::Widgets
const Targets::TargetRegisterDescriptor& registerDescriptor,
InsightWorker& insightWorker,
Targets::TargetState currentTargetState,
std::optional<Targets::TargetMemoryBuffer> registerValue = std::nullopt,
const std::optional<Targets::TargetMemoryBuffer>& registerValue = std::nullopt,
QWidget* parent = nullptr
);

View File

@@ -2,9 +2,9 @@
#include <QStyle>
using namespace Bloom::Widgets;
ItemWidget::ItemWidget(QWidget* parent): ClickableWidget(parent) {
namespace Bloom::Widgets
{
ItemWidget::ItemWidget(QWidget* parent): ClickableWidget(parent) {
auto onClick = [this] {
this->setSelected(true);
};
@@ -13,9 +13,9 @@ ItemWidget::ItemWidget(QWidget* parent): ClickableWidget(parent) {
QObject::connect(this, &ClickableWidget::rightClicked, this, onClick);
this->setSelected(false);
}
}
void ItemWidget::setSelected(bool selected) {
void ItemWidget::setSelected(bool selected) {
this->setProperty("selected", selected);
this->style()->unpolish(this);
this->style()->polish(this);
@@ -25,4 +25,5 @@ void ItemWidget::setSelected(bool selected) {
}
this->postSetSelected(selected);
}
}

View File

@@ -8,17 +8,18 @@
#include "src/Helpers/Paths.hpp"
using namespace Bloom::Widgets;
using namespace Bloom::Exceptions;
namespace Bloom::Widgets
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptor;
RegisterGroupWidget::RegisterGroupWidget(
RegisterGroupWidget::RegisterGroupWidget(
QString name,
const std::set<TargetRegisterDescriptor>& registerDescriptors,
InsightWorker& insightWorker,
TargetRegistersPaneWidget* parent
): ItemWidget(parent), name(std::move(name)) {
): ItemWidget(parent), name(std::move(name)) {
this->setObjectName(this->name);
this->headerWidget->setObjectName("register-group-header");
@@ -102,27 +103,27 @@ RegisterGroupWidget::RegisterGroupWidget(
parent,
&TargetRegistersPaneWidget::onItemSelectionChange
);
}
}
void RegisterGroupWidget::collapse() {
void RegisterGroupWidget::collapse() {
this->arrowIcon->setAngle(0);
this->bodyWidget->setVisible(false);
this->collapsed = true;
}
}
void RegisterGroupWidget::expand() {
void RegisterGroupWidget::expand() {
this->arrowIcon->setAngle(90);
this->bodyWidget->setVisible(true);
this->collapsed = false;
}
}
void RegisterGroupWidget::setAllRegistersVisible(bool visible) {
void RegisterGroupWidget::setAllRegistersVisible(bool visible) {
for (const auto& registerWidget : this->registerWidgets) {
registerWidget->setVisible(visible);
}
}
}
void RegisterGroupWidget::filterRegisters(const QString& keyword) {
void RegisterGroupWidget::filterRegisters(const QString& keyword) {
int matchingWidgetCount = 0;
for (const auto& registerWidget : this->registerWidgets) {
if (keyword.isEmpty() || (registerWidget->searchKeywords.contains(keyword, Qt::CaseInsensitive))) {
@@ -147,4 +148,5 @@ void RegisterGroupWidget::filterRegisters(const QString& keyword) {
this->collapse();
}
}
}
}

View File

@@ -9,23 +9,24 @@
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"
using namespace Bloom::Widgets;
using namespace Bloom::Exceptions;
namespace Bloom::Widgets
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptor;
RegisterWidget::RegisterWidget(
RegisterWidget::RegisterWidget(
TargetRegisterDescriptor descriptor,
InsightWorker& insightWorker,
QWidget *parent
)
)
: ItemWidget(parent)
, descriptor(std::move(descriptor))
, searchKeywords(QString::fromStdString(
this->descriptor.name.value_or("") + this->descriptor.description.value_or("")
).toLower())
, insightWorker(insightWorker)
{
{
this->setObjectName("register-item");
this->setFixedHeight(25);
@@ -64,9 +65,9 @@ RegisterWidget::RegisterWidget(
this,
&RegisterWidget::onTargetStateChange
);
}
}
void RegisterWidget::setRegisterValue(const Targets::TargetRegister& targetRegister) {
void RegisterWidget::setRegisterValue(const Targets::TargetRegister& targetRegister) {
const auto valueChanged = this->currentRegister.has_value()
&& this->currentRegister.value().value != targetRegister.value;
this->currentRegister = targetRegister;
@@ -93,13 +94,13 @@ void RegisterWidget::setRegisterValue(const Targets::TargetRegister& targetRegis
if (this->inspectWindow != nullptr) {
this->inspectWindow->setValue(targetRegister.value);
}
}
}
void RegisterWidget::clearInlineValue() {
void RegisterWidget::clearInlineValue() {
this->valueLabel->clear();
}
}
void RegisterWidget::contextMenuEvent(QContextMenuEvent* event) {
void RegisterWidget::contextMenuEvent(QContextMenuEvent* event) {
this->setSelected(true);
auto* menu = new QMenu(this);
@@ -126,9 +127,9 @@ void RegisterWidget::contextMenuEvent(QContextMenuEvent* event) {
this->copyValueBinaryAction->setEnabled(targetStoppedAndValuePresent);
menu->exec(event->globalPos());
}
}
void RegisterWidget::openInspectionWindow() {
void RegisterWidget::openInspectionWindow() {
if (!TargetRegisterInspectorWindow::registerSupported(this->descriptor)) {
return;
}
@@ -138,7 +139,8 @@ void RegisterWidget::openInspectionWindow() {
this->descriptor,
this->insightWorker,
this->targetState,
this->currentRegister.has_value() ? std::optional(this->currentRegister->value) : std::nullopt,
this->currentRegister.has_value() ? std::optional(this->currentRegister->value)
: std::nullopt,
this
);
@@ -154,9 +156,9 @@ void RegisterWidget::openInspectionWindow() {
this->inspectWindow->activateWindow();
}
}
}
}
void RegisterWidget::refreshValue() {
void RegisterWidget::refreshValue() {
auto* readRegisterTask = new ReadTargetRegisters({this->descriptor});
QObject::connect(
@@ -173,15 +175,15 @@ void RegisterWidget::refreshValue() {
);
this->insightWorker.queueTask(readRegisterTask);
}
}
void RegisterWidget::copyName() {
void RegisterWidget::copyName() {
if (this->nameLabel != nullptr) {
QApplication::clipboard()->setText(this->nameLabel->text());
}
}
}
void RegisterWidget::copyValueHex() {
void RegisterWidget::copyValueHex() {
if (this->currentRegister.has_value()) {
auto valueByteArray = QByteArray(
reinterpret_cast<const char*>(this->currentRegister.value().value.data()),
@@ -189,9 +191,9 @@ void RegisterWidget::copyValueHex() {
).toHex();
QApplication::clipboard()->setText(QString(valueByteArray).toUpper());
}
}
}
void RegisterWidget::copyValueDecimal() {
void RegisterWidget::copyValueDecimal() {
if (this->currentRegister.has_value()) {
auto valueByteArray = QByteArray(
reinterpret_cast<const char*>(this->currentRegister.value().value.data()),
@@ -199,9 +201,9 @@ void RegisterWidget::copyValueDecimal() {
).toHex();
QApplication::clipboard()->setText(QString::number(valueByteArray.toUInt(nullptr, 16)));
}
}
}
void RegisterWidget::copyValueBinary() {
void RegisterWidget::copyValueBinary() {
if (this->currentRegister.has_value()) {
const auto registerValueSize = static_cast<qsizetype>(this->currentRegister.value().size());
auto valueByteArray = QByteArray(
@@ -217,18 +219,19 @@ void RegisterWidget::copyValueBinary() {
QApplication::clipboard()->setText(bitString);
}
}
}
void RegisterWidget::postSetSelected(bool selected) {
void RegisterWidget::postSetSelected(bool selected) {
auto valueLabelStyle = this->valueLabel->style();
valueLabelStyle->unpolish(this->valueLabel);
valueLabelStyle->polish(this->valueLabel);
}
}
void RegisterWidget::onTargetStateChange(Targets::TargetState newState) {
void RegisterWidget::onTargetStateChange(Targets::TargetState newState) {
this->targetState = newState;
if (this->targetState == Targets::TargetState::RUNNING) {
this->clearInlineValue();
}
}
}

View File

@@ -12,24 +12,26 @@
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"
using namespace Bloom::Widgets;
using namespace Bloom::Exceptions;
namespace Bloom::Widgets
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetDescriptor;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
using Bloom::Targets::TargetDescriptor;
using Bloom::Targets::TargetRegisterDescriptor;
using Bloom::Targets::TargetRegisterDescriptors;
using Bloom::Targets::TargetRegisterType;
TargetRegistersPaneWidget::TargetRegistersPaneWidget(
TargetRegistersPaneWidget::TargetRegistersPaneWidget(
const TargetDescriptor& targetDescriptor,
InsightWorker& insightWorker,
PanelWidget* parent
): QWidget(parent), parent(parent), targetDescriptor(targetDescriptor), insightWorker(insightWorker) {
): QWidget(parent), parent(parent), targetDescriptor(targetDescriptor), insightWorker(insightWorker) {
this->setObjectName("target-registers-side-pane");
auto targetRegistersPaneUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/UiFiles/TargetRegistersSidePane.ui"
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/UiFiles/"
"TargetRegistersSidePane.ui"
)
);
@@ -121,9 +123,9 @@ TargetRegistersPaneWidget::TargetRegistersPaneWidget(
this,
&TargetRegistersPaneWidget::onRegistersRead
);
}
}
void TargetRegistersPaneWidget::filterRegisters(const QString& keyword) {
void TargetRegistersPaneWidget::filterRegisters(const QString& keyword) {
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
// If the group name matches the keyword, then don't bother iterating through all the register widgets
if (keyword.isEmpty() || registerGroupWidget->name.contains(keyword, Qt::CaseInsensitive)) {
@@ -141,21 +143,21 @@ void TargetRegistersPaneWidget::filterRegisters(const QString& keyword) {
registerGroupWidget->filterRegisters(keyword);
}
}
}
}
void TargetRegistersPaneWidget::collapseAllRegisterGroups() {
void TargetRegistersPaneWidget::collapseAllRegisterGroups() {
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
registerGroupWidget->collapse();
}
}
}
void TargetRegistersPaneWidget::expandAllRegisterGroups() {
void TargetRegistersPaneWidget::expandAllRegisterGroups() {
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
registerGroupWidget->expand();
}
}
}
void TargetRegistersPaneWidget::refreshRegisterValues(std::optional<std::function<void(void)>> callback) {
void TargetRegistersPaneWidget::refreshRegisterValues(std::optional<std::function<void(void)>> callback) {
auto& descriptors = this->renderedDescriptors;
if (descriptors.empty()) {
@@ -180,21 +182,21 @@ void TargetRegistersPaneWidget::refreshRegisterValues(std::optional<std::functio
}
this->insightWorker.queueTask(readRegisterTask);
}
}
void TargetRegistersPaneWidget::activate() {
void TargetRegistersPaneWidget::activate() {
this->show();
this->activated = true;
this->postActivate();
}
}
void TargetRegistersPaneWidget::deactivate() {
void TargetRegistersPaneWidget::deactivate() {
this->hide();
this->activated = false;
this->postDeactivate();
}
}
void TargetRegistersPaneWidget::onItemSelectionChange(ItemWidget* newlySelectedWidget) {
void TargetRegistersPaneWidget::onItemSelectionChange(ItemWidget* newlySelectedWidget) {
// Only one item in the target registers pane can be selected at any given time.
if (this->selectedItemWidget != newlySelectedWidget) {
if (this->selectedItemWidget != nullptr) {
@@ -203,9 +205,9 @@ void TargetRegistersPaneWidget::onItemSelectionChange(ItemWidget* newlySelectedW
this->selectedItemWidget = newlySelectedWidget;
}
}
}
void TargetRegistersPaneWidget::resizeEvent(QResizeEvent* event) {
void TargetRegistersPaneWidget::resizeEvent(QResizeEvent* event) {
const auto parentSize = this->parent->size();
const auto width = parentSize.width() - 1;
this->container->setFixedWidth(width);
@@ -216,36 +218,39 @@ void TargetRegistersPaneWidget::resizeEvent(QResizeEvent* event) {
* the scroll area.
*/
this->itemScrollArea->setFixedWidth(width - this->parent->getHandleSize());
}
}
void TargetRegistersPaneWidget::postActivate() {
void TargetRegistersPaneWidget::postActivate() {
if (this->targetState == Targets::TargetState::STOPPED) {
this->refreshRegisterValues();
}
}
}
void TargetRegistersPaneWidget::postDeactivate() {
void TargetRegistersPaneWidget::postDeactivate() {
}
}
void TargetRegistersPaneWidget::onTargetStateChanged(Targets::TargetState newState) {
void TargetRegistersPaneWidget::onTargetStateChanged(Targets::TargetState newState) {
using Targets::TargetState;
this->targetState = newState;
if (newState == TargetState::STOPPED && this->activated) {
this->refreshRegisterValues();
}
}
}
void TargetRegistersPaneWidget::onRegistersRead(const Targets::TargetRegisters& registers) {
void TargetRegistersPaneWidget::onRegistersRead(const Targets::TargetRegisters& registers) {
for (const auto& targetRegister : registers) {
auto& descriptor = targetRegister.descriptor;
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
if (registerGroupWidget->registerWidgetsMappedByDescriptor.contains(descriptor)) {
registerGroupWidget->registerWidgetsMappedByDescriptor.at(descriptor)->setRegisterValue(targetRegister);
registerGroupWidget->registerWidgetsMappedByDescriptor.at(
descriptor
)->setRegisterValue(targetRegister);
break;
}
}
}
}
}

View File

@@ -1,8 +1,8 @@
#include "BodyWidget.hpp"
using namespace Bloom::Widgets::InsightTargetWidgets::Dip;
BodyWidget::BodyWidget(QWidget* parent, std::size_t pinCount): QWidget(parent) {
namespace Bloom::Widgets::InsightTargetWidgets::Dip
{
BodyWidget::BodyWidget(QWidget* parent, std::size_t pinCount): QWidget(parent) {
this->setObjectName("target-body");
/*
@@ -29,15 +29,18 @@ BodyWidget::BodyWidget(QWidget* parent, std::size_t pinCount): QWidget(parent) {
this->orientationIndicatorDiameter = this->firstPinIndicatorDiameter % 2 == 0 ?
this->firstPinIndicatorDiameter + 3
: this->firstPinIndicatorDiameter + 2;
}
}
void BodyWidget::paintEvent(QPaintEvent* event) {
void BodyWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void BodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void BodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
const auto bodyHeight = this->height();
const auto bodyRect = QRectF(
0,
@@ -55,8 +58,8 @@ void BodyWidget::drawWidget(QPainter& painter) {
);
/*
* The orientation indicator is just a half-circle cut-out, positioned on the side of the DIP package closest to
* the first pin.
* The orientation indicator is just a half-circle cut-out, positioned on the side of the DIP package
* closest to the first pin.
*/
const auto orientationIndicatorRect = QRectF(
-(this->orientationIndicatorDiameter / 2),
@@ -78,4 +81,5 @@ void BodyWidget::drawWidget(QPainter& painter) {
painter.setBrush(backgroundColor);
painter.drawEllipse(firstPinIndicatorRect);
painter.drawEllipse(orientationIndicatorRect);
}
}

View File

@@ -8,19 +8,21 @@
#include "src/Helpers/Paths.hpp"
using namespace Bloom::Widgets::InsightTargetWidgets::Dip;
using namespace Bloom::Exceptions;
namespace Bloom::Widgets::InsightTargetWidgets::Dip
{
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetVariant;
using Bloom::Targets::TargetVariant;
DualInlinePackageWidget::DualInlinePackageWidget(
DualInlinePackageWidget::DualInlinePackageWidget(
const TargetVariant& targetVariant,
InsightWorker& insightWorker,
QWidget* parent
): TargetPackageWidget(targetVariant, insightWorker, parent) {
): TargetPackageWidget(targetVariant, insightWorker, parent) {
auto stylesheetFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss"
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/DIP/Stylesheets/"
"DualInlinePackage.qss"
)
);
stylesheetFile.open(QFile::ReadOnly);
@@ -99,14 +101,14 @@ DualInlinePackageWidget::DualInlinePackageWidget(
width,
height
);
}
}
void DualInlinePackageWidget::paintEvent(QPaintEvent* event) {
void DualInlinePackageWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void DualInlinePackageWidget::drawWidget(QPainter& painter) {
void DualInlinePackageWidget::drawWidget(QPainter& painter) {
using Targets::TargetPinState;
static auto pinNameFont = QFont("'Ubuntu', sans-serif");
@@ -247,4 +249,5 @@ void DualInlinePackageWidget::drawWidget(QPainter& painter) {
}
}
}
}
}

View File

@@ -2,21 +2,25 @@
#include <QPainter>
using namespace Bloom::Widgets::InsightTargetWidgets::Dip;
using namespace Bloom::Targets;
namespace Bloom::Widgets::InsightTargetWidgets::Dip
{
using namespace Bloom::Targets;
PinBodyWidget::PinBodyWidget(QWidget* parent, Targets::TargetPinDescriptor pinDescriptor)
: TargetPinBodyWidget(parent, std::move(pinDescriptor)) {
PinBodyWidget::PinBodyWidget(QWidget* parent, Targets::TargetPinDescriptor pinDescriptor)
: TargetPinBodyWidget(parent, std::move(pinDescriptor)) {
this->setFixedSize(PinBodyWidget::WIDTH, PinBodyWidget::HEIGHT);
}
}
void PinBodyWidget::paintEvent(QPaintEvent* event) {
void PinBodyWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void PinBodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void PinBodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
auto pinWidth = PinBodyWidget::WIDTH;
auto pinHeight = PinBodyWidget::HEIGHT;
this->setFixedSize(pinWidth, pinHeight);
@@ -32,4 +36,5 @@ void PinBodyWidget::drawWidget(QPainter& painter) {
pinWidth,
pinHeight
);
}
}

View File

@@ -1,14 +1,15 @@
#include "PinWidget.hpp"
using namespace Bloom::Widgets::InsightTargetWidgets::Dip;
using namespace Bloom::Targets;
namespace Bloom::Widgets::InsightTargetWidgets::Dip
{
using namespace Bloom::Targets;
PinWidget::PinWidget(
PinWidget::PinWidget(
const TargetPinDescriptor& pinDescriptor,
const TargetVariant& targetVariant,
InsightWorker& insightWorker,
QWidget* parent
): TargetPinWidget(pinDescriptor, targetVariant, insightWorker, parent) {
): TargetPinWidget(pinDescriptor, targetVariant, insightWorker, parent) {
this->setFixedSize(PinWidget::MINIMUM_WIDTH, PinWidget::MAXIMUM_HEIGHT);
this->layout = new QVBoxLayout();
@@ -44,4 +45,5 @@ PinWidget::PinWidget(
this->setLayout(this->layout);
connect(this->bodyWidget, &PinBodyWidget::clicked, this, &TargetPinWidget::onWidgetBodyClicked);
}
}

View File

@@ -2,15 +2,18 @@
#include <QPainter>
using namespace Bloom::Widgets::InsightTargetWidgets::Qfp;
void BodyWidget::paintEvent(QPaintEvent* event) {
namespace Bloom::Widgets::InsightTargetWidgets::Qfp
{
void BodyWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void BodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void BodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
auto targetBodyColor = this->getBodyColor();
auto backgroundColor = QColor("#373835");
@@ -45,4 +48,5 @@ void BodyWidget::drawWidget(QPainter& painter) {
18,
18
));
}
}

View File

@@ -3,26 +3,30 @@
#include <QPainter>
#include <QEvent>
using namespace Bloom::Widgets::InsightTargetWidgets::Qfp;
using namespace Bloom::Targets;
namespace Bloom::Widgets::InsightTargetWidgets::Qfp
{
using namespace Bloom::Targets;
PinBodyWidget::PinBodyWidget(QWidget* parent, Targets::TargetPinDescriptor pinDescriptor, bool isVertical)
: TargetPinBodyWidget(parent, std::move(pinDescriptor)), isVertical(isVertical) {
PinBodyWidget::PinBodyWidget(QWidget* parent, Targets::TargetPinDescriptor pinDescriptor, bool isVertical)
: TargetPinBodyWidget(parent, std::move(pinDescriptor)), isVertical(isVertical) {
if (isVertical) {
this->setFixedSize(PinBodyWidget::WIDTH, PinBodyWidget::HEIGHT);
} else {
this->setFixedSize(PinBodyWidget::HEIGHT, PinBodyWidget::WIDTH);
}
}
}
void PinBodyWidget::paintEvent(QPaintEvent* event) {
void PinBodyWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void PinBodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
void PinBodyWidget::drawWidget(QPainter& painter) {
painter.setRenderHints(
QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform,
true
);
auto pinWidth = this->isVertical ? PinBodyWidget::WIDTH : PinBodyWidget::HEIGHT;
auto pinHeight = this->isVertical ? PinBodyWidget::HEIGHT : PinBodyWidget::WIDTH;
this->setFixedSize(pinWidth, pinHeight);
@@ -38,4 +42,5 @@ void PinBodyWidget::drawWidget(QPainter& painter) {
pinWidth,
pinHeight
);
}
}

View File

@@ -7,15 +7,16 @@
#include "PinWidget.hpp"
#include "PinBodyWidget.hpp"
using namespace Bloom::Widgets::InsightTargetWidgets::Qfp;
using namespace Bloom::Targets;
namespace Bloom::Widgets::InsightTargetWidgets::Qfp
{
using namespace Bloom::Targets;
PinWidget::PinWidget(
PinWidget::PinWidget(
const TargetPinDescriptor& pinDescriptor,
const TargetVariant& targetVariant,
InsightWorker& insightWorker,
QWidget* parent
): TargetPinWidget(pinDescriptor, targetVariant, insightWorker, parent) {
): TargetPinWidget(pinDescriptor, targetVariant, insightWorker, parent) {
this->layout = new QBoxLayout(QBoxLayout::TopToBottom);
this->layout->setContentsMargins(0, 0, 0, 0);
this->layout->setSpacing(0);
@@ -90,12 +91,13 @@ PinWidget::PinWidget(
this->setLayout(this->layout);
connect(this->bodyWidget, &PinBodyWidget::clicked, this, &TargetPinWidget::onWidgetBodyClicked);
}
}
void PinWidget::updatePinState(const Targets::TargetPinState& pinState) {
void PinWidget::updatePinState(const Targets::TargetPinState& pinState) {
TargetPinWidget::updatePinState(pinState);
if (this->bodyWidget != nullptr) {
this->bodyWidget->setPinState(pinState);
}
}
}

View File

@@ -11,14 +11,15 @@
#include "PinWidget.hpp"
#include "BodyWidget.hpp"
using namespace Bloom::Widgets::InsightTargetWidgets::Qfp;
using namespace Bloom::Targets;
namespace Bloom::Widgets::InsightTargetWidgets::Qfp
{
using namespace Bloom::Targets;
QuadFlatPackageWidget::QuadFlatPackageWidget(
QuadFlatPackageWidget::QuadFlatPackageWidget(
const TargetVariant& targetVariant,
InsightWorker& insightWorker,
QWidget* parent
): TargetPackageWidget(targetVariant, insightWorker, parent) {
): TargetPackageWidget(targetVariant, insightWorker, parent) {
assert((targetVariant.pinDescriptorsByNumber.size() % 4) == 0);
auto stylesheetFile = QFile(QString::fromStdString(
@@ -182,14 +183,14 @@ QuadFlatPackageWidget::QuadFlatPackageWidget(
width,
height
);
}
}
void QuadFlatPackageWidget::paintEvent(QPaintEvent* event) {
void QuadFlatPackageWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
this->drawWidget(painter);
}
}
void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
static auto pinNameFont = QFont("'Ubuntu', sans-serif");
static auto pinDirectionFont = pinNameFont;
pinNameFont.setPixelSize(11);
@@ -222,8 +223,8 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
painter.setPen(pinStateChanged ? pinChangedFontColor : pinNameFontColor);
painter.drawText(
QRect(
pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH - PinWidget::MAXIMUM_LABEL_WIDTH
- (PinWidget::PIN_LABEL_SPACING * 2),
pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH
- PinWidget::MAXIMUM_LABEL_WIDTH - (PinWidget::PIN_LABEL_SPACING * 2),
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2)
- (PinWidget::MAXIMUM_LABEL_HEIGHT / 2),
PinWidget::MAXIMUM_LABEL_WIDTH,
@@ -239,8 +240,9 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
painter.setPen(pinDirectionFontColor);
painter.drawText(
QRect(
pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH - PinWidget::MAXIMUM_LABEL_WIDTH
- (PinWidget::PIN_LABEL_SPACING * 3) - PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH,
pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH
- PinWidget::MAXIMUM_LABEL_WIDTH - (PinWidget::PIN_LABEL_SPACING * 3)
- PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH,
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2)
- (PinWidget::MAXIMUM_LABEL_HEIGHT / 2),
PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH,
@@ -256,7 +258,8 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
painter.drawLine(QLine(
pinGeoPosition.x() + PinWidget::MAXIMUM_HORIZONTAL_WIDTH,
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2),
pinGeoPosition.x() + PinWidget::MAXIMUM_HORIZONTAL_WIDTH + PinWidget::PIN_LABEL_LONG_LINE_LENGTH,
pinGeoPosition.x() + PinWidget::MAXIMUM_HORIZONTAL_WIDTH
+ PinWidget::PIN_LABEL_LONG_LINE_LENGTH,
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2)
));
@@ -411,4 +414,5 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
}
}
}
}
}

View File

@@ -4,16 +4,15 @@
#include "src/Insight/InsightWorker/Tasks/RefreshTargetPinStates.hpp"
using namespace Bloom;
using namespace Bloom::Widgets::InsightTargetWidgets;
namespace Bloom::Widgets::InsightTargetWidgets
{
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetState;
TargetPackageWidget::TargetPackageWidget(
TargetPackageWidget::TargetPackageWidget(
Targets::TargetVariant targetVariant,
InsightWorker& insightWorker,
QWidget* parent
): QWidget(parent), targetVariant(std::move(targetVariant)), insightWorker(insightWorker) {
): QWidget(parent), targetVariant(std::move(targetVariant)), insightWorker(insightWorker) {
QObject::connect(
&(this->insightWorker),
&InsightWorker::targetStateUpdated,
@@ -29,9 +28,9 @@ TargetPackageWidget::TargetPackageWidget(
);
this->setDisabled(true);
}
}
void TargetPackageWidget::refreshPinStates(std::optional<std::function<void(void)>> callback) {
void TargetPackageWidget::refreshPinStates(std::optional<std::function<void(void)>> callback) {
auto* refreshTask = new RefreshTargetPinStates(this->targetVariant.id);
QObject::connect(
refreshTask,
@@ -50,9 +49,9 @@ void TargetPackageWidget::refreshPinStates(std::optional<std::function<void(void
}
this->insightWorker.queueTask(refreshTask);
}
}
void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMappingType& pinStatesByNumber) {
void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMappingType& pinStatesByNumber) {
for (auto& pinWidget : this->pinWidgets) {
auto pinNumber = pinWidget->getPinNumber();
if (pinStatesByNumber.contains(pinNumber)) {
@@ -61,9 +60,9 @@ void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMappingTy
}
this->update();
}
}
void TargetPackageWidget::onTargetStateChanged(TargetState newState) {
void TargetPackageWidget::onTargetStateChanged(TargetState newState) {
this->targetState = newState;
if (newState == TargetState::RUNNING) {
@@ -76,9 +75,9 @@ void TargetPackageWidget::onTargetStateChanged(TargetState newState) {
}
});
}
}
}
void TargetPackageWidget::onRegistersWritten(Targets::TargetRegisters targetRegisters) {
void TargetPackageWidget::onRegistersWritten(Targets::TargetRegisters targetRegisters) {
if (this->targetState != TargetState::STOPPED) {
return;
}
@@ -90,4 +89,5 @@ void TargetPackageWidget::onRegistersWritten(Targets::TargetRegisters targetRegi
return;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More