Perform an entire chip erase for UPDI targets, in preparation for programming
This commit is contained in:
@@ -720,16 +720,18 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
return this->writeMemory(avr8MemoryType, startAddress, buffer);
|
return this->writeMemory(avr8MemoryType, startAddress, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::eraseProgramMemorySection(ProgramMemorySection section) {
|
void EdbgAvr8Interface::eraseProgramMemory(std::optional<Avr8Bit::ProgramMemorySection> section) {
|
||||||
if (this->configVariant != Avr8ConfigVariant::XMEGA) {
|
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||||
throw Exception("AVR8 erase command not supported for non-XMEGA config variants.");
|
throw Exception("AVR8 erase command not supported for debugWire config variant.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(
|
auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame(
|
||||||
EraseMemory(
|
EraseMemory(
|
||||||
section == ProgramMemorySection::BOOT
|
section.has_value()
|
||||||
? Avr8EraseMemoryMode::BOOT_SECTION
|
? section == ProgramMemorySection::BOOT
|
||||||
: Avr8EraseMemoryMode::APPLICATION_SECTION
|
? Avr8EraseMemoryMode::BOOT_SECTION
|
||||||
|
: Avr8EraseMemoryMode::APPLICATION_SECTION
|
||||||
|
: Avr8EraseMemoryMode::CHIP
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -243,11 +243,13 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
) override;
|
) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issues the "Erase" command to erase a particular section of program memory.
|
* Issues the "Erase" command to erase a particular section of program memory, or the entire chip.
|
||||||
*
|
*
|
||||||
* @param section
|
* @param section
|
||||||
*/
|
*/
|
||||||
void eraseProgramMemorySection(Targets::Microchip::Avr::Avr8Bit::ProgramMemorySection section) override;
|
void eraseProgramMemory(
|
||||||
|
std::optional<Targets::Microchip::Avr::Avr8Bit::ProgramMemorySection> section = std::nullopt
|
||||||
|
) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current state of the target.
|
* Returns the current state of the target.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.hpp"
|
#include "src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.hpp"
|
||||||
|
|
||||||
@@ -196,11 +197,14 @@ namespace Bloom::DebugToolDrivers::TargetInterfaces::Microchip::Avr::Avr8
|
|||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should erase a particular program memory section.
|
* Should erase the target's entire program memory, or a specific section where applicable.
|
||||||
*
|
*
|
||||||
* @param section
|
* @param section
|
||||||
|
* The section to erase, or std::nullopt to erase the entire program memory.
|
||||||
*/
|
*/
|
||||||
virtual void eraseProgramMemorySection(Targets::Microchip::Avr::Avr8Bit::ProgramMemorySection section) = 0;
|
virtual void eraseProgramMemory(
|
||||||
|
std::optional<Targets::Microchip::Avr::Avr8Bit::ProgramMemorySection> section = std::nullopt
|
||||||
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should obtain the current target state.
|
* Should obtain the current target state.
|
||||||
|
|||||||
@@ -325,42 +325,48 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
void Avr8::writeMemory(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer) {
|
void Avr8::writeMemory(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer) {
|
||||||
if (
|
if (
|
||||||
memoryType == TargetMemoryType::FLASH && this->programmingSession.has_value()
|
memoryType == TargetMemoryType::FLASH && this->programmingSession.has_value()
|
||||||
&& this->targetConfig->physicalInterface == PhysicalInterface::PDI
|
&& this->targetConfig->physicalInterface != PhysicalInterface::DEBUG_WIRE
|
||||||
) {
|
) {
|
||||||
// For PDI targets, we must erase the appropriate section before the first write.
|
if (this->targetConfig->physicalInterface == PhysicalInterface::PDI) {
|
||||||
const auto startSection = this->getProgramMemorySectionFromAddress(startAddress);
|
const auto startSection = this->getProgramMemorySectionFromAddress(startAddress);
|
||||||
const auto endSection = this->getProgramMemorySectionFromAddress(
|
const auto endSection = this->getProgramMemorySectionFromAddress(
|
||||||
static_cast<std::uint32_t>(startAddress + buffer.size() - 1)
|
static_cast<std::uint32_t>(startAddress + buffer.size() - 1)
|
||||||
);
|
|
||||||
|
|
||||||
if (startSection != endSection) {
|
|
||||||
throw Exception(
|
|
||||||
"Requested program memory write spans more than one section (APPLICATION and BOOT) - aborting."
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (startSection != endSection) {
|
||||||
!this->programmingSession->applicationSectionErased
|
throw Exception(
|
||||||
&& (
|
"Requested program memory write spans more than one section (APPLICATION and BOOT) - aborting."
|
||||||
startSection == ProgramMemorySection::APPLICATION
|
);
|
||||||
|| endSection == ProgramMemorySection::APPLICATION
|
}
|
||||||
)
|
|
||||||
) {
|
|
||||||
Logger::warning("Erasing program memory APPLICATION section, in preparation for writing.");
|
|
||||||
this->avr8DebugInterface->eraseProgramMemorySection(ProgramMemorySection::APPLICATION);
|
|
||||||
this->programmingSession->applicationSectionErased = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!this->programmingSession->bootSectionErased
|
!this->programmingSession->applicationSectionErased
|
||||||
|
&& (
|
||||||
|
startSection == ProgramMemorySection::APPLICATION
|
||||||
|
|| endSection == ProgramMemorySection::APPLICATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Logger::warning("Erasing program memory APPLICATION section, in preparation for programming.");
|
||||||
|
this->avr8DebugInterface->eraseProgramMemory(ProgramMemorySection::APPLICATION);
|
||||||
|
this->programmingSession->applicationSectionErased = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!this->programmingSession->bootSectionErased
|
||||||
&& (
|
&& (
|
||||||
startSection == ProgramMemorySection::BOOT
|
startSection == ProgramMemorySection::BOOT
|
||||||
|| endSection == ProgramMemorySection::BOOT
|
|| endSection == ProgramMemorySection::BOOT
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Logger::warning("Erasing program memory BOOT section, in preparation for writing.");
|
Logger::warning("Erasing program memory BOOT section, in preparation for programming.");
|
||||||
this->avr8DebugInterface->eraseProgramMemorySection(ProgramMemorySection::BOOT);
|
this->avr8DebugInterface->eraseProgramMemory(ProgramMemorySection::BOOT);
|
||||||
this->programmingSession->bootSectionErased = true;
|
this->programmingSession->bootSectionErased = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (!this->programmingSession->chipErased) {
|
||||||
|
Logger::warning("Erasing entire chip, in preparation for programming.");
|
||||||
|
this->avr8DebugInterface->eraseProgramMemory();
|
||||||
|
this->programmingSession->chipErased = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -962,7 +968,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProgramMemorySection Avr8::getProgramMemorySectionFromAddress(std::uint32_t address) {
|
ProgramMemorySection Avr8::getProgramMemorySectionFromAddress(std::uint32_t address) {
|
||||||
return address >= this->targetParameters->bootSectionStartAddress.value()
|
return this->targetParameters->bootSectionStartAddress.has_value()
|
||||||
|
&& address >= this->targetParameters->bootSectionStartAddress.value()
|
||||||
? ProgramMemorySection::BOOT
|
? ProgramMemorySection::BOOT
|
||||||
: ProgramMemorySection::APPLICATION;
|
: ProgramMemorySection::APPLICATION;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
{
|
{
|
||||||
struct ProgrammingSession
|
struct ProgrammingSession
|
||||||
{
|
{
|
||||||
|
bool chipErased = false;
|
||||||
bool applicationSectionErased = false;
|
bool applicationSectionErased = false;
|
||||||
bool bootSectionErased = false;
|
bool bootSectionErased = false;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user