Added support for flash memory inspection

This commit is contained in:
Nav
2023-05-03 23:13:22 +01:00
parent da5db96f11
commit eca86fcb1a
18 changed files with 316 additions and 52 deletions

View File

@@ -5,6 +5,7 @@
#include "InsightWorkerTask.hpp" #include "InsightWorkerTask.hpp"
#include "src/Targets/TargetMemory.hpp" #include "src/Targets/TargetMemory.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
namespace Bloom namespace Bloom
{ {
@@ -26,7 +27,7 @@ namespace Bloom
{} {}
QString brief() const override { 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 { TaskGroups taskGroups() const override {

View File

@@ -6,6 +6,7 @@
#include "src/Targets/TargetMemory.hpp" #include "src/Targets/TargetMemory.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
namespace Bloom namespace Bloom
{ {
@@ -17,7 +18,7 @@ namespace Bloom
RetrieveMemorySnapshots(Targets::TargetMemoryType memoryType); RetrieveMemorySnapshots(Targets::TargetMemoryType memoryType);
QString brief() const override { 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"; + " memory snapshots";
} }

View File

@@ -4,6 +4,8 @@
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
#include "src/Exceptions/Exception.hpp"
namespace Bloom namespace Bloom
{ {
using Services::TargetControllerService; using Services::TargetControllerService;
@@ -11,6 +13,10 @@ namespace Bloom
void WriteTargetMemory::run(TargetControllerService& targetControllerService) { void WriteTargetMemory::run(TargetControllerService& targetControllerService) {
using Targets::TargetMemorySize; 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 * To prevent locking up the TargetController for too long, we split the write operation into numerous
* operations. * operations.
@@ -20,7 +26,7 @@ namespace Bloom
*/ */
const auto maxBlockSize = std::max( const auto maxBlockSize = std::max(
TargetMemorySize(256), TargetMemorySize(256),
memoryDescriptor.pageSize.value_or(TargetMemorySize(0)) this->memoryDescriptor.pageSize.value_or(TargetMemorySize(0))
); );
const TargetMemorySize totalBytesToWrite = std::accumulate( const TargetMemorySize totalBytesToWrite = std::accumulate(

View File

@@ -5,6 +5,7 @@
#include "InsightWorkerTask.hpp" #include "InsightWorkerTask.hpp"
#include "src/Targets/TargetMemory.hpp" #include "src/Targets/TargetMemory.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
namespace Bloom namespace Bloom
{ {
@@ -48,8 +49,9 @@ namespace Bloom
QString brief() const override { QString brief() const override {
return return
"Writing to target " "Writing to target " + EnumToStringMappings::targetMemoryTypes.at(
+ QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM"); this->memoryDescriptor.type
).toUpper();
} }
TaskGroups taskGroups() const override { TaskGroups taskGroups() const override {

View File

@@ -152,6 +152,7 @@ namespace Bloom
this->ramInspectionButton = this->container->findChild<QToolButton*>("ram-inspection-btn"); this->ramInspectionButton = this->container->findChild<QToolButton*>("ram-inspection-btn");
this->eepromInspectionButton = this->container->findChild<QToolButton*>("eeprom-inspection-btn"); this->eepromInspectionButton = this->container->findChild<QToolButton*>("eeprom-inspection-btn");
this->flashInspectionButton = this->container->findChild<QToolButton*>("flash-inspection-btn");
this->footer = this->windowContainer->findChild<QWidget*>("footer"); this->footer = this->windowContainer->findChild<QWidget*>("footer");
this->targetStatusLabel = this->footer->findChild<Label*>("target-state"); this->targetStatusLabel = this->footer->findChild<Label*>("target-state");
@@ -247,6 +248,12 @@ namespace Bloom
this, this,
&InsightWindow::toggleEepromInspectionPane &InsightWindow::toggleEepromInspectionPane
); );
QObject::connect(
this->flashInspectionButton,
&QToolButton::clicked,
this,
&InsightWindow::toggleFlashInspectionPane
);
// InsightSignal connections // InsightSignal connections
auto* insightSignals = InsightSignals::instance(); auto* insightSignals = InsightSignals::instance();
@@ -609,9 +616,9 @@ namespace Bloom
// Target memory inspection panes // Target memory inspection panes
auto* bottomPanelLayout = this->bottomPanel->layout(); 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 ramDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::RAM);
const auto eepromDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::EEPROM); 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 (ramDescriptorIt != this->targetDescriptor.memoryDescriptorsByType.end()) {
if (!this->insightProjectSettings.ramInspectionPaneState.has_value()) { if (!this->insightProjectSettings.ramInspectionPaneState.has_value()) {
@@ -694,6 +701,47 @@ namespace Bloom
this->eepromInspectionButton->setDisabled(false); this->eepromInspectionButton->setDisabled(false);
this->onEepromInspectionPaneStateChanged(); 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() { void InsightWindow::destroyPanes() {
@@ -1001,19 +1049,28 @@ namespace Bloom
} }
this->ramInspectionPane->deactivate(); this->ramInspectionPane->deactivate();
return;
}
} else { if (this->ramInspectionPane->state.attached) {
if ( if (
this->ramInspectionPane->state.attached this->eepromInspectionPane != nullptr
&& this->eepromInspectionPane != nullptr
&& this->eepromInspectionPane->state.activated && this->eepromInspectionPane->state.activated
&& this->eepromInspectionPane->state.attached && this->eepromInspectionPane->state.attached
) { ) {
this->eepromInspectionPane->deactivate(); 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() { void InsightWindow::toggleEepromInspectionPane() {
@@ -1026,19 +1083,62 @@ namespace Bloom
} }
this->eepromInspectionPane->deactivate(); this->eepromInspectionPane->deactivate();
return;
}
} else { if (this->eepromInspectionPane->state.attached) {
if ( if (
this->eepromInspectionPane->state.attached this->ramInspectionPane != nullptr
&& this->ramInspectionPane != nullptr
&& this->ramInspectionPane->state.activated && this->ramInspectionPane->state.activated
&& this->ramInspectionPane->state.attached && this->ramInspectionPane->state.attached
) { ) {
this->ramInspectionPane->deactivate(); 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() { void InsightWindow::onRegistersPaneStateChanged() {
@@ -1052,30 +1152,67 @@ namespace Bloom
void InsightWindow::onRamInspectionPaneStateChanged() { void InsightWindow::onRamInspectionPaneStateChanged() {
this->ramInspectionButton->setChecked(this->ramInspectionPane->state.activated); this->ramInspectionButton->setChecked(this->ramInspectionPane->state.activated);
if ( if (this->ramInspectionPane->state.activated && this->ramInspectionPane->state.attached) {
this->ramInspectionPane->state.activated if (
&& this->ramInspectionPane->state.attached this->eepromInspectionPane != nullptr
&& this->eepromInspectionPane != nullptr && this->eepromInspectionPane->state.activated
&& this->eepromInspectionPane->state.activated && this->eepromInspectionPane->state.attached
&& this->eepromInspectionPane->state.attached ) {
) { this->eepromInspectionPane->deactivate();
// Both panes cannot be attached and activated at the same time. }
this->eepromInspectionPane->deactivate();
if (
this->flashInspectionPane != nullptr
&& this->flashInspectionPane->state.activated
&& this->flashInspectionPane->state.attached
) {
this->flashInspectionPane->deactivate();
}
} }
} }
void InsightWindow::onEepromInspectionPaneStateChanged() { void InsightWindow::onEepromInspectionPaneStateChanged() {
this->eepromInspectionButton->setChecked(this->eepromInspectionPane->state.activated); this->eepromInspectionButton->setChecked(this->eepromInspectionPane->state.activated);
if ( if (this->eepromInspectionPane->state.activated && this->eepromInspectionPane->state.attached) {
this->eepromInspectionPane->state.activated if (
&& this->eepromInspectionPane->state.attached this->ramInspectionPane != nullptr
&& this->ramInspectionPane != nullptr && this->ramInspectionPane->state.activated
&& this->ramInspectionPane->state.activated && this->ramInspectionPane->state.attached
&& this->ramInspectionPane->state.attached ) {
) { this->ramInspectionPane->deactivate();
// Both panes cannot be attached and activated at the same time. }
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();
}
} }
} }

View File

@@ -93,12 +93,14 @@ namespace Bloom
Widgets::PanelWidget* bottomPanel = nullptr; Widgets::PanelWidget* bottomPanel = nullptr;
Widgets::TargetMemoryInspectionPane* ramInspectionPane = nullptr; Widgets::TargetMemoryInspectionPane* ramInspectionPane = nullptr;
Widgets::TargetMemoryInspectionPane* eepromInspectionPane = nullptr; Widgets::TargetMemoryInspectionPane* eepromInspectionPane = nullptr;
Widgets::TargetMemoryInspectionPane* flashInspectionPane = nullptr;
std::map< std::map<
Targets::TargetMemoryType, Targets::TargetMemoryType,
Widgets::TargetMemoryInspectionPaneSettings Widgets::TargetMemoryInspectionPaneSettings
> memoryInspectionPaneSettingsByMemoryType; > memoryInspectionPaneSettingsByMemoryType;
QToolButton* ramInspectionButton = nullptr; QToolButton* ramInspectionButton = nullptr;
QToolButton* eepromInspectionButton = nullptr; QToolButton* eepromInspectionButton = nullptr;
QToolButton* flashInspectionButton = nullptr;
QWidget* footer = nullptr; QWidget* footer = nullptr;
Widgets::Label* targetStatusLabel = nullptr; Widgets::Label* targetStatusLabel = nullptr;
@@ -137,9 +139,11 @@ namespace Bloom
void toggleTargetRegistersPane(); void toggleTargetRegistersPane();
void toggleRamInspectionPane(); void toggleRamInspectionPane();
void toggleEepromInspectionPane(); void toggleEepromInspectionPane();
void toggleFlashInspectionPane();
void onRegistersPaneStateChanged(); void onRegistersPaneStateChanged();
void onRamInspectionPaneStateChanged(); void onRamInspectionPaneStateChanged();
void onEepromInspectionPaneStateChanged(); void onEepromInspectionPaneStateChanged();
void onFlashInspectionPaneStateChanged();
void onProgrammingModeEnabled(); void onProgrammingModeEnabled();
void onProgrammingModeDisabled(); void onProgrammingModeDisabled();
}; };

View File

@@ -211,7 +211,8 @@ QScrollBar::sub-line:vertical {
} }
#bottom-menu-bar #ram-inspection-btn, #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; position: relative;
border: none; border: none;
min-height: 22px; min-height: 22px;
@@ -225,14 +226,20 @@ QScrollBar::sub-line:vertical {
min-width: 99px; 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 #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-left: 6px;
margin-top: 1px; margin-top: 1px;
} }
#bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-label, #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; color: #999a9d;
margin-left: 5px; margin-left: 5px;
} }

View File

@@ -352,6 +352,57 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QToolButton" name="flash-inspection-btn">
<property name="toolTip">
<string>Inspect FLASH</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="disabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item alignment="Qt::AlignLeft">
<widget class="SvgWidget" name="flash-inspection-btn-icon">
<property name="containerHeight">
<number>22</number>
</property>
<property name="containerWidth">
<number>26</number>
</property>
<property name="svgFilePath">
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon.svg</string>
</property>
<property name="disabledSvgFilePath">
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon-disabled.svg</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="Label" name="flash-inspection-btn-label">
<property name="text">
<string>FLASH</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<spacer name="horizontal-spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="horizontal-spacer"> <spacer name="horizontal-spacer">
<property name="orientation"> <property name="orientation">

View File

@@ -8,6 +8,7 @@
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.hpp"
#include "src/Services/PathService.hpp" #include "src/Services/PathService.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
namespace Bloom::Widgets namespace Bloom::Widgets
@@ -28,8 +29,7 @@ namespace Bloom::Widgets
this->setWindowFlag(Qt::Window); this->setWindowFlag(Qt::Window);
this->setObjectName("memory-region-manager-window"); this->setObjectName("memory-region-manager-window");
this->setWindowTitle( this->setWindowTitle(
"Memory Regions - " "Memory Regions - " + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper()
+ QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM")
); );
auto windowUiFile = QFile( auto windowUiFile = QFile(

View File

@@ -9,6 +9,7 @@
#include "src/Insight/InsightSignals.hpp" #include "src/Insight/InsightSignals.hpp"
#include "src/Services/PathService.hpp" #include "src/Services/PathService.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
namespace Bloom::Widgets namespace Bloom::Widgets
@@ -28,7 +29,7 @@ namespace Bloom::Widgets
this->setWindowFlag(Qt::Window); this->setWindowFlag(Qt::Window);
this->setObjectName("create-snapshot-window"); this->setObjectName("create-snapshot-window");
this->setWindowTitle( this->setWindowTitle(
"New Snapshot - " + QString(memoryType == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") "New Snapshot - " + EnumToStringMappings::targetMemoryTypes.at(memoryType).toUpper()
); );
auto windowUiFile = QFile( auto windowUiFile = QFile(

View File

@@ -12,6 +12,7 @@
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ConfirmationDialog.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ConfirmationDialog.hpp"
#include "src/Services/PathService.hpp" #include "src/Services/PathService.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
#include "src/Insight/InsightSignals.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->dataASecondaryLabel->setText(snapshotA.createdDate.toString("dd/MM/yyyy hh:mm"));
this->dataBSecondaryLabel->setVisible(false); this->dataBSecondaryLabel->setVisible(false);
this->restoreBytesAction = new ContextMenuAction("Restore Selection", std::nullopt, this); this->restoreBytesAction = new ContextMenuAction(
"Restore Selection",
[this] (const std::unordered_map<Targets::TargetMemoryAddress, ByteItem*>&) {
return this->memoryDescriptor.access.writeableDuringDebugSession;
},
this
);
QObject::connect( QObject::connect(
this->restoreBytesAction, this->restoreBytesAction,
@@ -329,7 +336,7 @@ namespace Bloom::Widgets
"Restore selected bytes", "Restore selected bytes",
"This operation will write " + QString::number(sortedByteItemsByAddress.size()) "This operation will write " + QString::number(sortedByteItemsByAddress.size())
+ " byte(s) to the target's " + " byte(s) to the target's "
+ QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper()
+ ".<br/><br/>Are you sure you want to proceed?", + ".<br/><br/>Are you sure you want to proceed?",
"Proceed", "Proceed",
std::nullopt, std::nullopt,

View File

@@ -14,6 +14,7 @@
#include "src/Insight/InsightWorker/InsightWorker.hpp" #include "src/Insight/InsightWorker/InsightWorker.hpp"
#include "src/Services/PathService.hpp" #include "src/Services/PathService.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
#include "src/Logger/Logger.hpp" #include "src/Logger/Logger.hpp"
@@ -495,8 +496,8 @@ namespace Bloom::Widgets
auto* confirmationDialog = new ConfirmationDialog( auto* confirmationDialog = new ConfirmationDialog(
"Restore snapshot", "Restore snapshot",
"This operation will overwrite the entire address range of the target's " "This operation will overwrite the entire address range of the target's "
+ QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper()
+ " with the contents of the selected snapshot.<br/><br/>Are you sure you want to proceed?", + " with the contents of the selected snapshot.<br/><br/>Are you sure you want to proceed?",
"Proceed", "Proceed",
std::nullopt, std::nullopt,
this this
@@ -611,7 +612,9 @@ namespace Bloom::Widgets
&& this->data.has_value() && this->data.has_value()
); );
this->restoreSnapshotAction->setEnabled( 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); menu->exec(sourcePosition);

View File

@@ -17,6 +17,7 @@
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ConfirmationDialog.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ConfirmationDialog.hpp"
#include "src/Services/PathService.hpp" #include "src/Services/PathService.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
#include "src/Insight/InsightSignals.hpp" #include "src/Insight/InsightSignals.hpp"
@@ -123,7 +124,13 @@ namespace Bloom::Widgets
memoryRegionsLayout->insertWidget(0, this->memoryRegionListView); 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<Targets::TargetMemoryAddress, ByteItem*>&) {
return this->memoryDescriptor.access.writeableDuringDebugSession;
},
this
);
this->hexViewerWidget = new HexViewerWidget( this->hexViewerWidget = new HexViewerWidget(
this->memoryDescriptor, this->memoryDescriptor,
@@ -214,7 +221,7 @@ namespace Bloom::Widgets
"Restore selected bytes", "Restore selected bytes",
"This operation will write " + QString::number(sortedByteItemsByAddress.size()) "This operation will write " + QString::number(sortedByteItemsByAddress.size())
+ " byte(s) to the target's " + " byte(s) to the target's "
+ QString(this->memoryDescriptor.type == Targets::TargetMemoryType::EEPROM ? "EEPROM" : "RAM") + EnumToStringMappings::targetMemoryTypes.at(this->memoryDescriptor.type).toUpper()
+ ".<br/><br/>Are you sure you want to proceed?", + ".<br/><br/>Are you sure you want to proceed?",
"Proceed", "Proceed",
std::nullopt, std::nullopt,

View File

@@ -13,6 +13,7 @@
#include "src/Insight/InsightWorker/Tasks/ReadStackPointer.hpp" #include "src/Insight/InsightWorker/Tasks/ReadStackPointer.hpp"
#include "src/Services/PathService.hpp" #include "src/Services/PathService.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp" #include "src/Exceptions/Exception.hpp"
namespace Bloom::Widgets namespace Bloom::Widgets
@@ -35,11 +36,9 @@ namespace Bloom::Widgets
{ {
this->setObjectName("target-memory-inspection-pane"); this->setObjectName("target-memory-inspection-pane");
const auto memoryName = QString( const auto memoryName = "Internal " + EnumToStringMappings::targetMemoryTypes.at(
this->targetMemoryDescriptor.type == TargetMemoryType::EEPROM this->targetMemoryDescriptor.type
? "Internal EEPROM" ).toUpper();
: "Internal RAM"
);
this->setWindowTitle("Memory Inspection - " + memoryName); this->setWindowTitle("Memory Inspection - " + memoryName);
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);

View File

@@ -64,6 +64,12 @@ namespace Bloom
); );
} }
if (jsonObject.contains("flashInspectionPaneState")) {
this->flashInspectionPaneState = this->paneStateFromJson(
jsonObject.find("flashInspectionPaneState")->toObject()
);
}
if (jsonObject.contains("memoryInspectionPaneSettings")) { if (jsonObject.contains("memoryInspectionPaneSettings")) {
const auto settingsMappingObj = jsonObject.find("memoryInspectionPaneSettings")->toObject(); 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; return insightObj;
} }

View File

@@ -25,6 +25,7 @@ namespace Bloom
std::optional<Widgets::PaneState> registersPaneState; std::optional<Widgets::PaneState> registersPaneState;
std::optional<Widgets::PaneState> ramInspectionPaneState; std::optional<Widgets::PaneState> ramInspectionPaneState;
std::optional<Widgets::PaneState> eepromInspectionPaneState; std::optional<Widgets::PaneState> eepromInspectionPaneState;
std::optional<Widgets::PaneState> flashInspectionPaneState;
std::map< std::map<
Targets::TargetMemoryType, Targets::TargetMemoryType,
@@ -40,6 +41,7 @@ namespace Bloom
static const inline BiMap<Targets::TargetMemoryType, QString> memoryTypesByName = { static const inline BiMap<Targets::TargetMemoryType, QString> memoryTypesByName = {
{Targets::TargetMemoryType::RAM, "ram"}, {Targets::TargetMemoryType::RAM, "ram"},
{Targets::TargetMemoryType::EEPROM, "eeprom"}, {Targets::TargetMemoryType::EEPROM, "eeprom"},
{Targets::TargetMemoryType::FLASH, "flash"},
}; };
static const inline BiMap<AddressType, QString> addressTypesByName = { static const inline BiMap<AddressType, QString> addressTypesByName = {

View File

@@ -723,7 +723,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
TargetMemoryAddressRange( TargetMemoryAddressRange(
ramStartAddress, ramStartAddress,
ramStartAddress + this->targetParameters->ramSize.value() - 1 ramStartAddress + this->targetParameters->ramSize.value() - 1
) ),
TargetMemoryAccess(true, true, true)
) )
)); ));
@@ -735,6 +736,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
flashStartAddress, flashStartAddress,
flashStartAddress + this->targetParameters->flashSize.value() - 1 flashStartAddress + this->targetParameters->flashSize.value() - 1
), ),
TargetMemoryAccess(true, true, false),
this->targetParameters->flashPageSize this->targetParameters->flashPageSize
) )
)); ));
@@ -749,7 +751,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
TargetMemoryAddressRange( TargetMemoryAddressRange(
eepromStartAddress, eepromStartAddress,
eepromStartAddress + this->targetParameters->eepromSize.value() - 1 eepromStartAddress + this->targetParameters->eepromSize.value() - 1
) ),
TargetMemoryAccess(true, true, true)
) )
)); ));
} }

View File

@@ -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 struct TargetMemoryDescriptor
{ {
TargetMemoryType type; TargetMemoryType type;
TargetMemoryAddressRange addressRange; TargetMemoryAddressRange addressRange;
TargetMemoryAccess access;
std::optional<TargetMemorySize> pageSize; std::optional<TargetMemorySize> pageSize;
TargetMemoryDescriptor( TargetMemoryDescriptor(
TargetMemoryType type, TargetMemoryType type,
TargetMemoryAddressRange addressRange, TargetMemoryAddressRange addressRange,
TargetMemoryAccess access,
std::optional<TargetMemorySize> pageSize = std::nullopt std::optional<TargetMemorySize> pageSize = std::nullopt
) )
: type(type) : type(type)
, addressRange(addressRange) , addressRange(addressRange)
, access(access)
, pageSize(pageSize) , pageSize(pageSize)
{}; {};