WCH-Link erase command doesn't erase the whole chip, as initially thought. It only erases the program memory segment.
The boot segment appears to be left untouched.
This commit is contained in:
@@ -45,14 +45,27 @@ namespace DebugServer::Gdb::RiscVGdb::CommandPackets
|
||||
Logger::info("Handling FlashErase packet");
|
||||
|
||||
try {
|
||||
const auto segmentDescriptorOpt = gdbTargetDescriptor.systemAddressSpaceDescriptor.getContainingMemorySegmentDescriptor(
|
||||
this->startAddress
|
||||
);
|
||||
|
||||
if (!segmentDescriptorOpt.has_value()) {
|
||||
throw Exception{"Invalid command - no containing memory segment found for the given start address"};
|
||||
}
|
||||
|
||||
const auto& segmentDescriptor = segmentDescriptorOpt->get();
|
||||
if (!segmentDescriptor.programmingModeAccess.writeable) {
|
||||
throw Exception{"Memory segment (\"" + segmentDescriptor.name + "\") not writable in programming mode"};
|
||||
}
|
||||
|
||||
Logger::warning("Erasing \"" + segmentDescriptor.name + "\" segment, in preparation for programming");
|
||||
|
||||
targetControllerService.enableProgrammingMode();
|
||||
|
||||
Logger::warning("Erasing program memory, in preparation for programming");
|
||||
|
||||
// We don't erase a specific address range - we just erase the entire program memory.
|
||||
// We don't erase a specific address range - we just erase the entire segment
|
||||
targetControllerService.eraseMemory(
|
||||
gdbTargetDescriptor.systemAddressSpaceDescriptor,
|
||||
gdbTargetDescriptor.programMemorySegmentDescriptor
|
||||
segmentDescriptor
|
||||
);
|
||||
|
||||
debugSession.connection.writePacket(OkResponsePacket{});
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
namespace DebugToolDrivers::Wch::Protocols::WchLink::Commands
|
||||
{
|
||||
class EraseChip: public Command<std::array<unsigned char, 1>>
|
||||
class EraseProgramMemory: public Command<std::array<unsigned char, 1>>
|
||||
{
|
||||
public:
|
||||
EraseChip()
|
||||
EraseProgramMemory()
|
||||
: Command(0x02)
|
||||
{
|
||||
this->payload = {
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "Commands/StartRamCodeWrite.hpp"
|
||||
#include "Commands/EndRamCodeWrite.hpp"
|
||||
#include "Commands/WriteFlash.hpp"
|
||||
#include "Commands/EraseChip.hpp"
|
||||
#include "Commands/EraseProgramMemory.hpp"
|
||||
|
||||
#include "src/Helpers/BiMap.hpp"
|
||||
#include "src/Services/StringService.hpp"
|
||||
@@ -243,7 +243,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
this->sendCommandAndWaitForResponse(Commands::EndProgrammingSession{});
|
||||
}
|
||||
|
||||
void WchLinkInterface::eraseChip() {
|
||||
this->sendCommandAndWaitForResponse(Commands::EraseChip{});
|
||||
void WchLinkInterface::eraseProgramMemory() {
|
||||
this->sendCommandAndWaitForResponse(Commands::EraseProgramMemory{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
Targets::TargetMemorySize blockSize,
|
||||
std::span<const unsigned char> flashProgramOpcodes
|
||||
);
|
||||
void eraseChip();
|
||||
void eraseProgramMemory();
|
||||
|
||||
template <class CommandType>
|
||||
auto sendCommandAndWaitForResponse(const CommandType& command) {
|
||||
|
||||
@@ -57,6 +57,11 @@ namespace DebugToolDrivers::Wch
|
||||
this->targetConfig
|
||||
}
|
||||
)
|
||||
, programSegmentDescriptor(
|
||||
this->targetDescriptionFile.getSystemAddressSpaceDescriptor().getMemorySegmentDescriptor(
|
||||
"internal_program_memory"
|
||||
)
|
||||
)
|
||||
, flashProgramOpcodes(
|
||||
WchLinkDebugInterface::getFlashProgramOpcodes(
|
||||
this->targetDescriptionFile.getProperty("wch_link_interface", "programming_opcode_key").value
|
||||
@@ -352,11 +357,11 @@ namespace DebugToolDrivers::Wch
|
||||
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
|
||||
const TargetMemorySegmentDescriptor& memorySegmentDescriptor
|
||||
) {
|
||||
if (memorySegmentDescriptor.type == TargetMemorySegmentType::FLASH) {
|
||||
return this->eraseFlashMemory();
|
||||
if (memorySegmentDescriptor == this->programSegmentDescriptor) {
|
||||
return this->wchLinkInterface.eraseProgramMemory();
|
||||
}
|
||||
|
||||
throw Exception{"Erasing non-flash memory not supported in WchLinkDebugInterface"};
|
||||
// Ignore other (non-program memory) erase requests, for now.
|
||||
}
|
||||
|
||||
void WchLinkDebugInterface::enableProgrammingMode() {
|
||||
@@ -471,10 +476,6 @@ namespace DebugToolDrivers::Wch
|
||||
this->softwareBreakpointRegistry.remove(softwareBreakpoint);
|
||||
}
|
||||
|
||||
void WchLinkDebugInterface::eraseFlashMemory() {
|
||||
this->wchLinkInterface.eraseChip();
|
||||
}
|
||||
|
||||
std::span<const unsigned char> WchLinkDebugInterface::getFlashProgramOpcodes(const std::string& key) {
|
||||
if (key == "op1") {
|
||||
return FlashProgramOpcodes::FLASH_OP1;
|
||||
|
||||
@@ -89,6 +89,8 @@ namespace DebugToolDrivers::Wch
|
||||
Protocols::WchLink::WchLinkInterface& wchLinkInterface;
|
||||
DebugToolDrivers::Protocols::RiscVDebugSpec::DebugTranslator riscVTranslator;
|
||||
|
||||
const Targets::TargetMemorySegmentDescriptor& programSegmentDescriptor;
|
||||
|
||||
/**
|
||||
* The 'target activation' command returns a payload of 5 bytes.
|
||||
*
|
||||
@@ -107,7 +109,6 @@ namespace DebugToolDrivers::Wch
|
||||
void setSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
|
||||
void clearSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
|
||||
|
||||
void eraseFlashMemory();
|
||||
static std::span<const unsigned char> getFlashProgramOpcodes(const std::string& key);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user