Support for reserved hardware breakpoint (for stepping on AVR8 targets)

This commit is contained in:
Nav
2023-09-23 21:50:04 +01:00
parent 0851da3a7a
commit 9904d93314
5 changed files with 68 additions and 18 deletions

View File

@@ -510,12 +510,23 @@ namespace TargetController
if (!this->environmentConfig.targetConfig.hardwareBreakpoints) { if (!this->environmentConfig.targetConfig.hardwareBreakpoints) {
Logger::warning("Hardware breakpoints have been disabled"); Logger::warning("Hardware breakpoints have been disabled");
} else if (targetDescriptor.breakpointResources.maximumHardwareBreakpoints.has_value()) { } else {
Logger::info( const auto& breakpointResources = targetDescriptor.breakpointResources;
"Available hardware breakpoints: " + std::to_string( if (breakpointResources.maximumHardwareBreakpoints.has_value()) {
*(targetDescriptor.breakpointResources.maximumHardwareBreakpoints) Logger::info(
) "Available hardware breakpoints: " + std::to_string(
); *(breakpointResources.maximumHardwareBreakpoints)
)
);
}
if (breakpointResources.reservedHardwareBreakpoints > 0) {
Logger::info(
"Reserved hardware breakpoints: " + std::to_string(
breakpointResources.reservedHardwareBreakpoints
)
);
}
} }
this->programMemoryCache = std::make_unique<Targets::TargetMemoryCache>( this->programMemoryCache = std::make_unique<Targets::TargetMemoryCache>(
@@ -971,7 +982,8 @@ namespace TargetController
if ( if (
!targetBreakpointResources.maximumHardwareBreakpoints.has_value() !targetBreakpointResources.maximumHardwareBreakpoints.has_value()
|| this->hardwareBreakpointsByAddress.size() < *(targetBreakpointResources.maximumHardwareBreakpoints) || this->hardwareBreakpointsByAddress.size() < (*(targetBreakpointResources.maximumHardwareBreakpoints)
- targetBreakpointResources.reservedHardwareBreakpoints)
) { ) {
exhaustedResourcesWarning = true; exhaustedResourcesWarning = true;

View File

@@ -697,7 +697,7 @@ namespace Targets::Microchip::Avr::Avr8Bit
} }
BreakpointResources Avr8::getBreakpointResources() { BreakpointResources Avr8::getBreakpointResources() {
auto maxHardwareBreakpoints = 0; auto maxHardwareBreakpoints = static_cast<std::uint16_t>(0);
switch (this->targetConfig.physicalInterface) { switch (this->targetConfig.physicalInterface) {
case PhysicalInterface::JTAG: { case PhysicalInterface::JTAG: {
@@ -719,7 +719,11 @@ namespace Targets::Microchip::Avr::Avr8Bit
return BreakpointResources( return BreakpointResources(
maxHardwareBreakpoints, maxHardwareBreakpoints,
std::nullopt std::nullopt,
std::min(
static_cast<std::uint16_t>(this->targetConfig.reserveSteppingBreakpoint ? 1 : 0),
maxHardwareBreakpoints
)
); );
} }

View File

@@ -35,31 +35,51 @@ namespace Targets::Microchip::Avr::Avr8Bit
// The 'manageDwenFuseBit' param used to be 'updateDwenFuseBit' - we still support the old, for now. // The 'manageDwenFuseBit' param used to be 'updateDwenFuseBit' - we still support the old, for now.
if (targetNode["updateDwenFuseBit"]) { if (targetNode["updateDwenFuseBit"]) {
this->manageDwenFuseBit = targetNode["updateDwenFuseBit"].as<bool>(); this->manageDwenFuseBit = targetNode["updateDwenFuseBit"].as<bool>(
this->manageDwenFuseBit
);
} }
if (targetNode["manageDwenFuseBit"]) { if (targetNode["manageDwenFuseBit"]) {
this->manageDwenFuseBit = targetNode["manageDwenFuseBit"].as<bool>(); this->manageDwenFuseBit = targetNode["manageDwenFuseBit"].as<bool>(
this->manageDwenFuseBit
);
} }
if (targetNode["cycleTargetPowerPostDwenUpdate"]) { if (targetNode["cycleTargetPowerPostDwenUpdate"]) {
this->cycleTargetPowerPostDwenUpdate = targetNode["cycleTargetPowerPostDwenUpdate"].as<bool>(); this->cycleTargetPowerPostDwenUpdate = targetNode["cycleTargetPowerPostDwenUpdate"].as<bool>(
this->cycleTargetPowerPostDwenUpdate
);
} }
if (targetNode["disableDebugWirePreDisconnect"]) { if (targetNode["disableDebugWirePreDisconnect"]) {
this->disableDebugWireOnDeactivate = targetNode["disableDebugWirePreDisconnect"].as<bool>(); this->disableDebugWireOnDeactivate = targetNode["disableDebugWirePreDisconnect"].as<bool>(
this->disableDebugWireOnDeactivate
);
} }
if (targetNode["targetPowerCycleDelay"]) { if (targetNode["targetPowerCycleDelay"]) {
this->targetPowerCycleDelay = std::chrono::milliseconds(targetNode["targetPowerCycleDelay"].as<int>()); this->targetPowerCycleDelay = std::chrono::milliseconds(targetNode["targetPowerCycleDelay"].as<int>(
this->targetPowerCycleDelay.count()
));
} }
if (targetNode["manageOcdenFuseBit"]) { if (targetNode["manageOcdenFuseBit"]) {
this->manageOcdenFuseBit = targetNode["manageOcdenFuseBit"].as<bool>(); this->manageOcdenFuseBit = targetNode["manageOcdenFuseBit"].as<bool>(
this->manageOcdenFuseBit
);
} }
if (targetNode["preserveEeprom"]) { if (targetNode["preserveEeprom"]) {
this->preserveEeprom = targetNode["preserveEeprom"].as<bool>(); this->preserveEeprom = targetNode["preserveEeprom"].as<bool>(
this->preserveEeprom
);
}
if (targetNode["reserveSteppingBreakpoint"]) {
this->reserveSteppingBreakpoint = targetNode["reserveSteppingBreakpoint"].as<bool>(
this->reserveSteppingBreakpoint
);
} }
} }
} }

View File

@@ -93,6 +93,11 @@ namespace Targets::Microchip::Avr::Avr8Bit
*/ */
bool preserveEeprom = true; bool preserveEeprom = true;
/**
* Determines if Bloom will reserve a single hardware breakpoint for stepping operations.
*/
bool reserveSteppingBreakpoint = true;
explicit Avr8TargetConfig(const TargetConfig& targetConfig); explicit Avr8TargetConfig(const TargetConfig& targetConfig);
private: private:

View File

@@ -2,6 +2,7 @@
#include <cstdint> #include <cstdint>
#include <optional> #include <optional>
#include <cassert>
#include "TargetMemory.hpp" #include "TargetMemory.hpp"
@@ -40,13 +41,21 @@ namespace Targets
{ {
std::optional<std::uint16_t> maximumHardwareBreakpoints; std::optional<std::uint16_t> maximumHardwareBreakpoints;
std::optional<std::uint16_t> maximumSoftwareBreakpoints; std::optional<std::uint16_t> maximumSoftwareBreakpoints;
std::uint16_t reservedHardwareBreakpoints;
BreakpointResources( BreakpointResources(
std::optional<std::uint16_t> maximumHardwareBreakpoints, std::optional<std::uint16_t> maximumHardwareBreakpoints,
std::optional<std::uint16_t> maximumSoftwareBreakpoints std::optional<std::uint16_t> maximumSoftwareBreakpoints,
std::uint16_t reservedHardwareBreakpoints
) )
: maximumHardwareBreakpoints(maximumHardwareBreakpoints) : maximumHardwareBreakpoints(maximumHardwareBreakpoints)
, maximumSoftwareBreakpoints(maximumSoftwareBreakpoints) , maximumSoftwareBreakpoints(maximumSoftwareBreakpoints)
{} , reservedHardwareBreakpoints(reservedHardwareBreakpoints)
{
assert(
!this->maximumHardwareBreakpoints.has_value()
|| this->maximumHardwareBreakpoints >= this->reservedHardwareBreakpoints
);
}
}; };
} }