Created EdbgAvr8Session struct and moved EDBG target info to it
This commit is contained in:
@@ -24,6 +24,7 @@ target_sources(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Parameters/AVR8Generic/UpdiParameters.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/EdbgInterface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/EdbgTargetPowerManagementInterface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvr8Session.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvr8Interface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvrIspInterface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/EdbgDevice.cpp
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
using CommandFrames::Avr8Generic::EraseMemory;
|
||||
using CommandFrames::Avr8Generic::DisableDebugWire;
|
||||
|
||||
using Targets::TargetAddressSpaceDescriptor;
|
||||
using Targets::TargetMemorySegmentType;
|
||||
using Targets::TargetState;
|
||||
using Targets::TargetPhysicalInterface;
|
||||
using Targets::TargetMemoryType;
|
||||
@@ -90,38 +92,31 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
using Targets::TargetRegisterDescriptors;
|
||||
using Targets::TargetRegisterDescriptorId;
|
||||
using Targets::TargetRegisterDescriptorIds;
|
||||
using Targets::TargetRegisterType;
|
||||
using Targets::TargetRegisters;
|
||||
|
||||
EdbgAvr8Interface::EdbgAvr8Interface(
|
||||
EdbgInterface* edbgInterface,
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig,
|
||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters,
|
||||
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||
)
|
||||
: edbgInterface(edbgInterface)
|
||||
, targetConfig(targetConfig)
|
||||
, family(targetFamily)
|
||||
, configVariant(EdbgAvr8Interface::resolveConfigVariant(targetFamily, targetConfig.physicalInterface))
|
||||
, targetParameters(targetParameters)
|
||||
, targetRegisterDescriptorsById(targetRegisterDescriptorsById)
|
||||
, session(EdbgAvr8Session(targetDescriptionFile, targetConfig))
|
||||
{}
|
||||
|
||||
void EdbgAvr8Interface::init() {
|
||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
// Default PDI clock to 4MHz
|
||||
// TODO: Make this adjustable via a target config parameter
|
||||
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(4000));
|
||||
}
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::UPDI) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::UPDI) {
|
||||
// Default UPDI clock to 1.8MHz
|
||||
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(1800));
|
||||
this->setParameter(Avr8EdbgParameters::ENABLE_HIGH_VOLTAGE_UPDI, static_cast<std::uint8_t>(0));
|
||||
}
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::MEGAJTAG) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::MEGAJTAG) {
|
||||
// Default clock value for mega debugging is 200KHz
|
||||
// TODO: Make this adjustable via a target config parameter
|
||||
this->setParameter(Avr8EdbgParameters::MEGA_DEBUG_CLOCK, static_cast<std::uint16_t>(200));
|
||||
@@ -130,17 +125,17 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::CONFIG_VARIANT,
|
||||
static_cast<std::uint8_t>(this->configVariant)
|
||||
static_cast<std::uint8_t>(this->session.configVariant)
|
||||
);
|
||||
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::CONFIG_FUNCTION,
|
||||
static_cast<std::uint8_t>(this->configFunction)
|
||||
static_cast<std::uint8_t>(Avr8ConfigFunction::DEBUGGING)
|
||||
);
|
||||
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::PHYSICAL_INTERFACE,
|
||||
getPhysicalInterfaceToAvr8IdMapping().at(this->targetConfig.physicalInterface)
|
||||
getPhysicalInterfaceToAvr8IdMapping().at(this->session.targetConfig.physicalInterface)
|
||||
);
|
||||
|
||||
this->setTargetParameters();
|
||||
@@ -232,7 +227,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
|
||||
} catch (const Avr8CommandFailure& activationException) {
|
||||
if (
|
||||
this->targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
||||
this->session.targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
||||
&& (
|
||||
activationException.code == Avr8CommandFailureCode::DEBUGWIRE_PHYSICAL_ERROR
|
||||
|| activationException.code == Avr8CommandFailureCode::FAILED_TO_ENABLE_OCD
|
||||
@@ -257,8 +252,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
void EdbgAvr8Interface::deactivate() {
|
||||
if (this->targetAttached) {
|
||||
if (
|
||||
this->targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
||||
&& this->targetConfig.disableDebugWireOnDeactivate
|
||||
this->session.targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
||||
&& this->session.targetConfig.disableDebugWireOnDeactivate
|
||||
) {
|
||||
try {
|
||||
this->disableDebugWire();
|
||||
@@ -317,7 +312,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
|
||||
TargetSignature EdbgAvr8Interface::getDeviceId() {
|
||||
if (this->configVariant == Avr8ConfigVariant::UPDI) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::UPDI) {
|
||||
/*
|
||||
* When using the UPDI physical interface, the 'Get device ID' command behaves in an odd manner, where it
|
||||
* doesn't actually return the target signature, but instead a fixed four byte string reading:
|
||||
@@ -331,7 +326,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
*/
|
||||
const auto signatureMemory = this->readMemory(
|
||||
Avr8MemoryType::SRAM,
|
||||
this->targetParameters.signatureSegmentStartAddress.value(),
|
||||
this->session.signatureMemorySegment.startAddress,
|
||||
3
|
||||
);
|
||||
|
||||
@@ -339,7 +334,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
throw Exception("Failed to read AVR8 signature from target - unexpected response size");
|
||||
}
|
||||
|
||||
return TargetSignature(signatureMemory[0], signatureMemory[1], signatureMemory[2]);
|
||||
return {signatureMemory[0], signatureMemory[1], signatureMemory[2]};
|
||||
}
|
||||
|
||||
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
||||
@@ -350,7 +345,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
throw Avr8CommandFailure("AVR8 Get device ID command failed", responseFrame);
|
||||
}
|
||||
|
||||
return responseFrame.extractSignature(this->targetConfig.physicalInterface);
|
||||
return responseFrame.extractSignature(this->session.targetConfig.physicalInterface);
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setSoftwareBreakpoint(TargetMemoryAddress address) {
|
||||
@@ -518,7 +513,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
|
||||
const auto memoryType = (registerType != TargetRegisterType::GENERAL_PURPOSE_REGISTER)
|
||||
? Avr8MemoryType::SRAM
|
||||
: (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI
|
||||
: (this->session.configVariant == Avr8ConfigVariant::XMEGA || this->session.configVariant == Avr8ConfigVariant::UPDI
|
||||
? Avr8MemoryType::REGISTER_FILE
|
||||
: Avr8MemoryType::SRAM);
|
||||
|
||||
@@ -622,7 +617,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
auto memoryType = Avr8MemoryType::SRAM;
|
||||
if (
|
||||
registerDescriptor.type == TargetRegisterType::GENERAL_PURPOSE_REGISTER
|
||||
&& (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI)
|
||||
&& (this->session.configVariant == Avr8ConfigVariant::XMEGA || this->session.configVariant == Avr8ConfigVariant::UPDI)
|
||||
) {
|
||||
memoryType = Avr8MemoryType::REGISTER_FILE;
|
||||
}
|
||||
@@ -743,14 +738,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
case TargetMemoryType::FLASH: {
|
||||
if (
|
||||
this->configVariant == Avr8ConfigVariant::DEBUG_WIRE
|
||||
|| this->configVariant == Avr8ConfigVariant::UPDI
|
||||
|| this->configVariant == Avr8ConfigVariant::MEGAJTAG
|
||||
this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE
|
||||
|| this->session.configVariant == Avr8ConfigVariant::UPDI
|
||||
|| this->session.configVariant == Avr8ConfigVariant::MEGAJTAG
|
||||
) {
|
||||
avr8MemoryType = Avr8MemoryType::FLASH_PAGE;
|
||||
|
||||
} else if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
const auto bootSectionStartAddress = this->targetParameters.bootSectionStartAddress.value();
|
||||
} else if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
const auto bootSectionStartAddress = this->session.programBootSection.value().get().startAddress;
|
||||
if (startAddress >= bootSectionStartAddress) {
|
||||
avr8MemoryType = Avr8MemoryType::BOOT_FLASH;
|
||||
|
||||
@@ -765,21 +760,21 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
* When using the APPL_FLASH memory type, the address should be relative to the start of the
|
||||
* application section.
|
||||
*/
|
||||
startAddress -= this->targetParameters.appSectionStartAddress.value();
|
||||
startAddress -= this->session.programAppSection.value().get().startAddress;
|
||||
avr8MemoryType = Avr8MemoryType::APPL_FLASH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TargetMemoryType::EEPROM: {
|
||||
switch (this->configVariant) {
|
||||
switch (this->session.configVariant) {
|
||||
case Avr8ConfigVariant::UPDI:
|
||||
case Avr8ConfigVariant::XMEGA: {
|
||||
avr8MemoryType = Avr8MemoryType::EEPROM_ATOMIC;
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
// EEPROM addresses should be in relative form, for XMEGA (PDI) targets
|
||||
startAddress -= this->targetParameters.eepromStartAddress.value();
|
||||
startAddress -= this->session.eepromMemorySegment.startAddress;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -810,16 +805,16 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::eraseProgramMemory(std::optional<Avr8Bit::ProgramMemorySection> section) {
|
||||
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||
// The EDBG erase command does not work on debugWire targets - we'll just write to the memory instead
|
||||
return this->writeMemory(
|
||||
TargetMemoryType::FLASH,
|
||||
this->targetParameters.flashStartAddress.value(),
|
||||
TargetMemoryBuffer(this->targetParameters.flashSize.value(), 0xFF)
|
||||
this->session.programMemorySegment.startAddress,
|
||||
TargetMemoryBuffer(this->session.programMemorySegment.size, 0xFF)
|
||||
);
|
||||
}
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
// For PDI (XMEGA) targets, we can erase flash memory without erasing EEPROM
|
||||
|
||||
if (!section.has_value() || *section == Avr8Bit::ProgramMemorySection::BOOT) {
|
||||
@@ -908,7 +903,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
|
||||
this->programmingModeEnabled = false;
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::MEGAJTAG && this->reactivateJtagTargetPostProgrammingMode) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::MEGAJTAG && this->reactivateJtagTargetPostProgrammingMode) {
|
||||
this->deactivatePhysical();
|
||||
this->targetAttached = false;
|
||||
this->activate();
|
||||
@@ -916,23 +911,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setTargetParameters() {
|
||||
if (!this->targetParameters.stackPointerRegisterLowAddress.has_value()) {
|
||||
throw DeviceInitializationFailure("Failed to find stack pointer register start address");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.stackPointerRegisterSize.has_value()) {
|
||||
throw DeviceInitializationFailure("Failed to find stack pointer register size");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.statusRegisterStartAddress.has_value()) {
|
||||
throw DeviceInitializationFailure("Failed to find status register start address");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.statusRegisterSize.has_value()) {
|
||||
throw DeviceInitializationFailure("Failed to find status register size");
|
||||
}
|
||||
|
||||
switch (this->configVariant) {
|
||||
switch (this->session.configVariant) {
|
||||
case Avr8ConfigVariant::DEBUG_WIRE:
|
||||
case Avr8ConfigVariant::MEGAJTAG: {
|
||||
this->setDebugWireAndJtagParameters();
|
||||
@@ -952,76 +931,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
}
|
||||
|
||||
std::map<Family, std::map<TargetPhysicalInterface, Avr8ConfigVariant>>
|
||||
EdbgAvr8Interface::getConfigVariantsByFamilyAndPhysicalInterface() {
|
||||
return std::map<Family, std::map<TargetPhysicalInterface, Avr8ConfigVariant>>({
|
||||
{
|
||||
Family::MEGA,
|
||||
{
|
||||
{TargetPhysicalInterface::JTAG, Avr8ConfigVariant::MEGAJTAG},
|
||||
{TargetPhysicalInterface::DEBUG_WIRE, Avr8ConfigVariant::DEBUG_WIRE},
|
||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||
}
|
||||
},
|
||||
{
|
||||
Family::TINY,
|
||||
{
|
||||
{TargetPhysicalInterface::JTAG, Avr8ConfigVariant::MEGAJTAG},
|
||||
{TargetPhysicalInterface::DEBUG_WIRE, Avr8ConfigVariant::DEBUG_WIRE},
|
||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||
}
|
||||
},
|
||||
{
|
||||
Family::XMEGA,
|
||||
{
|
||||
{TargetPhysicalInterface::JTAG, Avr8ConfigVariant::XMEGA},
|
||||
{TargetPhysicalInterface::PDI, Avr8ConfigVariant::XMEGA},
|
||||
}
|
||||
},
|
||||
{
|
||||
Family::DA,
|
||||
{
|
||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||
}
|
||||
},
|
||||
{
|
||||
Family::DB,
|
||||
{
|
||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||
}
|
||||
},
|
||||
{
|
||||
Family::DD,
|
||||
{
|
||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||
}
|
||||
},
|
||||
{
|
||||
Family::EA,
|
||||
{
|
||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Avr8ConfigVariant EdbgAvr8Interface::resolveConfigVariant(
|
||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
||||
TargetPhysicalInterface physicalInterface
|
||||
) {
|
||||
const auto configVariantsByFamily = EdbgAvr8Interface::getConfigVariantsByFamilyAndPhysicalInterface();
|
||||
const auto configVariantsByPhysicalInterfaceIt = configVariantsByFamily.find(targetFamily);
|
||||
|
||||
assert(configVariantsByPhysicalInterfaceIt != configVariantsByFamily.end());
|
||||
|
||||
const auto& configVariantsByPhysicalInterface = configVariantsByPhysicalInterfaceIt->second;
|
||||
const auto configVariantIt = configVariantsByPhysicalInterface.find(physicalInterface);
|
||||
|
||||
assert(configVariantIt != configVariantsByPhysicalInterface.end());
|
||||
|
||||
return configVariantIt->second;
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value) {
|
||||
using Services::StringService;
|
||||
|
||||
@@ -1052,7 +961,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
|
||||
const auto parameters = Parameters::Avr8Generic::DebugWireJtagParameters(this->targetDescriptionFile);
|
||||
const auto parameters = Parameters::Avr8Generic::DebugWireJtagParameters(this->session.targetDescriptionFile);
|
||||
|
||||
Logger::debug("Setting FLASH_PAGE_SIZE AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE, parameters.flashPageSize);
|
||||
@@ -1103,7 +1012,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setPdiParameters() {
|
||||
const auto parameters = Parameters::Avr8Generic::PdiParameters(this->targetDescriptionFile);
|
||||
const auto parameters = Parameters::Avr8Generic::PdiParameters(this->session.targetDescriptionFile);
|
||||
|
||||
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR, parameters.appSectionPdiOffset);
|
||||
@@ -1152,7 +1061,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setUpdiParameters() {
|
||||
const auto parameters = Parameters::Avr8Generic::UpdiParameters(this->targetDescriptionFile);
|
||||
const auto parameters = Parameters::Avr8Generic::UpdiParameters(this->session.targetDescriptionFile);
|
||||
|
||||
/*
|
||||
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be
|
||||
@@ -1202,56 +1111,36 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
static_cast<std::uint8_t>(parameters.flashPageSize >> 8)
|
||||
);
|
||||
|
||||
if (this->targetParameters.eepromPageSize.has_value()) {
|
||||
Logger::debug("Setting UPDI_EEPROM_PAGE_SIZE AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_PAGE_SIZE, parameters.eepromPageSize);
|
||||
}
|
||||
|
||||
if (this->targetParameters.nvmModuleBaseAddress.has_value()) {
|
||||
Logger::debug("Setting UPDI_NVMCTRL_ADDR AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_NVMCTRL_ADDR, parameters.nvmModuleBaseAddress);
|
||||
}
|
||||
|
||||
if (this->targetParameters.ocdModuleAddress.has_value()) {
|
||||
Logger::debug("Setting UPDI_OCD_ADDR AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_OCD_ADDR, parameters.ocdModuleAddress);
|
||||
}
|
||||
|
||||
if (this->targetParameters.flashSize.has_value()) {
|
||||
Logger::debug("Setting UPDI_FLASH_SIZE AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FLASH_SIZE, parameters.flashSize);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromSize.has_value()) {
|
||||
Logger::debug("Setting UPDI_EEPROM_SIZE AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_SIZE, parameters.eepromSize);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromStartAddress.has_value()) {
|
||||
Logger::debug("Setting UPDI_EEPROM_BASE_ADDR AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_BASE_ADDR, parameters.eepromStartAddress);
|
||||
}
|
||||
|
||||
if (this->targetParameters.signatureSegmentStartAddress.has_value()) {
|
||||
Logger::debug("Setting UPDI_SIG_BASE_ADDR AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_SIG_BASE_ADDR, parameters.signatureSegmentStartAddress);
|
||||
}
|
||||
|
||||
if (this->targetParameters.fuseSegmentStartAddress.has_value()) {
|
||||
Logger::debug("Setting UPDI_FUSE_BASE_ADDR AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_BASE_ADDR, parameters.fuseSegmentStartAddress);
|
||||
}
|
||||
|
||||
if (this->targetParameters.fuseSegmentSize.has_value()) {
|
||||
Logger::debug("Setting UPDI_FUSE_SIZE AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_SIZE, parameters.fuseSegmentSize);
|
||||
}
|
||||
|
||||
if (this->targetParameters.lockbitsSegmentStartAddress.has_value()) {
|
||||
Logger::debug("Setting UPDI_LOCK_BASE_ADDR AVR8 device parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_LOCK_BASE_ADDR, parameters.lockbitSegmentStartAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
|
||||
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
||||
@@ -1295,7 +1184,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
*/
|
||||
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
||||
Attach(
|
||||
this->configVariant != Avr8ConfigVariant::MEGAJTAG
|
||||
this->session.configVariant != Avr8ConfigVariant::MEGAJTAG
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1384,12 +1273,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
* align them - we've tried only word aligning them - the debug tool reports a "Too many or too few
|
||||
* bytes" error.
|
||||
*/
|
||||
alignTo = this->targetParameters.flashPageSize.value();
|
||||
alignTo = static_cast<std::uint16_t>(this->session.programMemorySegment.pageSize.value());
|
||||
break;
|
||||
}
|
||||
case Avr8MemoryType::EEPROM_ATOMIC:
|
||||
case Avr8MemoryType::EEPROM_PAGE: {
|
||||
alignTo = this->targetParameters.eepromPageSize.value();
|
||||
alignTo = static_cast<std::uint16_t>(this->session.eepromMemorySegment.pageSize.value());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1418,12 +1307,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
case Avr8MemoryType::APPL_FLASH:
|
||||
case Avr8MemoryType::BOOT_FLASH: {
|
||||
// See comment in EdbgAvr8Interface::alignMemoryAddress()
|
||||
alignTo = this->targetParameters.flashPageSize.value();
|
||||
alignTo = static_cast<std::uint16_t>(this->session.programMemorySegment.pageSize.value());
|
||||
break;
|
||||
}
|
||||
case Avr8MemoryType::EEPROM_ATOMIC:
|
||||
case Avr8MemoryType::EEPROM_PAGE: {
|
||||
alignTo = this->targetParameters.eepromPageSize.value();
|
||||
alignTo = static_cast<std::uint16_t>(this->session.eepromMemorySegment.pageSize.value());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1445,10 +1334,10 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
memoryType == Avr8MemoryType::FLASH_PAGE
|
||||
|| memoryType == Avr8MemoryType::APPL_FLASH
|
||||
|| memoryType == Avr8MemoryType::BOOT_FLASH
|
||||
|| (memoryType == Avr8MemoryType::SPM && this->configVariant == Avr8ConfigVariant::MEGAJTAG)
|
||||
|| (memoryType == Avr8MemoryType::SPM && this->session.configVariant == Avr8ConfigVariant::MEGAJTAG)
|
||||
) {
|
||||
// These flash memory types require single page access.
|
||||
return this->targetParameters.flashPageSize.value();
|
||||
return this->session.programMemorySegment.pageSize.value();
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -1456,7 +1345,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
|| memoryType == Avr8MemoryType::EEPROM_PAGE
|
||||
) {
|
||||
// These EEPROM memory types requires single page access.
|
||||
return this->targetParameters.eepromPageSize.value();
|
||||
return this->session.eepromMemorySegment.pageSize.value();
|
||||
}
|
||||
|
||||
if (this->maximumMemoryAccessSizePerRequest.has_value()) {
|
||||
@@ -1485,7 +1374,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
const std::set<TargetMemoryAddress>& excludedAddresses
|
||||
) {
|
||||
if (type == Avr8MemoryType::FUSES) {
|
||||
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||
throw Exception("Cannot access AVR fuses via the debugWire interface");
|
||||
}
|
||||
}
|
||||
@@ -1618,7 +1507,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
const TargetMemoryBuffer& buffer
|
||||
) {
|
||||
if (type == Avr8MemoryType::FUSES) {
|
||||
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||
if (this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||
throw Exception("Cannot access AVR fuses via the debugWire interface");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
#include "src/DebugToolDrivers/Microchip/Protocols/EDBG/EdbgInterface.hpp"
|
||||
|
||||
#include "Avr8Generic.hpp"
|
||||
#include "EdbgAvr8Session.hpp"
|
||||
|
||||
#include "src/Targets/TargetPhysicalInterface.hpp"
|
||||
#include "src/Targets/TargetMemory.hpp"
|
||||
#include "src/Targets/TargetRegisterDescriptor.hpp"
|
||||
#include "src/Targets/TargetRegister.hpp"
|
||||
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||
#include "src/Targets/Microchip/AVR/AVR8/Family.hpp"
|
||||
#include "src/Targets/Microchip/AVR/AVR8/TargetParameters.hpp"
|
||||
|
||||
@@ -34,10 +36,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
public:
|
||||
explicit EdbgAvr8Interface(
|
||||
EdbgInterface* edbgInterface,
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig,
|
||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters,
|
||||
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -294,42 +294,9 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
EdbgInterface* edbgInterface = nullptr;
|
||||
|
||||
/**
|
||||
* Project's AVR8 target configuration.
|
||||
* The active EDBG AVR8 session.
|
||||
*/
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig;
|
||||
|
||||
/**
|
||||
* The target family is taken into account when configuring the AVR8 Generic protocol on the EDBG device.
|
||||
*
|
||||
* We use this to determine which config variant to select.
|
||||
* See EdbgAvr8Interface::resolveConfigVariant() for more.
|
||||
*/
|
||||
Targets::Microchip::Avr::Avr8Bit::Family family;
|
||||
|
||||
/**
|
||||
* The AVR8 Generic protocol provides two functions: Debugging and programming. The desired function must be
|
||||
* configured via the setting of the "AVR8_CONFIG_FUNCTION" parameter.
|
||||
*/
|
||||
Avr8ConfigFunction configFunction = Avr8ConfigFunction::DEBUGGING;
|
||||
|
||||
/**
|
||||
* Configuring of the AVR8 Generic protocol depends on some characteristics of the target.
|
||||
* The "AVR8_CONFIG_VARIANT" parameter allows us to determine which target parameters are required by the
|
||||
* debug tool.
|
||||
*/
|
||||
Avr8ConfigVariant configVariant = Avr8ConfigVariant::NONE;
|
||||
|
||||
/**
|
||||
* EDBG-based debug tools require target specific parameters such as memory locations, page sizes and
|
||||
* register addresses. It is the AVR8 target's responsibility to obtain the required information and pass it
|
||||
* to the Avr8Interface. See Avr8::getTargetParameters() and Avr8::postPromotionConfigure().
|
||||
*
|
||||
* For the EdbgAvr8Interface, we send the required parameters to the debug tool immediately upon receiving
|
||||
* them. See EdbgAvr8Interface::setTargetParameters().
|
||||
*/
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters;
|
||||
|
||||
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById;
|
||||
EdbgAvr8Session session;
|
||||
|
||||
/**
|
||||
* See the comment for EdbgAvr8Interface::setAvoidMaskedMemoryRead().
|
||||
@@ -379,25 +346,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
*/
|
||||
void setTargetParameters();
|
||||
|
||||
/**
|
||||
* This mapping allows us to determine which config variant to select, based on the target family and the
|
||||
* selected physical interface.
|
||||
*/
|
||||
static std::map<
|
||||
Targets::Microchip::Avr::Avr8Bit::Family,
|
||||
std::map<Targets::TargetPhysicalInterface, Avr8ConfigVariant>
|
||||
> getConfigVariantsByFamilyAndPhysicalInterface();
|
||||
|
||||
/**
|
||||
* Determines the config variant given a target family and physical interface.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static Avr8ConfigVariant resolveConfigVariant(
|
||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
||||
Targets::TargetPhysicalInterface physicalInterface
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets an AVR8 parameter on the debug tool. See the Avr8EdbgParameters class and protocol documentation
|
||||
* for more on available parameters.
|
||||
@@ -461,17 +409,15 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
* register addresses. These parameters can be sent to the tool before and during a session.
|
||||
*
|
||||
* What parameters we need to send depend on the physical interface (and config variant) selected by the user.
|
||||
* For target parameters, the address (ID) of the parameter also varies across config variants. This is why
|
||||
* we sometimes have separate parameters for sending the same data, where they differ only in parameter IDs
|
||||
* (and sometimes size constraints). For example, the Avr8EdbgParameters::FLASH_PAGE_BYTES parameter is used
|
||||
* to specify the size of a single page in flash memory. The parameter is assigned an address (ID) of 0x00. But
|
||||
* the Avr8EdbgParameters::DEVICE_XMEGA_FLASH_PAGE_BYTES parameter is used to send the same data (flash page
|
||||
* size), but only for sessions with the PDI physical interface. The address is 0x26.
|
||||
* For target parameters, the address (ID) of the parameter also varies across config variants.
|
||||
*
|
||||
* - The setDebugWireAndJtagParameters() function sends the required target parameters for debugWire and JTAG
|
||||
* sessions. Both sessions are covered in a single function because they require the same parameters.
|
||||
* - The setPdiParameters() function sends the required target parameters for PDI sessions.
|
||||
* - The setUpdiParameters() function sends the required target parameters for UPDI sessions.
|
||||
*
|
||||
* We extract the required parameters from the TDF. See the constructors for the `DebugWireJtagParameters`,
|
||||
* `PdiParameters` and `UpdiParameters` structs for more.
|
||||
*/
|
||||
void setDebugWireAndJtagParameters();
|
||||
void setPdiParameters();
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "EdbgAvr8Session.hpp"
|
||||
|
||||
#include "src/Services/StringService.hpp"
|
||||
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
|
||||
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
{
|
||||
EdbgAvr8Session::EdbgAvr8Session(
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||
)
|
||||
: targetDescriptionFile(targetDescriptionFile)
|
||||
, targetConfig(targetConfig)
|
||||
, programAddressSpace(this->targetDescriptionFile.getProgramAddressSpace())
|
||||
, ramAddressSpace(this->targetDescriptionFile.getRamAddressSpace())
|
||||
, eepromAddressSpace(this->targetDescriptionFile.getEepromAddressSpace())
|
||||
, ioAddressSpace(this->targetDescriptionFile.getIoAddressSpace())
|
||||
, signatureAddressSpace(this->targetDescriptionFile.getSignatureAddressSpace())
|
||||
, programMemorySegment(this->targetDescriptionFile.getProgramMemorySegment())
|
||||
, ramMemorySegment(this->targetDescriptionFile.getRamMemorySegment())
|
||||
, eepromMemorySegment(this->targetDescriptionFile.getEepromMemorySegment())
|
||||
, ioMemorySegment(this->targetDescriptionFile.getIoMemorySegment())
|
||||
, signatureMemorySegment(this->targetDescriptionFile.getSignatureMemorySegment())
|
||||
, programAppSection(this->programMemorySegment.tryGetSection("app_section"))
|
||||
, programBootSection(this->programMemorySegment.tryGetSection("boot_section"))
|
||||
{
|
||||
using Services::StringService;
|
||||
|
||||
const auto ocdDataRegisterProperty = this->targetDescriptionFile.tryGetProperty("ocd", "ocd_datareg");
|
||||
if (ocdDataRegisterProperty.has_value()) {
|
||||
this->ocdDataRegister = StringService::toUint8(ocdDataRegisterProperty->get().value);
|
||||
}
|
||||
|
||||
const auto resolvedConfigVariant = EdbgAvr8Session::tryResolveConfigVariant(
|
||||
this->targetDescriptionFile.getAvrFamily(),
|
||||
this->targetConfig.physicalInterface
|
||||
);
|
||||
|
||||
if (!resolvedConfigVariant.has_value()) {
|
||||
throw Exceptions::Exception(
|
||||
"Failed to resolve EDBG config variant from the selected physical interface and the AVR target family"
|
||||
" - please review the selected physical interface"
|
||||
);
|
||||
}
|
||||
|
||||
this->configVariant = *resolvedConfigVariant;
|
||||
}
|
||||
|
||||
std::optional<Avr8ConfigVariant> EdbgAvr8Session::tryResolveConfigVariant(
|
||||
Targets::Microchip::Avr::Avr8Bit::Family avrFamily,
|
||||
Targets::TargetPhysicalInterface physicalInterface
|
||||
) {
|
||||
using Targets::Microchip::Avr::Avr8Bit::Family;
|
||||
using Targets::TargetPhysicalInterface;
|
||||
|
||||
if (avrFamily == Family::MEGA || avrFamily == Family::TINY) {
|
||||
switch (physicalInterface) {
|
||||
case TargetPhysicalInterface::JTAG: {
|
||||
return Avr8ConfigVariant::MEGAJTAG;
|
||||
}
|
||||
case TargetPhysicalInterface::DEBUG_WIRE: {
|
||||
return Avr8ConfigVariant::DEBUG_WIRE;
|
||||
}
|
||||
case TargetPhysicalInterface::UPDI: {
|
||||
return Avr8ConfigVariant::UPDI;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (avrFamily == Family::XMEGA) {
|
||||
switch (physicalInterface) {
|
||||
case TargetPhysicalInterface::JTAG:
|
||||
case TargetPhysicalInterface::PDI: {
|
||||
return Avr8ConfigVariant::XMEGA;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (avrFamily == Family::DA || avrFamily == Family::DB || avrFamily == Family::DD || avrFamily == Family::EA) {
|
||||
switch (physicalInterface) {
|
||||
case TargetPhysicalInterface::UPDI: {
|
||||
return Avr8ConfigVariant::UPDI;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
|
||||
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||
#include "src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.hpp"
|
||||
#include "src/Targets/TargetMemorySegmentDescriptor.hpp"
|
||||
#include "src/Targets/TargetRegisterDescriptor.hpp"
|
||||
|
||||
#include "Avr8Generic.hpp"
|
||||
|
||||
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||
{
|
||||
/**
|
||||
* This struct holds all required target info for an EDBG AVR8 session.
|
||||
*/
|
||||
struct EdbgAvr8Session
|
||||
{
|
||||
/**
|
||||
* AVR8 TDF, from which we extract all target info to configure the EDBG debug tool.
|
||||
*/
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile;
|
||||
|
||||
/**
|
||||
* Project's AVR8 target configuration.
|
||||
*/
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig;
|
||||
|
||||
/**
|
||||
* The EDBG config variant parameter.
|
||||
*
|
||||
* See the "AVR8_CONFIG_VARIANT" parameter in section 7.1.3.1 of Microchip's "EDBG-based Tools Protocols"
|
||||
* document for more.
|
||||
*/
|
||||
Avr8ConfigVariant configVariant = Avr8ConfigVariant::NONE;
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& programAddressSpace;
|
||||
const Targets::TargetDescription::AddressSpace& ramAddressSpace;
|
||||
const Targets::TargetDescription::AddressSpace& eepromAddressSpace;
|
||||
const Targets::TargetDescription::AddressSpace& ioAddressSpace;
|
||||
const Targets::TargetDescription::AddressSpace& signatureAddressSpace;
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& programMemorySegment;
|
||||
const Targets::TargetDescription::MemorySegment& ramMemorySegment;
|
||||
const Targets::TargetDescription::MemorySegment& eepromMemorySegment;
|
||||
const Targets::TargetDescription::MemorySegment& ioMemorySegment;
|
||||
const Targets::TargetDescription::MemorySegment& signatureMemorySegment;
|
||||
|
||||
const std::optional<
|
||||
std::reference_wrapper<const Targets::TargetDescription::MemorySegmentSection>
|
||||
> programAppSection;
|
||||
|
||||
const std::optional<
|
||||
std::reference_wrapper<const Targets::TargetDescription::MemorySegmentSection>
|
||||
> programBootSection;
|
||||
|
||||
std::optional<std::uint8_t> ocdDataRegister;
|
||||
|
||||
EdbgAvr8Session(
|
||||
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||
);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Attempts to determine the EDBG config variant for a given AVR family and physical interface.
|
||||
*
|
||||
* See the "AVR8_CONFIG_VARIANT" parameter in section 7.1.3.1 of Microchip's "EDBG-based Tools Protocols"
|
||||
* document for more.
|
||||
*
|
||||
* @return
|
||||
* The resolved config variant, or std::nullopt if the given AVR family and physical interface do not map to
|
||||
* any particular EDBG config variant.
|
||||
*/
|
||||
static std::optional<Avr8ConfigVariant> tryResolveConfigVariant(
|
||||
Targets::Microchip::Avr::Avr8Bit::Family avrFamily,
|
||||
Targets::TargetPhysicalInterface physicalInterface
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -50,27 +50,60 @@ namespace Targets::Microchip::Avr::Avr8Bit
|
||||
return familyIt->second;
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getProgramAddressSpace() const {
|
||||
return this->getAddressSpace("prog");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getRamAddressSpace() const {
|
||||
return this->getAddressSpace("data");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getEepromAddressSpace() const {
|
||||
const auto addressSpace = this->tryGetAddressSpace("eeprom");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get()
|
||||
: this->getAddressSpace("data");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getIoAddressSpace() const {
|
||||
return this->getAddressSpace("data");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getSignatureAddressSpace() const {
|
||||
const auto addressSpace = this->tryGetAddressSpace("signatures");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get()
|
||||
: this->getAddressSpace("data");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getFuseAddressSpace() const {
|
||||
const auto addressSpace = this->tryGetAddressSpace("fuses");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get()
|
||||
: this->getAddressSpace("data");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getLockbitAddressSpace() const {
|
||||
const auto addressSpace = this->tryGetAddressSpace("lockbits");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get()
|
||||
: this->getAddressSpace("data");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getProgramMemorySegment() const {
|
||||
return this->getAddressSpace("prog").getMemorySegment("internal_program_memory");
|
||||
return this->getProgramAddressSpace().getMemorySegment("internal_program_memory");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getRamMemorySegment() const {
|
||||
return this->getAddressSpace("data").getMemorySegment("internal_ram");
|
||||
return this->getRamAddressSpace().getMemorySegment("internal_ram");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getEepromMemorySegment() const {
|
||||
/*
|
||||
* The EEPROM segment can sometimes be found within a dedicated address space, or within the data address
|
||||
* space.
|
||||
*/
|
||||
const auto addressSpace = this->tryGetAddressSpace("eeprom");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get().getMemorySegment("internal_eeprom")
|
||||
: this->getAddressSpace("data").getMemorySegment("internal_eeprom");
|
||||
return this->getEepromAddressSpace().getMemorySegment("internal_eeprom");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getIoMemorySegment() const {
|
||||
const auto addressSpace = this->getAddressSpace("data");
|
||||
const auto addressSpace = this->getIoAddressSpace();
|
||||
const auto segment = addressSpace.tryGetMemorySegment("io");
|
||||
return segment.has_value()
|
||||
? segment->get()
|
||||
@@ -78,36 +111,15 @@ namespace Targets::Microchip::Avr::Avr8Bit
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getSignatureMemorySegment() const {
|
||||
/*
|
||||
* The signatures segment can sometimes be found within a dedicated address space, or within the data address
|
||||
* space.
|
||||
*/
|
||||
const auto addressSpace = this->tryGetAddressSpace("signatures");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get().getMemorySegment("signatures")
|
||||
: this->getAddressSpace("data").getMemorySegment("signatures");
|
||||
return this->getSignatureAddressSpace().getMemorySegment("signatures");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getFuseMemorySegment() const {
|
||||
/*
|
||||
* The fuses segment can sometimes be found within a dedicated address space, or within the data address
|
||||
* space.
|
||||
*/
|
||||
const auto addressSpace = this->tryGetAddressSpace("fuses");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get().getMemorySegment("fuses")
|
||||
: this->getAddressSpace("data").getMemorySegment("fuses");
|
||||
return this->getFuseAddressSpace().getMemorySegment("fuses");
|
||||
}
|
||||
|
||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getLockbitMemorySegment() const {
|
||||
/*
|
||||
* The lockbits segment can sometimes be found within a dedicated address space, or within the data address
|
||||
* space.
|
||||
*/
|
||||
const auto addressSpace = this->tryGetAddressSpace("lockbits");
|
||||
return addressSpace.has_value()
|
||||
? addressSpace->get().getMemorySegment("lockbits")
|
||||
: this->getAddressSpace("data").getMemorySegment("lockbits");
|
||||
return this->getLockbitAddressSpace().getMemorySegment("lockbits");
|
||||
}
|
||||
|
||||
TargetParameters TargetDescriptionFile::getTargetParameters() const {
|
||||
|
||||
@@ -54,6 +54,14 @@ namespace Targets::Microchip::Avr::Avr8Bit
|
||||
*/
|
||||
[[nodiscard]] Family getAvrFamily() const;
|
||||
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getProgramAddressSpace() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getRamAddressSpace() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getEepromAddressSpace() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getIoAddressSpace() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getSignatureAddressSpace() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getFuseAddressSpace() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::AddressSpace& getLockbitAddressSpace() const;
|
||||
|
||||
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getProgramMemorySegment() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getRamMemorySegment() const;
|
||||
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getEepromMemorySegment() const;
|
||||
|
||||
Reference in New Issue
Block a user