From eca86fcb1afaacd76f0dce575b1ee92ac9d9eb66 Mon Sep 17 00:00:00 2001 From: Nav Date: Wed, 3 May 2023 23:13:22 +0100 Subject: [PATCH] Added support for flash memory inspection --- .../InsightWorker/Tasks/ReadTargetMemory.hpp | 3 +- .../Tasks/RetrieveMemorySnapshots.hpp | 3 +- .../InsightWorker/Tasks/WriteTargetMemory.cpp | 8 +- .../InsightWorker/Tasks/WriteTargetMemory.hpp | 6 +- .../InsightWindow/InsightWindow.cpp | 191 +++++++++++++++--- .../InsightWindow/InsightWindow.hpp | 4 + .../Stylesheets/InsightWindow.qss | 13 +- .../InsightWindow/UiFiles/InsightWindow.ui | 51 +++++ .../MemoryRegionManagerWindow.cpp | 4 +- .../CreateSnapshotWindow.cpp | 3 +- .../SnapshotDiff/SnapshotDiff.cpp | 11 +- .../SnapshotManager/SnapshotManager.cpp | 9 +- .../SnapshotViewer/SnapshotViewer.cpp | 11 +- .../TargetMemoryInspectionPane.cpp | 9 +- src/ProjectSettings.cpp | 13 ++ src/ProjectSettings.hpp | 2 + src/Targets/Microchip/AVR/AVR8/Avr8.cpp | 7 +- src/Targets/TargetMemory.hpp | 20 ++ 18 files changed, 316 insertions(+), 52 deletions(-) diff --git a/src/Insight/InsightWorker/Tasks/ReadTargetMemory.hpp b/src/Insight/InsightWorker/Tasks/ReadTargetMemory.hpp index 019ef89a..7fcc895a 100644 --- a/src/Insight/InsightWorker/Tasks/ReadTargetMemory.hpp +++ b/src/Insight/InsightWorker/Tasks/ReadTargetMemory.hpp @@ -5,6 +5,7 @@ #include "InsightWorkerTask.hpp" #include "src/Targets/TargetMemory.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" namespace Bloom { @@ -26,7 +27,7 @@ namespace Bloom {} QString brief() const override { - return "Reading target " + QString(this->memoryType == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM"); + return "Reading target " + EnumToStringMappings::targetMemoryTypes.at(this->memoryType).toUpper(); } TaskGroups taskGroups() const override { diff --git a/src/Insight/InsightWorker/Tasks/RetrieveMemorySnapshots.hpp b/src/Insight/InsightWorker/Tasks/RetrieveMemorySnapshots.hpp index 035f3291..ed374346 100644 --- a/src/Insight/InsightWorker/Tasks/RetrieveMemorySnapshots.hpp +++ b/src/Insight/InsightWorker/Tasks/RetrieveMemorySnapshots.hpp @@ -6,6 +6,7 @@ #include "src/Targets/TargetMemory.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" namespace Bloom { @@ -17,7 +18,7 @@ namespace Bloom RetrieveMemorySnapshots(Targets::TargetMemoryType memoryType); QString brief() const override { - return "Loading saved " + QString(this->memoryType == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + return "Loading saved " + EnumToStringMappings::targetMemoryTypes.at(this->memoryType).toUpper() + " memory snapshots"; } diff --git a/src/Insight/InsightWorker/Tasks/WriteTargetMemory.cpp b/src/Insight/InsightWorker/Tasks/WriteTargetMemory.cpp index e3580808..54020854 100644 --- a/src/Insight/InsightWorker/Tasks/WriteTargetMemory.cpp +++ b/src/Insight/InsightWorker/Tasks/WriteTargetMemory.cpp @@ -4,6 +4,8 @@ #include #include +#include "src/Exceptions/Exception.hpp" + namespace Bloom { using Services::TargetControllerService; @@ -11,6 +13,10 @@ namespace Bloom void WriteTargetMemory::run(TargetControllerService& targetControllerService) { using Targets::TargetMemorySize; + if (!this->memoryDescriptor.access.writeableDuringDebugSession) { + throw Exceptions::Exception("Invalid request - cannot write to this memory type during a debug session."); + } + /* * To prevent locking up the TargetController for too long, we split the write operation into numerous * operations. @@ -20,7 +26,7 @@ namespace Bloom */ const auto maxBlockSize = std::max( TargetMemorySize(256), - memoryDescriptor.pageSize.value_or(TargetMemorySize(0)) + this->memoryDescriptor.pageSize.value_or(TargetMemorySize(0)) ); const TargetMemorySize totalBytesToWrite = std::accumulate( diff --git a/src/Insight/InsightWorker/Tasks/WriteTargetMemory.hpp b/src/Insight/InsightWorker/Tasks/WriteTargetMemory.hpp index 14318f0d..ea1ec246 100644 --- a/src/Insight/InsightWorker/Tasks/WriteTargetMemory.hpp +++ b/src/Insight/InsightWorker/Tasks/WriteTargetMemory.hpp @@ -5,6 +5,7 @@ #include "InsightWorkerTask.hpp" #include "src/Targets/TargetMemory.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" namespace Bloom { @@ -48,8 +49,9 @@ namespace Bloom QString brief() const override { return - "Writing to target " - + QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM"); + "Writing to target " + EnumToStringMappings::targetMemoryTypes.at( + this->memoryDescriptor.type + ).toUpper(); } TaskGroups taskGroups() const override { diff --git a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp index 4fa741bc..5ae04d66 100644 --- a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp @@ -152,6 +152,7 @@ namespace Bloom this->ramInspectionButton = this->container->findChild("ram-inspection-btn"); this->eepromInspectionButton = this->container->findChild("eeprom-inspection-btn"); + this->flashInspectionButton = this->container->findChild("flash-inspection-btn"); this->footer = this->windowContainer->findChild("footer"); this->targetStatusLabel = this->footer->findChild("target-state"); @@ -247,6 +248,12 @@ namespace Bloom this, &InsightWindow::toggleEepromInspectionPane ); + QObject::connect( + this->flashInspectionButton, + &QToolButton::clicked, + this, + &InsightWindow::toggleFlashInspectionPane + ); // InsightSignal connections auto* insightSignals = InsightSignals::instance(); @@ -609,9 +616,9 @@ namespace Bloom // Target memory inspection panes auto* bottomPanelLayout = this->bottomPanel->layout(); - // We only support inspection of RAM and EEPROM, for now. const auto ramDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::RAM); const auto eepromDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::EEPROM); + const auto flashDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::FLASH); if (ramDescriptorIt != this->targetDescriptor.memoryDescriptorsByType.end()) { if (!this->insightProjectSettings.ramInspectionPaneState.has_value()) { @@ -694,6 +701,47 @@ namespace Bloom this->eepromInspectionButton->setDisabled(false); this->onEepromInspectionPaneStateChanged(); } + + if (flashDescriptorIt != this->targetDescriptor.memoryDescriptorsByType.end()) { + if (!this->insightProjectSettings.flashInspectionPaneState.has_value()) { + this->insightProjectSettings.flashInspectionPaneState = PaneState(false, true, std::nullopt); + } + + if (!memoryInspectionPaneSettingsByMemoryType.contains(TargetMemoryType::FLASH)) { + memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::FLASH] = TargetMemoryInspectionPaneSettings(); + } + + this->flashInspectionPane = new TargetMemoryInspectionPane( + flashDescriptorIt->second, + memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::FLASH], + *(this->insightProjectSettings.flashInspectionPaneState), + this->bottomPanel + ); + + bottomPanelLayout->addWidget(this->flashInspectionPane); + + QObject::connect( + this->flashInspectionPane, + &PaneWidget::paneActivated, + this, + &InsightWindow::onFlashInspectionPaneStateChanged + ); + QObject::connect( + this->flashInspectionPane, + &PaneWidget::paneDeactivated, + this, + &InsightWindow::onFlashInspectionPaneStateChanged + ); + QObject::connect( + this->flashInspectionPane, + &PaneWidget::paneAttached, + this, + &InsightWindow::onFlashInspectionPaneStateChanged + ); + + this->flashInspectionButton->setDisabled(false); + this->onFlashInspectionPaneStateChanged(); + } } void InsightWindow::destroyPanes() { @@ -1001,19 +1049,28 @@ namespace Bloom } this->ramInspectionPane->deactivate(); + return; + } - } else { + if (this->ramInspectionPane->state.attached) { if ( - this->ramInspectionPane->state.attached - && this->eepromInspectionPane != nullptr + this->eepromInspectionPane != nullptr && this->eepromInspectionPane->state.activated && this->eepromInspectionPane->state.attached ) { this->eepromInspectionPane->deactivate(); } - this->ramInspectionPane->activate(); + if ( + this->flashInspectionPane != nullptr + && this->flashInspectionPane->state.activated + && this->flashInspectionPane->state.attached + ) { + this->flashInspectionPane->deactivate(); + } } + + this->ramInspectionPane->activate(); } void InsightWindow::toggleEepromInspectionPane() { @@ -1026,19 +1083,62 @@ namespace Bloom } this->eepromInspectionPane->deactivate(); + return; + } - } else { + if (this->eepromInspectionPane->state.attached) { if ( - this->eepromInspectionPane->state.attached - && this->ramInspectionPane != nullptr + this->ramInspectionPane != nullptr && this->ramInspectionPane->state.activated && this->ramInspectionPane->state.attached ) { this->ramInspectionPane->deactivate(); } - this->eepromInspectionPane->activate(); + if ( + this->flashInspectionPane != nullptr + && this->flashInspectionPane->state.activated + && this->flashInspectionPane->state.attached + ) { + this->flashInspectionPane->deactivate(); + } } + + this->eepromInspectionPane->activate(); + } + + void InsightWindow::toggleFlashInspectionPane() { + if (this->flashInspectionPane->state.activated) { + if (!this->flashInspectionPane->state.attached) { + this->flashInspectionPane->activateWindow(); + this->flashInspectionButton->setChecked(true); + + return; + } + + this->flashInspectionPane->deactivate(); + return; + } + + if (this->flashInspectionPane->state.attached) { + if ( + this->ramInspectionPane != nullptr + && this->ramInspectionPane->state.activated + && this->ramInspectionPane->state.attached + ) { + this->ramInspectionPane->deactivate(); + } + + if ( + this->eepromInspectionPane != nullptr + && this->eepromInspectionPane->state.activated + && this->eepromInspectionPane->state.attached + ) { + this->eepromInspectionPane->deactivate(); + } + } + + this->flashInspectionPane->activate(); } void InsightWindow::onRegistersPaneStateChanged() { @@ -1052,30 +1152,67 @@ namespace Bloom void InsightWindow::onRamInspectionPaneStateChanged() { this->ramInspectionButton->setChecked(this->ramInspectionPane->state.activated); - if ( - this->ramInspectionPane->state.activated - && this->ramInspectionPane->state.attached - && this->eepromInspectionPane != nullptr - && this->eepromInspectionPane->state.activated - && this->eepromInspectionPane->state.attached - ) { - // Both panes cannot be attached and activated at the same time. - this->eepromInspectionPane->deactivate(); + if (this->ramInspectionPane->state.activated && this->ramInspectionPane->state.attached) { + if ( + this->eepromInspectionPane != nullptr + && this->eepromInspectionPane->state.activated + && this->eepromInspectionPane->state.attached + ) { + this->eepromInspectionPane->deactivate(); + } + + if ( + this->flashInspectionPane != nullptr + && this->flashInspectionPane->state.activated + && this->flashInspectionPane->state.attached + ) { + this->flashInspectionPane->deactivate(); + } } } void InsightWindow::onEepromInspectionPaneStateChanged() { this->eepromInspectionButton->setChecked(this->eepromInspectionPane->state.activated); - if ( - this->eepromInspectionPane->state.activated - && this->eepromInspectionPane->state.attached - && this->ramInspectionPane != nullptr - && this->ramInspectionPane->state.activated - && this->ramInspectionPane->state.attached - ) { - // Both panes cannot be attached and activated at the same time. - this->ramInspectionPane->deactivate(); + if (this->eepromInspectionPane->state.activated && this->eepromInspectionPane->state.attached) { + if ( + this->ramInspectionPane != nullptr + && this->ramInspectionPane->state.activated + && this->ramInspectionPane->state.attached + ) { + this->ramInspectionPane->deactivate(); + } + + if ( + this->flashInspectionPane != nullptr + && this->flashInspectionPane->state.activated + && this->flashInspectionPane->state.attached + ) { + this->flashInspectionPane->deactivate(); + } + } + } + + void InsightWindow::onFlashInspectionPaneStateChanged() { + this->flashInspectionButton->setChecked(this->flashInspectionPane->state.activated); + + if (this->flashInspectionPane->state.activated && this->flashInspectionPane->state.attached) { + if ( + this->ramInspectionPane != nullptr + && this->ramInspectionPane->state.activated + && this->ramInspectionPane->state.attached + ) { + this->ramInspectionPane->deactivate(); + } + + if ( + this->eepromInspectionPane != nullptr + && this->eepromInspectionPane->state.activated + && this->eepromInspectionPane->state.attached + ) { + this->eepromInspectionPane->deactivate(); + } + } } diff --git a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp index 4eb48961..b9869bf1 100644 --- a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp @@ -93,12 +93,14 @@ namespace Bloom Widgets::PanelWidget* bottomPanel = nullptr; Widgets::TargetMemoryInspectionPane* ramInspectionPane = nullptr; Widgets::TargetMemoryInspectionPane* eepromInspectionPane = nullptr; + Widgets::TargetMemoryInspectionPane* flashInspectionPane = nullptr; std::map< Targets::TargetMemoryType, Widgets::TargetMemoryInspectionPaneSettings > memoryInspectionPaneSettingsByMemoryType; QToolButton* ramInspectionButton = nullptr; QToolButton* eepromInspectionButton = nullptr; + QToolButton* flashInspectionButton = nullptr; QWidget* footer = nullptr; Widgets::Label* targetStatusLabel = nullptr; @@ -137,9 +139,11 @@ namespace Bloom void toggleTargetRegistersPane(); void toggleRamInspectionPane(); void toggleEepromInspectionPane(); + void toggleFlashInspectionPane(); void onRegistersPaneStateChanged(); void onRamInspectionPaneStateChanged(); void onEepromInspectionPaneStateChanged(); + void onFlashInspectionPaneStateChanged(); void onProgrammingModeEnabled(); void onProgrammingModeDisabled(); }; diff --git a/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss b/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss index 27c68aa4..89328de4 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss +++ b/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss @@ -211,7 +211,8 @@ QScrollBar::sub-line:vertical { } #bottom-menu-bar #ram-inspection-btn, -#bottom-menu-bar #eeprom-inspection-btn { +#bottom-menu-bar #eeprom-inspection-btn, +#bottom-menu-bar #flash-inspection-btn { position: relative; border: none; min-height: 22px; @@ -225,14 +226,20 @@ QScrollBar::sub-line:vertical { min-width: 99px; } +#bottom-menu-bar #flash-inspection-btn { + min-width: 85px; +} + #bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-icon, -#bottom-menu-bar #eeprom-inspection-btn #eeprom-inspection-btn-icon { +#bottom-menu-bar #eeprom-inspection-btn #eeprom-inspection-btn-icon, +#bottom-menu-bar #flash-inspection-btn #flash-inspection-btn-icon { margin-left: 6px; margin-top: 1px; } #bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-label, -#bottom-menu-bar #eeprom-inspection-btn #eeprom-inspection-btn-label { +#bottom-menu-bar #eeprom-inspection-btn #eeprom-inspection-btn-label, +#bottom-menu-bar #flash-inspection-btn #flash-inspection-btn-label { color: #999a9d; margin-left: 5px; } diff --git a/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui b/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui index 30010a4c..8c3961d3 100644 --- a/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui +++ b/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui @@ -352,6 +352,57 @@ + + + + Inspect FLASH + + + true + + + false + + + + 0 + + + 0 + + + + + 22 + + + 26 + + + :/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon.svg + + + :/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon-disabled.svg + + + + + + + FLASH + + + + + + + Qt::Horizontal + + + + + + diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp index 73012e24..3b3f53ff 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp @@ -8,6 +8,7 @@ #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.hpp" #include "src/Services/PathService.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" #include "src/Exceptions/Exception.hpp" namespace Bloom::Widgets @@ -28,8 +29,7 @@ namespace Bloom::Widgets this->setWindowFlag(Qt::Window); this->setObjectName("memory-region-manager-window"); this->setWindowTitle( - "Memory Regions - " - + QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + "Memory Regions - " + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper() ); auto windowUiFile = QFile( diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/CreateSnapshotWindow/CreateSnapshotWindow.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/CreateSnapshotWindow/CreateSnapshotWindow.cpp index e138b0ce..2aac143d 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/CreateSnapshotWindow/CreateSnapshotWindow.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/CreateSnapshotWindow/CreateSnapshotWindow.cpp @@ -9,6 +9,7 @@ #include "src/Insight/InsightSignals.hpp" #include "src/Services/PathService.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" #include "src/Exceptions/Exception.hpp" namespace Bloom::Widgets @@ -28,7 +29,7 @@ namespace Bloom::Widgets this->setWindowFlag(Qt::Window); this->setObjectName("create-snapshot-window"); this->setWindowTitle( - "New Snapshot - " + QString(memoryType == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + "New Snapshot - " + EnumToStringMappings::targetMemoryTypes.at(memoryType).toUpper() ); auto windowUiFile = QFile( diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp index b170e245..59239e7b 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp @@ -12,6 +12,7 @@ #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ConfirmationDialog.hpp" #include "src/Services/PathService.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" #include "src/Exceptions/Exception.hpp" #include "src/Insight/InsightSignals.hpp" @@ -81,7 +82,13 @@ namespace Bloom::Widgets this->dataASecondaryLabel->setText(snapshotA.createdDate.toString("dd/MM/yyyy hh:mm")); this->dataBSecondaryLabel->setVisible(false); - this->restoreBytesAction = new ContextMenuAction("Restore Selection", std::nullopt, this); + this->restoreBytesAction = new ContextMenuAction( + "Restore Selection", + [this] (const std::unordered_map&) { + return this->memoryDescriptor.access.writeableDuringDebugSession; + }, + this + ); QObject::connect( this->restoreBytesAction, @@ -329,7 +336,7 @@ namespace Bloom::Widgets "Restore selected bytes", "This operation will write " + QString::number(sortedByteItemsByAddress.size()) + " byte(s) to the target's " - + QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper() + ".

Are you sure you want to proceed?", "Proceed", std::nullopt, diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp index 38e3ec7e..2ea7b457 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp @@ -14,6 +14,7 @@ #include "src/Insight/InsightWorker/InsightWorker.hpp" #include "src/Services/PathService.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" #include "src/Exceptions/Exception.hpp" #include "src/Logger/Logger.hpp" @@ -495,8 +496,8 @@ namespace Bloom::Widgets auto* confirmationDialog = new ConfirmationDialog( "Restore snapshot", "This operation will overwrite the entire address range of the target's " - + QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") - + " with the contents of the selected snapshot.

Are you sure you want to proceed?", + + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper() + + " with the contents of the selected snapshot.

Are you sure you want to proceed?", "Proceed", std::nullopt, this @@ -611,7 +612,9 @@ namespace Bloom::Widgets && this->data.has_value() ); this->restoreSnapshotAction->setEnabled( - this->selectedSnapshotItems.size() == 1 && this->targetState == Targets::TargetState::STOPPED + this->memoryDescriptor.access.writeableDuringDebugSession + && this->selectedSnapshotItems.size() == 1 + && this->targetState == Targets::TargetState::STOPPED ); menu->exec(sourcePosition); diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotViewer/SnapshotViewer.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotViewer/SnapshotViewer.cpp index 7ce6c081..84475e97 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotViewer/SnapshotViewer.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotViewer/SnapshotViewer.cpp @@ -17,6 +17,7 @@ #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ConfirmationDialog.hpp" #include "src/Services/PathService.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" #include "src/Exceptions/Exception.hpp" #include "src/Insight/InsightSignals.hpp" @@ -123,7 +124,13 @@ namespace Bloom::Widgets memoryRegionsLayout->insertWidget(0, this->memoryRegionListView); } - this->restoreBytesAction = new ContextMenuAction("Restore Selection", std::nullopt, this); + this->restoreBytesAction = new ContextMenuAction( + "Restore Selection", + [this] (const std::unordered_map&) { + return this->memoryDescriptor.access.writeableDuringDebugSession; + }, + this + ); this->hexViewerWidget = new HexViewerWidget( this->memoryDescriptor, @@ -214,7 +221,7 @@ namespace Bloom::Widgets "Restore selected bytes", "This operation will write " + QString::number(sortedByteItemsByAddress.size()) + " byte(s) to the target's " - + QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper() + ".

Are you sure you want to proceed?", "Proceed", std::nullopt, diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp index 00452b8a..3bbfdea2 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp @@ -13,6 +13,7 @@ #include "src/Insight/InsightWorker/Tasks/ReadStackPointer.hpp" #include "src/Services/PathService.hpp" +#include "src/Helpers/EnumToStringMappings.hpp" #include "src/Exceptions/Exception.hpp" namespace Bloom::Widgets @@ -35,11 +36,9 @@ namespace Bloom::Widgets { this->setObjectName("target-memory-inspection-pane"); - const auto memoryName = QString( - this->targetMemoryDescriptor.type == TargetMemoryType::EEPROM - ? "Internal EEPROM" - : "Internal RAM" - ); + const auto memoryName = "Internal " + EnumToStringMappings::targetMemoryTypes.at( + this->targetMemoryDescriptor.type + ).toUpper(); this->setWindowTitle("Memory Inspection - " + memoryName); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); diff --git a/src/ProjectSettings.cpp b/src/ProjectSettings.cpp index 204a995d..3a2b260f 100644 --- a/src/ProjectSettings.cpp +++ b/src/ProjectSettings.cpp @@ -64,6 +64,12 @@ namespace Bloom ); } + if (jsonObject.contains("flashInspectionPaneState")) { + this->flashInspectionPaneState = this->paneStateFromJson( + jsonObject.find("flashInspectionPaneState")->toObject() + ); + } + if (jsonObject.contains("memoryInspectionPaneSettings")) { const auto settingsMappingObj = jsonObject.find("memoryInspectionPaneSettings")->toObject(); @@ -144,6 +150,13 @@ namespace Bloom ); } + if (this->flashInspectionPaneState.has_value()) { + insightObj.insert( + "flashInspectionPaneState", + this->paneStateToJson(this->flashInspectionPaneState.value()) + ); + } + return insightObj; } diff --git a/src/ProjectSettings.hpp b/src/ProjectSettings.hpp index e5e94f42..907c3939 100644 --- a/src/ProjectSettings.hpp +++ b/src/ProjectSettings.hpp @@ -25,6 +25,7 @@ namespace Bloom std::optional registersPaneState; std::optional ramInspectionPaneState; std::optional eepromInspectionPaneState; + std::optional flashInspectionPaneState; std::map< Targets::TargetMemoryType, @@ -40,6 +41,7 @@ namespace Bloom static const inline BiMap memoryTypesByName = { {Targets::TargetMemoryType::RAM, "ram"}, {Targets::TargetMemoryType::EEPROM, "eeprom"}, + {Targets::TargetMemoryType::FLASH, "flash"}, }; static const inline BiMap addressTypesByName = { diff --git a/src/Targets/Microchip/AVR/AVR8/Avr8.cpp b/src/Targets/Microchip/AVR/AVR8/Avr8.cpp index 58a3c7a7..b6679522 100644 --- a/src/Targets/Microchip/AVR/AVR8/Avr8.cpp +++ b/src/Targets/Microchip/AVR/AVR8/Avr8.cpp @@ -723,7 +723,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit TargetMemoryAddressRange( ramStartAddress, ramStartAddress + this->targetParameters->ramSize.value() - 1 - ) + ), + TargetMemoryAccess(true, true, true) ) )); @@ -735,6 +736,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit flashStartAddress, flashStartAddress + this->targetParameters->flashSize.value() - 1 ), + TargetMemoryAccess(true, true, false), this->targetParameters->flashPageSize ) )); @@ -749,7 +751,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit TargetMemoryAddressRange( eepromStartAddress, eepromStartAddress + this->targetParameters->eepromSize.value() - 1 - ) + ), + TargetMemoryAccess(true, true, true) ) )); } diff --git a/src/Targets/TargetMemory.hpp b/src/Targets/TargetMemory.hpp index 0425b302..ac1a23bb 100644 --- a/src/Targets/TargetMemory.hpp +++ b/src/Targets/TargetMemory.hpp @@ -61,19 +61,39 @@ namespace Bloom::Targets } }; + struct TargetMemoryAccess + { + bool readable = false; + bool writeable = false; + bool writeableDuringDebugSession = false; + + TargetMemoryAccess( + bool readable, + bool writeable, + bool writeableDuringDebugSession + ) + : readable(readable) + , writeable(writeable) + , writeableDuringDebugSession(writeableDuringDebugSession) + {} + }; + struct TargetMemoryDescriptor { TargetMemoryType type; TargetMemoryAddressRange addressRange; + TargetMemoryAccess access; std::optional pageSize; TargetMemoryDescriptor( TargetMemoryType type, TargetMemoryAddressRange addressRange, + TargetMemoryAccess access, std::optional pageSize = std::nullopt ) : type(type) , addressRange(addressRange) + , access(access) , pageSize(pageSize) {};