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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,15 +2,18 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp" #include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets; namespace Bloom::DebugServers::Gdb::CommandPackets
{
void ReadRegisters::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) { void ReadRegisters::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this); gdbRspDebugServer.handleGdbPacket(*this);
} }
void ReadRegisters::init() { void ReadRegisters::init() {
if (this->data.size() >= 2 && this->data.front() == 'p') { if (this->data.size() >= 2 && this->data.front() == 'p') {
// This command packet is requesting a specific register // 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" #include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets; namespace Bloom::DebugServers::Gdb::CommandPackets
using namespace Bloom::Exceptions; {
using namespace Bloom::Exceptions;
void RemoveBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) { void RemoveBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this); gdbRspDebugServer.handleGdbPacket(*this);
} }
void RemoveBreakpoint::init() { void RemoveBreakpoint::init() {
if (data.size() < 6) { if (data.size() < 6) {
throw Exception("Unexpected RemoveBreakpoint packet size"); throw Exception("Unexpected RemoveBreakpoint packet size");
} }
@@ -36,4 +37,5 @@ void RemoveBreakpoint::init() {
if (!conversionStatus) { if (!conversionStatus) {
throw Exception("Failed to convert address hex value from RemoveBreakpoint packet."); throw Exception("Failed to convert address hex value from RemoveBreakpoint packet.");
} }
}
} }

View File

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

View File

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

View File

@@ -4,13 +4,13 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp" #include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets; namespace Bloom::DebugServers::Gdb::CommandPackets
{
void SupportedFeaturesQuery::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) { void SupportedFeaturesQuery::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this); gdbRspDebugServer.handleGdbPacket(*this);
} }
void SupportedFeaturesQuery::init() { void SupportedFeaturesQuery::init() {
/* /*
* For qSupported packets, supported and unsupported GDB features are reported in the packet * For qSupported packets, supported and unsupported GDB features are reported in the packet
* data, where each GDB feature is separated by a semicolon. * 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" #include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets; namespace Bloom::DebugServers::Gdb::CommandPackets
using namespace Bloom::Exceptions; {
using namespace Bloom::Exceptions;
void WriteMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) { void WriteMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this); gdbRspDebugServer.handleGdbPacket(*this);
} }
void WriteMemory::init() { void WriteMemory::init() {
if (this->data.size() < 4) { if (this->data.size() < 4) {
throw Exception("Invalid packet length"); throw Exception("Invalid packet length");
} }
@@ -25,7 +26,9 @@ void WriteMemory::init() {
*/ */
auto packetSegments = packetString.split(","); auto packetSegments = packetString.split(",");
if (packetSegments.size() != 2) { 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; bool conversionStatus = false;
@@ -37,7 +40,10 @@ void WriteMemory::init() {
auto lengthAndBufferSegments = packetSegments.at(1).split(":"); auto lengthAndBufferSegments = packetSegments.at(1).split(":");
if (lengthAndBufferSegments.size() != 2) { 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); auto bufferSize = lengthAndBufferSegments.at(0).toUInt(&conversionStatus, 16);
@@ -50,4 +56,5 @@ void WriteMemory::init() {
if (this->buffer.size() != bufferSize) { if (this->buffer.size() != bufferSize) {
throw Exception("Buffer size does not match length value given in write memory packet"); 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/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets; namespace Bloom::DebugServers::Gdb::CommandPackets
using namespace Bloom::Exceptions; {
using namespace Bloom::Exceptions;
void WriteRegister::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) { void WriteRegister::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this); gdbRspDebugServer.handleGdbPacket(*this);
} }
void WriteRegister::init() { void WriteRegister::init() {
// The P packet updates a single register // The P packet updates a single register
auto packet = std::string(this->data.begin(), this->data.end()); 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->registerNumber = static_cast<int>(packetSegments.front().mid(1).toUInt(nullptr, 16));
this->registerValue = Packet::hexToData(packetSegments.back().toStdString()); this->registerValue = Packet::hexToData(packetSegments.back().toStdString());
std::reverse(this->registerValue.begin(), this->registerValue.end()); std::reverse(this->registerValue.begin(), this->registerValue.end());
}
} }

View File

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

View File

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

View File

@@ -1,8 +1,8 @@
#include "SupportedFeaturesResponse.hpp" #include "SupportedFeaturesResponse.hpp"
using namespace Bloom::DebugServers::Gdb::ResponsePackets; namespace Bloom::DebugServers::Gdb::ResponsePackets
{
std::vector<unsigned char> SupportedFeaturesResponse::getData() const { std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
std::string output = "qSupported:"; std::string output = "qSupported:";
auto gdbFeatureMapping = getGdbFeatureToNameMapping(); auto gdbFeatureMapping = getGdbFeatureToNameMapping();
@@ -12,6 +12,7 @@ std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
if (featureString.has_value()) { if (featureString.has_value()) {
if (supportedFeature.second.has_value()) { if (supportedFeature.second.has_value()) {
output.append(featureString.value() + "=" + supportedFeature.second.value() + ";"); output.append(featureString.value() + "=" + supportedFeature.second.value() + ";");
} else { } else {
output.append(featureString.value() + "+;"); output.append(featureString.value() + "+;");
} }
@@ -20,4 +21,5 @@ std::vector<unsigned char> SupportedFeaturesResponse::getData() const {
} }
return std::vector<unsigned char>(output.begin(), output.end()); 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/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" #include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::DebugToolDrivers; namespace Bloom::DebugToolDrivers
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr; {
using namespace Bloom::Exceptions; using namespace Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
void AtmelIce::init() { void AtmelIce::init() {
UsbDevice::init(); UsbDevice::init();
// TODO: Move away from hard-coding the CMSIS-DAP/EDBG interface number // 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->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(this->edbgInterface);
this->setInitialised(true); this->setInitialised(true);
} }
void AtmelIce::close() { void AtmelIce::close() {
if (this->sessionStarted) { if (this->sessionStarted) {
this->endSession(); this->endSession();
} }
this->getEdbgInterface().getUsbHidInterface().close(); this->getEdbgInterface().getUsbHidInterface().close();
UsbDevice::close(); UsbDevice::close();
} }
std::string AtmelIce::getSerialNumber() {
using namespace CommandFrames::Discovery;
std::string AtmelIce::getSerialNumber() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame( 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( throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID." "Failed to fetch serial number from device - invalid Discovery Protocol response ID."
); );
@@ -63,30 +66,35 @@ std::string AtmelIce::getSerialNumber() {
auto data = response.getPayloadData(); auto data = response.getPayloadData();
return std::string(data.begin(), data.end()); return std::string(data.begin(), data.end());
} }
void AtmelIce::startSession() {
using namespace CommandFrames::HouseKeeping;
void AtmelIce::startSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame( auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::StartSession() StartSession()
); );
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned! // Failed response returned!
throw DeviceInitializationFailure("Failed to start session with Atmel-ICE!"); throw DeviceInitializationFailure("Failed to start session with Atmel-ICE!");
} }
this->sessionStarted = true; this->sessionStarted = true;
} }
void AtmelIce::endSession() {
using namespace CommandFrames::HouseKeeping;
void AtmelIce::endSession() {
auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame( auto response = this->getEdbgInterface().sendAvrCommandFrameAndWaitForResponseFrame(
CommandFrames::HouseKeeping::EndSession() EndSession()
); );
if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { if (response.getResponseId() == ResponseId::FAILED) {
// Failed response returned! // Failed response returned!
throw DeviceFailure("Failed to end session with Atmel-ICE!"); throw DeviceFailure("Failed to end session with Atmel-ICE!");
} }
this->sessionStarted = false; this->sessionStarted = false;
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,17 +2,18 @@
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr; namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
using namespace Bloom::Exceptions; {
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); Response::init(rawResponse);
if (this->getResponseId() != 0x82) { if (this->getResponseId() != 0x82) {
throw Exception("Failed to construct AvrEvent object - invalid response ID."); throw Exception("Failed to construct AvrEvent object - invalid response ID.");
} }
auto& responseData = this->getData(); const auto& responseData = this->getData();
if (responseData.size() < 2) { if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID) // 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()) { if (!eventData.empty()) {
this->eventId = eventData[0]; this->eventId = eventData[0];
} }
}
} }

View File

@@ -2,17 +2,18 @@
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr; namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
using namespace Bloom::Exceptions; {
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); Response::init(rawResponse);
if (this->getResponseId() != 0x81) { if (this->getResponseId() != 0x81) {
throw Exception("Failed to construct AvrResponse object - invalid response ID."); throw Exception("Failed to construct AvrResponse object - invalid response ID.");
} }
auto& responseData = this->getData(); const auto& responseData = this->getData();
if (responseData.empty()) { if (responseData.empty()) {
// All AVR responses should contain at least one byte (the fragment info byte) // 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; 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)); this->setFragmentNumber(static_cast<std::uint8_t>(responseData[0] >> 4));
// Response size is two bytes, MSB // 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; std::vector<unsigned char> responsePacket;
responsePacket.resize(responsePacketSize); responsePacket.resize(responsePacketSize);
@@ -38,4 +39,5 @@ void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
} }
this->setResponsePacket(responsePacket); this->setResponsePacket(responsePacket);
}
} }

View File

@@ -3,9 +3,9 @@
#include <bitset> #include <bitset>
#include <cmath> #include <cmath>
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic; namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic
{
std::vector<unsigned char> ReadMemory::getPayload() const { std::vector<unsigned char> ReadMemory::getPayload() const {
/* /*
* The read memory command consists of 11/11 + (this->bytes / 8) bytes: * 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) * 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; return output;
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,16 +1,16 @@
#include "Interface.hpp" #include "Interface.hpp"
#include <libusb-1.0/libusb.h> #include <libusb-1.0/libusb.h>
#include <chrono>
#include "src/TargetController/Exceptions/DeviceFailure.hpp" #include "src/TargetController/Exceptions/DeviceFailure.hpp"
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp" #include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" #include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using namespace Bloom::Usb; namespace Bloom::Usb
using namespace Bloom::Exceptions; {
using namespace Bloom::Exceptions;
void Interface::init() { void Interface::init() {
if (this->libUsbDevice == nullptr) { if (this->libUsbDevice == nullptr) {
throw DeviceInitializationFailure("Cannot initialise interface without libusb device pointer."); throw DeviceInitializationFailure("Cannot initialise interface without libusb device pointer.");
} }
@@ -20,17 +20,17 @@ void Interface::init() {
} }
this->initialised = true; this->initialised = true;
} }
void Interface::close() { void Interface::close() {
if (this->libUsbDeviceHandle != nullptr) { if (this->libUsbDeviceHandle != nullptr) {
this->release(); this->release();
} }
this->initialised = false; this->initialised = false;
} }
void Interface::claim() { void Interface::claim() {
int interfaceNumber = this->getNumber(); int interfaceNumber = this->getNumber();
this->detachKernelDriver(); this->detachKernelDriver();
@@ -42,9 +42,9 @@ void Interface::claim() {
} }
this->claimed = true; this->claimed = true;
} }
void Interface::detachKernelDriver() { void Interface::detachKernelDriver() {
int interfaceNumber = this->getNumber(); int interfaceNumber = this->getNumber();
int libUsbStatusCode; int libUsbStatusCode;
@@ -59,21 +59,22 @@ void Interface::detachKernelDriver() {
throw DeviceInitializationFailure("Failed to check for active kernel driver on USB interface."); throw DeviceInitializationFailure("Failed to check for active kernel driver on USB interface.");
} }
} }
} }
void Interface::release() { void Interface::release() {
if (this->isClaimed()) { if (this->isClaimed()) {
if (libusb_release_interface(this->libUsbDeviceHandle, this->getNumber()) != 0) { if (libusb_release_interface(this->libUsbDeviceHandle, this->getNumber()) != 0) {
throw DeviceFailure( 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; 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 totalTransferred = 0;
int transferred = 0; int transferred = 0;
int libUsbStatusCode = 0; int libUsbStatusCode = 0;
@@ -98,9 +99,9 @@ int Interface::read(unsigned char* buffer, unsigned char endPoint, size_t length
} }
return transferred; 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 transferred = 0;
int libUsbStatusCode = 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) "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/Logger/Logger.hpp"
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" #include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
using Bloom::Usb::UsbDevice; namespace Bloom::Usb
using namespace Bloom::Exceptions; {
using namespace Bloom::Exceptions;
void UsbDevice::init() { void UsbDevice::init() {
libusb_init(&this->libUsbContext); libusb_init(&this->libUsbContext);
// libusb_set_option(this->libUsbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE); // libusb_set_option(this->libUsbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
auto devices = this->findMatchingDevices(); auto devices = this->findMatchingDevices();
if (devices.empty()) { if (devices.empty()) {
throw DeviceInitializationFailure("Failed to find USB device with matching vendor & product ID."); 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?) // TODO: implement support for multiple devices (maybe via serial number?)
throw DeviceInitializationFailure( throw DeviceInitializationFailure(
"Numerous devices of matching vendor & product ID found.\n" "Numerous devices of matching vendor & product ID found.\n"
@@ -23,57 +25,59 @@ void UsbDevice::init() {
} }
// For now, just use the first device found. // For now, just use the first device found.
auto device = devices.front(); auto* device = devices.front();
this->setLibUsbDevice(device); this->setLibUsbDevice(device);
int libUsbStatusCode; const int libUsbStatusCode = libusb_open(libUsbDevice, &this->libUsbDeviceHandle);
// Obtain a device handle from libusb // Obtain a device handle from libusb
if ((libUsbStatusCode = libusb_open(libUsbDevice, &this->libUsbDeviceHandle)) < 0) { if (libUsbStatusCode < 0) {
throw DeviceInitializationFailure( throw DeviceInitializationFailure(
"Failed to open USB device - error code " + std::to_string(libUsbStatusCode) + " returned." "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 = {}; 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( throw DeviceInitializationFailure(
"Failed to obtain USB configuration descriptor - error code " + std::to_string(libUsbStatusCode) "Failed to obtain USB configuration descriptor - error code " + std::to_string(libUsbStatusCode)
+ " returned." + " returned."
); );
} }
if ((libUsbStatusCode = libusb_set_configuration(this->libUsbDeviceHandle, configDescriptor->bConfigurationValue))) { libUsbStatusCode = libusb_set_configuration(this->libUsbDeviceHandle, configDescriptor->bConfigurationValue);
if (libUsbStatusCode < 0) {
throw DeviceInitializationFailure( throw DeviceInitializationFailure(
"Failed to set USB configuration - error code " + std::to_string(libUsbStatusCode) + " returned." "Failed to set USB configuration - error code " + std::to_string(libUsbStatusCode) + " returned."
); );
} }
libusb_free_config_descriptor(configDescriptor); 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 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** devices = nullptr;
libusb_device* device; libusb_device* device;
std::vector<libusb_device*> matchedDevices; std::vector<libusb_device*> matchedDevices;
ssize_t i = 0, libUsbStatusCode;
auto vendorIdToMatch = vendorId.value_or(this->vendorId); auto vendorIdToMatch = vendorId.value_or(this->vendorId);
auto productIdToMatch = productId.value_or(this->productId); 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( throw DeviceInitializationFailure(
"Failed to retrieve USB devices - return code: '" + std::to_string(libUsbStatusCode) + "'" "Failed to retrieve USB devices - return code: '" + std::to_string(libUsbStatusCode) + "'"
); );
} }
ssize_t i = 0;
while ((device = devices[i++]) != nullptr) { while ((device = devices[i++]) != nullptr) {
struct libusb_device_descriptor desc = {}; struct libusb_device_descriptor desc = {};
@@ -90,9 +94,9 @@ std::vector<libusb_device*> UsbDevice::findMatchingDevices(
libusb_free_device_list(devices, 1); libusb_free_device_list(devices, 1);
return matchedDevices; return matchedDevices;
} }
void UsbDevice::close() { void UsbDevice::close() {
if (this->libUsbDeviceHandle != nullptr) { if (this->libUsbDeviceHandle != nullptr) {
libusb_close(this->libUsbDeviceHandle); libusb_close(this->libUsbDeviceHandle);
this->libUsbDeviceHandle = nullptr; this->libUsbDeviceHandle = nullptr;
@@ -101,4 +105,5 @@ void UsbDevice::close() {
if (this->libUsbContext != nullptr) { if (this->libUsbContext != nullptr) {
libusb_exit(this->libUsbContext); libusb_exit(this->libUsbContext);
} }
}
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,22 +6,23 @@
#include "src/Helpers/Thread.hpp" #include "src/Helpers/Thread.hpp"
#include "src/Logger/Logger.hpp" #include "src/Logger/Logger.hpp"
using namespace Bloom; namespace Bloom
using namespace Bloom::Exceptions; {
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(); auto taskQueueLock = this->queuedTasks.acquireLock();
task->moveToThread(this->thread()); task->moveToThread(this->thread());
task->setParent(this); task->setParent(this);
this->queuedTasks.getReference().push(task); this->queuedTasks.getReference().push(task);
emit this->taskQueued(); emit this->taskQueued();
} }
void InsightWorker::startup() { void InsightWorker::startup() {
Logger::debug("Starting InsightWorker thread"); Logger::debug("Starting InsightWorker thread");
this->eventManager.registerListener(this->eventListener); this->eventManager.registerListener(this->eventListener);
@@ -52,13 +53,13 @@ void InsightWorker::startup() {
); );
emit this->ready(); emit this->ready();
} }
void InsightWorker::requestPinStates(int variantId) { void InsightWorker::requestPinStates(int variantId) {
this->targetControllerConsole.requestPinStates(variantId); this->targetControllerConsole.requestPinStates(variantId);
} }
std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() { std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() {
auto task = std::optional<InsightWorkerTask*>(); auto task = std::optional<InsightWorkerTask*>();
auto& queuedTasks = this->queuedTasks.getReference(); auto& queuedTasks = this->queuedTasks.getReference();
@@ -70,29 +71,30 @@ std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() {
} }
return task; 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 * When we report a target halt to Insight, Insight will immediately seek more data from the target (such as
* pin states). This can be problematic for cases where the target had halted due to a conditional breakpoint. * 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 * 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 * 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 * 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. * 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 * For the above reason, we don't want to report any target halts to Insight, unless we can be sure that the
* isn't going to immediately resume execution upon checking the condition. * 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 * 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 * that time window, we won't report the target halt to Insight, thus preventing Insight from needlessly
* data from the target and slowing things down. * 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 * 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 * problem is, we cannot differentiate a conditional breakpoint with a software breakpoint, so this seems to be
* only way. It would be nice if the debug client gave us some form of indication of whether the breakpoint is a * the only way. It would be nice if the debug client gave us some form of indication of whether the breakpoint
* conditional one. * is a conditional one.
*/ */
auto resumedEvent = this->eventListener->waitForEvent<Events::TargetExecutionResumed>( auto resumedEvent = this->eventListener->waitForEvent<Events::TargetExecutionResumed>(
std::chrono::milliseconds(650) std::chrono::milliseconds(650)
@@ -102,17 +104,17 @@ void InsightWorker::onTargetStoppedEvent(const Events::TargetExecutionStopped& e
emit this->targetStateUpdated(TargetState::STOPPED); emit this->targetStateUpdated(TargetState::STOPPED);
emit this->targetProgramCounterUpdated(event.programCounter); emit this->targetProgramCounterUpdated(event.programCounter);
} }
} }
void InsightWorker::onTargetResumedEvent(const Events::TargetExecutionResumed& event) { void InsightWorker::onTargetResumedEvent(const Events::TargetExecutionResumed& event) {
emit this->targetStateUpdated(TargetState::RUNNING); 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); 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 if (this->lastTargetControllerState == TargetControllerState::ACTIVE
&& event.state == TargetControllerState::SUSPENDED && event.state == TargetControllerState::SUSPENDED
) { ) {
@@ -129,12 +131,13 @@ void InsightWorker::onTargetControllerStateReportedEvent(const Events::TargetCon
} }
} }
this->lastTargetControllerState = event.state; this->lastTargetControllerState = event.state;
} }
void InsightWorker::executeTasks() { void InsightWorker::executeTasks() {
auto task = std::optional<InsightWorkerTask*>(); auto task = std::optional<InsightWorkerTask*>();
while ((task = this->getQueuedTask()).has_value()) { while ((task = this->getQueuedTask()).has_value()) {
task.value()->execute(this->targetControllerConsole); task.value()->execute(this->targetControllerConsole);
} }
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,10 +12,11 @@
#include "Widgets/ExpandingHeightScrollAreaWidget.hpp" #include "Widgets/ExpandingHeightScrollAreaWidget.hpp"
#include "Widgets/TargetWidgets/TargetPackageWidgetContainer.hpp" #include "Widgets/TargetWidgets/TargetPackageWidgetContainer.hpp"
using namespace Bloom; namespace Bloom
using namespace Bloom::Widgets; {
using namespace Bloom::Widgets;
UiLoader::UiLoader(QObject* parent): QUiLoader(parent) { UiLoader::UiLoader(QObject* parent): QUiLoader(parent) {
this->customWidgetConstructorsByWidgetName = decltype(this->customWidgetConstructorsByWidgetName) { this->customWidgetConstructorsByWidgetName = decltype(this->customWidgetConstructorsByWidgetName) {
{ {
"PanelWidget", "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)) { if (this->customWidgetConstructorsByWidgetName.contains(className)) {
// This is a custom widget - call the mapped constructor // This is a custom widget - call the mapped constructor
return this->customWidgetConstructorsByWidgetName.at(className)(parent, name); return this->customWidgetConstructorsByWidgetName.at(className)(parent, name);
} }
return QUiLoader::createWidget(className, parent, name); return QUiLoader::createWidget(className, parent, name);
}
} }

View File

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

View File

@@ -7,15 +7,15 @@
#include "src/Helpers/Paths.hpp" #include "src/Helpers/Paths.hpp"
#include "src/Exceptions/Exception.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& windowTitle,
const QString& errorMessage, const QString& errorMessage,
QWidget* parent QWidget* parent
): QDialog(parent) { ): QDialog(parent) {
this->setObjectName("error-dialogue"); this->setObjectName("error-dialogue");
this->setAttribute(Qt::WA_DeleteOnClose, true); this->setAttribute(Qt::WA_DeleteOnClose, true);
this->setWindowTitle(windowTitle); this->setWindowTitle(windowTitle);
@@ -45,7 +45,9 @@ ErrorDialogue::ErrorDialogue(
auto uiLoader = UiLoader(this); auto uiLoader = UiLoader(this);
this->container = uiLoader.load(&dialogueUiFile, 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->okButton = this->container->findChild<QPushButton*>("ok-btn");
this->container->setContentsMargins(15, 10, 15, 15); this->container->setContentsMargins(15, 10, 15, 15);
@@ -53,12 +55,16 @@ ErrorDialogue::ErrorDialogue(
this->errorMessageDescriptionLabel->setText(errorMessage); this->errorMessageDescriptionLabel->setText(errorMessage);
QObject::connect(this->okButton, &QPushButton::clicked, this, &QDialog::close); 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 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->setFixedSize(windowSize);
this->container->setFixedSize(windowSize); this->container->setFixedSize(windowSize);
}
} }

View File

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

View File

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

View File

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

View File

@@ -2,14 +2,14 @@
#include <QMenu> #include <QMenu>
using namespace Bloom::Widgets; namespace Bloom::Widgets
{
SvgToolButton::SvgToolButton(QWidget* parent): QToolButton(parent) { SvgToolButton::SvgToolButton(QWidget* parent): QToolButton(parent) {
this->setButtonWidth(10); this->setButtonWidth(10);
this->setButtonHeight(10); this->setButtonHeight(10);
} }
void SvgToolButton::childEvent(QChildEvent* childEvent) { void SvgToolButton::childEvent(QChildEvent* childEvent) {
if ((childEvent->added() || childEvent->polished()) && childEvent->child()->isWidgetType()) { 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 * 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); this->setMenu(menuWidget);
} }
} }
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,14 +11,15 @@
#include "PinWidget.hpp" #include "PinWidget.hpp"
#include "BodyWidget.hpp" #include "BodyWidget.hpp"
using namespace Bloom::Widgets::InsightTargetWidgets::Qfp; namespace Bloom::Widgets::InsightTargetWidgets::Qfp
using namespace Bloom::Targets; {
using namespace Bloom::Targets;
QuadFlatPackageWidget::QuadFlatPackageWidget( QuadFlatPackageWidget::QuadFlatPackageWidget(
const TargetVariant& targetVariant, const TargetVariant& targetVariant,
InsightWorker& insightWorker, InsightWorker& insightWorker,
QWidget* parent QWidget* parent
): TargetPackageWidget(targetVariant, insightWorker, parent) { ): TargetPackageWidget(targetVariant, insightWorker, parent) {
assert((targetVariant.pinDescriptorsByNumber.size() % 4) == 0); assert((targetVariant.pinDescriptorsByNumber.size() % 4) == 0);
auto stylesheetFile = QFile(QString::fromStdString( auto stylesheetFile = QFile(QString::fromStdString(
@@ -182,14 +183,14 @@ QuadFlatPackageWidget::QuadFlatPackageWidget(
width, width,
height height
); );
} }
void QuadFlatPackageWidget::paintEvent(QPaintEvent* event) { void QuadFlatPackageWidget::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this); auto painter = QPainter(this);
this->drawWidget(painter); this->drawWidget(painter);
} }
void QuadFlatPackageWidget::drawWidget(QPainter& painter) { void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
static auto pinNameFont = QFont("'Ubuntu', sans-serif"); static auto pinNameFont = QFont("'Ubuntu', sans-serif");
static auto pinDirectionFont = pinNameFont; static auto pinDirectionFont = pinNameFont;
pinNameFont.setPixelSize(11); pinNameFont.setPixelSize(11);
@@ -222,8 +223,8 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
painter.setPen(pinStateChanged ? pinChangedFontColor : pinNameFontColor); painter.setPen(pinStateChanged ? pinChangedFontColor : pinNameFontColor);
painter.drawText( painter.drawText(
QRect( QRect(
pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH - PinWidget::MAXIMUM_LABEL_WIDTH pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH
- (PinWidget::PIN_LABEL_SPACING * 2), - PinWidget::MAXIMUM_LABEL_WIDTH - (PinWidget::PIN_LABEL_SPACING * 2),
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2) pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2)
- (PinWidget::MAXIMUM_LABEL_HEIGHT / 2), - (PinWidget::MAXIMUM_LABEL_HEIGHT / 2),
PinWidget::MAXIMUM_LABEL_WIDTH, PinWidget::MAXIMUM_LABEL_WIDTH,
@@ -239,8 +240,9 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
painter.setPen(pinDirectionFontColor); painter.setPen(pinDirectionFontColor);
painter.drawText( painter.drawText(
QRect( QRect(
pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH - PinWidget::MAXIMUM_LABEL_WIDTH pinGeoPosition.x() - PinWidget::PIN_LABEL_LONG_LINE_LENGTH
- (PinWidget::PIN_LABEL_SPACING * 3) - PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH, - PinWidget::MAXIMUM_LABEL_WIDTH - (PinWidget::PIN_LABEL_SPACING * 3)
- PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH,
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2) pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2)
- (PinWidget::MAXIMUM_LABEL_HEIGHT / 2), - (PinWidget::MAXIMUM_LABEL_HEIGHT / 2),
PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH, PinWidget::MAXIMUM_PIN_DIRECTION_LABEL_WIDTH,
@@ -256,7 +258,8 @@ void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
painter.drawLine(QLine( painter.drawLine(QLine(
pinGeoPosition.x() + PinWidget::MAXIMUM_HORIZONTAL_WIDTH, pinGeoPosition.x() + PinWidget::MAXIMUM_HORIZONTAL_WIDTH,
pinGeoPosition.y() + (PinWidget::MAXIMUM_VERTICAL_WIDTH / 2), 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) 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" #include "src/Insight/InsightWorker/Tasks/RefreshTargetPinStates.hpp"
using namespace Bloom; namespace Bloom::Widgets::InsightTargetWidgets
using namespace Bloom::Widgets::InsightTargetWidgets; {
using Bloom::Targets::TargetState;
using Bloom::Targets::TargetState; TargetPackageWidget::TargetPackageWidget(
TargetPackageWidget::TargetPackageWidget(
Targets::TargetVariant targetVariant, Targets::TargetVariant targetVariant,
InsightWorker& insightWorker, InsightWorker& insightWorker,
QWidget* parent QWidget* parent
): QWidget(parent), targetVariant(std::move(targetVariant)), insightWorker(insightWorker) { ): QWidget(parent), targetVariant(std::move(targetVariant)), insightWorker(insightWorker) {
QObject::connect( QObject::connect(
&(this->insightWorker), &(this->insightWorker),
&InsightWorker::targetStateUpdated, &InsightWorker::targetStateUpdated,
@@ -29,9 +28,9 @@ TargetPackageWidget::TargetPackageWidget(
); );
this->setDisabled(true); 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); auto* refreshTask = new RefreshTargetPinStates(this->targetVariant.id);
QObject::connect( QObject::connect(
refreshTask, refreshTask,
@@ -50,9 +49,9 @@ void TargetPackageWidget::refreshPinStates(std::optional<std::function<void(void
} }
this->insightWorker.queueTask(refreshTask); this->insightWorker.queueTask(refreshTask);
} }
void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMappingType& pinStatesByNumber) { void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMappingType& pinStatesByNumber) {
for (auto& pinWidget : this->pinWidgets) { for (auto& pinWidget : this->pinWidgets) {
auto pinNumber = pinWidget->getPinNumber(); auto pinNumber = pinWidget->getPinNumber();
if (pinStatesByNumber.contains(pinNumber)) { if (pinStatesByNumber.contains(pinNumber)) {
@@ -61,9 +60,9 @@ void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMappingTy
} }
this->update(); this->update();
} }
void TargetPackageWidget::onTargetStateChanged(TargetState newState) { void TargetPackageWidget::onTargetStateChanged(TargetState newState) {
this->targetState = newState; this->targetState = newState;
if (newState == TargetState::RUNNING) { 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) { if (this->targetState != TargetState::STOPPED) {
return; return;
} }
@@ -90,4 +89,5 @@ void TargetPackageWidget::onRegistersWritten(Targets::TargetRegisters targetRegi
return; return;
} }
} }
}
} }

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