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");
|
Logger::info("Handling FlashErase packet");
|
||||||
|
|
||||||
try {
|
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();
|
targetControllerService.enableProgrammingMode();
|
||||||
|
|
||||||
Logger::warning("Erasing program memory, in preparation for programming");
|
// We don't erase a specific address range - we just erase the entire segment
|
||||||
|
|
||||||
// We don't erase a specific address range - we just erase the entire program memory.
|
|
||||||
targetControllerService.eraseMemory(
|
targetControllerService.eraseMemory(
|
||||||
gdbTargetDescriptor.systemAddressSpaceDescriptor,
|
gdbTargetDescriptor.systemAddressSpaceDescriptor,
|
||||||
gdbTargetDescriptor.programMemorySegmentDescriptor
|
segmentDescriptor
|
||||||
);
|
);
|
||||||
|
|
||||||
debugSession.connection.writePacket(OkResponsePacket{});
|
debugSession.connection.writePacket(OkResponsePacket{});
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
namespace DebugToolDrivers::Wch::Protocols::WchLink::Commands
|
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:
|
public:
|
||||||
EraseChip()
|
EraseProgramMemory()
|
||||||
: Command(0x02)
|
: Command(0x02)
|
||||||
{
|
{
|
||||||
this->payload = {
|
this->payload = {
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "Commands/StartRamCodeWrite.hpp"
|
#include "Commands/StartRamCodeWrite.hpp"
|
||||||
#include "Commands/EndRamCodeWrite.hpp"
|
#include "Commands/EndRamCodeWrite.hpp"
|
||||||
#include "Commands/WriteFlash.hpp"
|
#include "Commands/WriteFlash.hpp"
|
||||||
#include "Commands/EraseChip.hpp"
|
#include "Commands/EraseProgramMemory.hpp"
|
||||||
|
|
||||||
#include "src/Helpers/BiMap.hpp"
|
#include "src/Helpers/BiMap.hpp"
|
||||||
#include "src/Services/StringService.hpp"
|
#include "src/Services/StringService.hpp"
|
||||||
@@ -243,7 +243,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
|||||||
this->sendCommandAndWaitForResponse(Commands::EndProgrammingSession{});
|
this->sendCommandAndWaitForResponse(Commands::EndProgrammingSession{});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WchLinkInterface::eraseChip() {
|
void WchLinkInterface::eraseProgramMemory() {
|
||||||
this->sendCommandAndWaitForResponse(Commands::EraseChip{});
|
this->sendCommandAndWaitForResponse(Commands::EraseProgramMemory{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
|||||||
Targets::TargetMemorySize blockSize,
|
Targets::TargetMemorySize blockSize,
|
||||||
std::span<const unsigned char> flashProgramOpcodes
|
std::span<const unsigned char> flashProgramOpcodes
|
||||||
);
|
);
|
||||||
void eraseChip();
|
void eraseProgramMemory();
|
||||||
|
|
||||||
template <class CommandType>
|
template <class CommandType>
|
||||||
auto sendCommandAndWaitForResponse(const CommandType& command) {
|
auto sendCommandAndWaitForResponse(const CommandType& command) {
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ namespace DebugToolDrivers::Wch
|
|||||||
this->targetConfig
|
this->targetConfig
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
, programSegmentDescriptor(
|
||||||
|
this->targetDescriptionFile.getSystemAddressSpaceDescriptor().getMemorySegmentDescriptor(
|
||||||
|
"internal_program_memory"
|
||||||
|
)
|
||||||
|
)
|
||||||
, flashProgramOpcodes(
|
, flashProgramOpcodes(
|
||||||
WchLinkDebugInterface::getFlashProgramOpcodes(
|
WchLinkDebugInterface::getFlashProgramOpcodes(
|
||||||
this->targetDescriptionFile.getProperty("wch_link_interface", "programming_opcode_key").value
|
this->targetDescriptionFile.getProperty("wch_link_interface", "programming_opcode_key").value
|
||||||
@@ -352,11 +357,11 @@ namespace DebugToolDrivers::Wch
|
|||||||
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
|
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
|
||||||
const TargetMemorySegmentDescriptor& memorySegmentDescriptor
|
const TargetMemorySegmentDescriptor& memorySegmentDescriptor
|
||||||
) {
|
) {
|
||||||
if (memorySegmentDescriptor.type == TargetMemorySegmentType::FLASH) {
|
if (memorySegmentDescriptor == this->programSegmentDescriptor) {
|
||||||
return this->eraseFlashMemory();
|
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() {
|
void WchLinkDebugInterface::enableProgrammingMode() {
|
||||||
@@ -471,10 +476,6 @@ namespace DebugToolDrivers::Wch
|
|||||||
this->softwareBreakpointRegistry.remove(softwareBreakpoint);
|
this->softwareBreakpointRegistry.remove(softwareBreakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WchLinkDebugInterface::eraseFlashMemory() {
|
|
||||||
this->wchLinkInterface.eraseChip();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<const unsigned char> WchLinkDebugInterface::getFlashProgramOpcodes(const std::string& key) {
|
std::span<const unsigned char> WchLinkDebugInterface::getFlashProgramOpcodes(const std::string& key) {
|
||||||
if (key == "op1") {
|
if (key == "op1") {
|
||||||
return FlashProgramOpcodes::FLASH_OP1;
|
return FlashProgramOpcodes::FLASH_OP1;
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ namespace DebugToolDrivers::Wch
|
|||||||
Protocols::WchLink::WchLinkInterface& wchLinkInterface;
|
Protocols::WchLink::WchLinkInterface& wchLinkInterface;
|
||||||
DebugToolDrivers::Protocols::RiscVDebugSpec::DebugTranslator riscVTranslator;
|
DebugToolDrivers::Protocols::RiscVDebugSpec::DebugTranslator riscVTranslator;
|
||||||
|
|
||||||
|
const Targets::TargetMemorySegmentDescriptor& programSegmentDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 'target activation' command returns a payload of 5 bytes.
|
* The 'target activation' command returns a payload of 5 bytes.
|
||||||
*
|
*
|
||||||
@@ -107,7 +109,6 @@ namespace DebugToolDrivers::Wch
|
|||||||
void setSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
|
void setSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
|
||||||
void clearSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
|
void clearSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
|
||||||
|
|
||||||
void eraseFlashMemory();
|
|
||||||
static std::span<const unsigned char> getFlashProgramOpcodes(const std::string& key);
|
static std::span<const unsigned char> getFlashProgramOpcodes(const std::string& key);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user