Restricted the size of all memory access commands to ensure that no more than two packets are sent to and from EDBG debug tools
This commit is contained in:
@@ -1659,7 +1659,18 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
return this->maximumMemoryAccessSizePerRequest;
|
return this->maximumMemoryAccessSizePerRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
/*
|
||||||
|
* EDBG AVR8 debug tools behave in a really weird way when receiving or responding with more than two packets
|
||||||
|
* for a single memory access command. The data they read/write in this case appears to be wrong.
|
||||||
|
*
|
||||||
|
* To address this, we make sure we only issue memory access commands that will result in no more than two
|
||||||
|
* packets being sent to and from the debug tool.
|
||||||
|
*
|
||||||
|
* The -30 is to accommodate for the bytes in the command that are not part of the main payload of the command.
|
||||||
|
*/
|
||||||
|
return static_cast<Targets::TargetMemorySize>(
|
||||||
|
(this->edbgInterface->getUsbHidInputReportSize() - 30) * 2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetMemoryBuffer EdbgAvr8Interface::readMemory(
|
TargetMemoryBuffer EdbgAvr8Interface::readMemory(
|
||||||
@@ -1759,56 +1770,6 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
type != Avr8MemoryType::FLASH_PAGE
|
|
||||||
&& type != Avr8MemoryType::SPM
|
|
||||||
&& type != Avr8MemoryType::APPL_FLASH
|
|
||||||
&& type != Avr8MemoryType::BOOT_FLASH
|
|
||||||
&& type != Avr8MemoryType::EEPROM_PAGE
|
|
||||||
) {
|
|
||||||
/*
|
|
||||||
* EDBG AVR8 debug tools behave in a really weird way when responding with more than two packets
|
|
||||||
* for a single read (non-flash) memory command. The data they return in this case appears to be of little
|
|
||||||
* use.
|
|
||||||
*
|
|
||||||
* To address this, we make sure we only issue read memory commands that will result in no more than two
|
|
||||||
* response packets. For calls that require more than this, we simply split them into numerous calls.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The subtraction of 20 bytes here is just to account for any other bytes included in the response
|
|
||||||
* that isn't actually the memory data (like the command ID, version bytes, etc). I could have sought the
|
|
||||||
* actual value but who has the time. It won't exceed 20 bytes. Bite me.
|
|
||||||
*/
|
|
||||||
const auto singlePacketSize = static_cast<std::uint32_t>(this->edbgInterface->getUsbHidInputReportSize() - 20);
|
|
||||||
const auto totalResponsePackets = std::ceil(static_cast<float>(bytes) / static_cast<float>(singlePacketSize));
|
|
||||||
const auto totalReadsRequired = static_cast<std::uint16_t>(std::ceil(static_cast<float>(totalResponsePackets) / 2));
|
|
||||||
|
|
||||||
if (totalResponsePackets > 2) {
|
|
||||||
/*
|
|
||||||
* This call to readMemory() will result in more than two response packets, so split it into multiple
|
|
||||||
* calls that will result in no more than two response packets per call.
|
|
||||||
*/
|
|
||||||
auto output = TargetMemoryBuffer();
|
|
||||||
|
|
||||||
for (auto i = 1; i <= totalReadsRequired; i++) {
|
|
||||||
const auto bytesToRead = static_cast<TargetMemorySize>(
|
|
||||||
(bytes - output.size()) > (singlePacketSize * 2)
|
|
||||||
? (singlePacketSize * 2) : bytes - output.size()
|
|
||||||
);
|
|
||||||
auto data = this->readMemory(
|
|
||||||
type,
|
|
||||||
static_cast<TargetMemoryAddress>(startAddress + output.size()),
|
|
||||||
bytesToRead,
|
|
||||||
excludedAddresses
|
|
||||||
);
|
|
||||||
std::move(data.begin(), data.end(), std::back_inserter(output));
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
||||||
ReadMemory(
|
ReadMemory(
|
||||||
type,
|
type,
|
||||||
|
|||||||
Reference in New Issue
Block a user