More TDF refactoring

Moved address space, module, property group, variant, pinout and peripheral module extraction to TDF initialisation.
Also some other bits of tidying.
This commit is contained in:
Nav
2021-06-06 20:06:43 +01:00
parent 9b1f250625
commit a65cc0b5c0
5 changed files with 241 additions and 235 deletions

View File

@@ -231,7 +231,7 @@ void Avr8::loadTargetVariants() {
auto targetVariant = TargetVariant(); auto targetVariant = TargetVariant();
targetVariant.id = static_cast<int>(this->targetVariantsById.size()); targetVariant.id = static_cast<int>(this->targetVariantsById.size());
targetVariant.name = tdVariant.orderCode; targetVariant.name = tdVariant.name;
targetVariant.packageName = tdVariant.package; targetVariant.packageName = tdVariant.package;
if (tdVariant.package.find("QFP") == 0 || tdVariant.package.find("TQFP") == 0) { if (tdVariant.package.find("QFP") == 0 || tdVariant.package.find("TQFP") == 0) {

View File

@@ -100,7 +100,7 @@ QJsonObject TargetDescriptionFile::getTargetDescriptionMapping() {
} }
TargetSignature TargetDescriptionFile::getTargetSignature() const { TargetSignature TargetDescriptionFile::getTargetSignature() const {
auto propertyGroups = this->getPropertyGroupsMappedByName(); auto& propertyGroups = this->propertyGroupsMappedByName;
auto signaturePropertyGroupIt = propertyGroups.find("signatures"); auto signaturePropertyGroupIt = propertyGroups.find("signatures");
if (signaturePropertyGroupIt == propertyGroups.end()) { if (signaturePropertyGroupIt == propertyGroups.end()) {
@@ -154,7 +154,7 @@ Family TargetDescriptionFile::getFamily() const {
} }
std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() const { std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() const {
auto addressMapping = this->getAddressSpacesMappedById(); auto& addressMapping = this->addressSpacesMappedById;
auto programAddressSpaceIt = addressMapping.find("prog"); auto programAddressSpaceIt = addressMapping.find("prog");
// Flash memory attributes are typically found in memory segments within the program address space. // Flash memory attributes are typically found in memory segments within the program address space.
@@ -183,7 +183,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() cons
} }
std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const { std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const {
auto addressMapping = this->getAddressSpacesMappedById(); auto& addressMapping = this->addressSpacesMappedById;
// Internal RAM &register attributes are usually found in the data address space // Internal RAM &register attributes are usually found in the data address space
auto dataAddressSpaceIt = addressMapping.find("data"); auto dataAddressSpaceIt = addressMapping.find("data");
@@ -206,7 +206,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const
} }
std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() const { std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() const {
auto addressMapping = this->getAddressSpacesMappedById(); auto& addressMapping = this->addressSpacesMappedById;
// Internal RAM &register attributes are usually found in the data address space // Internal RAM &register attributes are usually found in the data address space
auto dataAddressSpaceIt = addressMapping.find("data"); auto dataAddressSpaceIt = addressMapping.find("data");
@@ -229,7 +229,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() c
} }
std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() const { std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() const {
auto addressMapping = this->getAddressSpacesMappedById(); auto& addressMapping = this->addressSpacesMappedById;
if (addressMapping.contains("eeprom")) { if (addressMapping.contains("eeprom")) {
auto& eepromAddressSpace = addressMapping.at("eeprom"); auto& eepromAddressSpace = addressMapping.at("eeprom");
@@ -254,7 +254,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() con
} }
std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySegment() const { std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySegment() const {
auto addressMapping = this->getAddressSpacesMappedById(); auto& addressMapping = this->addressSpacesMappedById;
auto programAddressSpaceIt = addressMapping.find("prog"); auto programAddressSpaceIt = addressMapping.find("prog");
if (programAddressSpaceIt != addressMapping.end()) { if (programAddressSpaceIt != addressMapping.end()) {
@@ -277,7 +277,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySeg
} }
std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const { std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const {
auto& modulesByName = this->getModulesMappedByName(); auto& modulesByName = this->modulesMappedByName;
if (modulesByName.find("cpu") != modulesByName.end()) { if (modulesByName.find("cpu") != modulesByName.end()) {
auto cpuModule = modulesByName.find("cpu")->second; auto cpuModule = modulesByName.find("cpu")->second;
@@ -292,7 +292,7 @@ std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const
} }
std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() const { std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() const {
auto& modulesByName = this->getModulesMappedByName(); auto& modulesByName = this->modulesMappedByName;
if (modulesByName.contains("boot_load")) { if (modulesByName.contains("boot_load")) {
auto& bootLoadModule = modulesByName.at("boot_load"); auto& bootLoadModule = modulesByName.at("boot_load");
@@ -307,7 +307,7 @@ std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() c
} }
std::optional<RegisterGroup> TargetDescriptionFile::getEepromRegisterGroup() const { std::optional<RegisterGroup> TargetDescriptionFile::getEepromRegisterGroup() const {
auto& modulesByName = this->getModulesMappedByName(); auto& modulesByName = this->modulesMappedByName;
if (modulesByName.find("eeprom") != modulesByName.end()) { if (modulesByName.find("eeprom") != modulesByName.end()) {
auto eepromModule = modulesByName.find("eeprom")->second; auto eepromModule = modulesByName.find("eeprom")->second;

View File

@@ -31,6 +31,13 @@ void TargetDescriptionFile::init(const QDomDocument& xml) {
} }
this->deviceElement = device; this->deviceElement = device;
this->loadAddressSpaces();
this->loadPropertyGroups();
this->loadModules();
this->loadPeripheralModules();
this->loadVariants();
this->loadPinouts();
} }
std::string TargetDescriptionFile::getTargetName() const { std::string TargetDescriptionFile::getTargetName() const {
@@ -208,13 +215,29 @@ Register TargetDescriptionFile::generateRegisterFromXml(const QDomElement& xmlEl
return reg; return reg;
} }
const std::map<std::string, PropertyGroup>& TargetDescriptionFile::getPropertyGroupsMappedByName() const { void TargetDescriptionFile::loadAddressSpaces() {
if (!this->cachedPropertyGroupMapping.has_value()) {
auto addressSpaceNodes = this->deviceElement.elementsByTagName("address-spaces").item(0).toElement()
.elementsByTagName("address-space");
for (int addressSpaceIndex = 0; addressSpaceIndex < addressSpaceNodes.count(); addressSpaceIndex++) {
try {
auto addressSpace = TargetDescriptionFile::generateAddressSpaceFromXml(
addressSpaceNodes.item(addressSpaceIndex).toElement()
);
this->addressSpacesMappedById.insert(std::pair(addressSpace.id, addressSpace));
} catch (const Exception& exception) {
Logger::debug("Failed to extract address space from target description element - " + exception.getMessage());
}
}
}
void TargetDescriptionFile::loadPropertyGroups() {
if (!this->deviceElement.isElement()) { if (!this->deviceElement.isElement()) {
throw TargetDescriptionParsingFailureException("Device element not found."); throw TargetDescriptionParsingFailureException("Device element not found.");
} }
std::map<std::string, PropertyGroup> output;
auto propertyGroupNodes = this->deviceElement.elementsByTagName("property-groups").item(0).toElement() auto propertyGroupNodes = this->deviceElement.elementsByTagName("property-groups").item(0).toElement()
.elementsByTagName("property-group"); .elementsByTagName("property-group");
@@ -236,18 +259,11 @@ const std::map<std::string, PropertyGroup>& TargetDescriptionFile::getPropertyGr
propertyGroup.propertiesMappedByName.insert(std::pair(propertyName.toLower().toStdString(), property)); propertyGroup.propertiesMappedByName.insert(std::pair(propertyName.toLower().toStdString(), property));
} }
output.insert(std::pair(propertyGroup.name, propertyGroup)); this->propertyGroupsMappedByName.insert(std::pair(propertyGroup.name, propertyGroup));
}
} }
this->cachedPropertyGroupMapping.emplace(output); void TargetDescriptionFile::loadModules() {
}
return this->cachedPropertyGroupMapping.value();
}
const std::map<std::string, Module>& TargetDescriptionFile::getModulesMappedByName() const {
if (!this->cachedModuleByNameMapping.has_value()) {
std::map<std::string, Module> output;
auto moduleNodes = this->xml.elementsByTagName("modules").item(0).toElement() auto moduleNodes = this->xml.elementsByTagName("modules").item(0).toElement()
.elementsByTagName("module"); .elementsByTagName("module");
@@ -266,18 +282,11 @@ const std::map<std::string, Module>& TargetDescriptionFile::getModulesMappedByNa
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup)); module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
} }
output.insert(std::pair(module.name, module)); this->modulesMappedByName.insert(std::pair(module.name, module));
}
} }
this->cachedModuleByNameMapping.emplace(output); void TargetDescriptionFile::loadPeripheralModules() {
}
return this->cachedModuleByNameMapping.value();
}
const std::map<std::string, Module>& TargetDescriptionFile::getPeripheralModulesMappedByName() const {
if (!this->cachedPeripheralModuleByNameMapping.has_value()) {
std::map<std::string, Module> output;
auto moduleNodes = this->deviceElement.elementsByTagName("peripherals").item(0).toElement() auto moduleNodes = this->deviceElement.elementsByTagName("peripherals").item(0).toElement()
.elementsByTagName("module"); .elementsByTagName("module");
@@ -338,39 +347,11 @@ const std::map<std::string, Module>& TargetDescriptionFile::getPeripheralModules
module.instancesMappedByName.insert(std::pair(instance.name, instance)); module.instancesMappedByName.insert(std::pair(instance.name, instance));
} }
output.insert(std::pair(module.name, module)); this->peripheralModulesMappedByName.insert(std::pair(module.name, module));
}
this->cachedPeripheralModuleByNameMapping.emplace(output);
}
return this->cachedPeripheralModuleByNameMapping.value();
}
std::map<std::string, AddressSpace> TargetDescriptionFile::getAddressSpacesMappedById() const {
std::map<std::string, AddressSpace> output;
auto addressSpaceNodes = this->deviceElement.elementsByTagName("address-spaces").item(0).toElement()
.elementsByTagName("address-space");
for (int addressSpaceIndex = 0; addressSpaceIndex < addressSpaceNodes.count(); addressSpaceIndex++) {
try {
auto addressSpace = TargetDescriptionFile::generateAddressSpaceFromXml(
addressSpaceNodes.item(addressSpaceIndex).toElement()
);
output.insert(std::pair(addressSpace.id, addressSpace));
} catch (const Exception& exception) {
Logger::debug("Failed to extract address space from target description element - " + exception.getMessage());
} }
} }
return output; void TargetDescriptionFile::loadVariants() {
}
std::vector<Variant> TargetDescriptionFile::getVariants() const {
std::vector<Variant> output;
auto variantNodes = this->xml.elementsByTagName("variants").item(0).toElement() auto variantNodes = this->xml.elementsByTagName("variants").item(0).toElement()
.elementsByTagName("variant"); .elementsByTagName("variant");
@@ -391,7 +372,7 @@ std::vector<Variant> TargetDescriptionFile::getVariants() const {
} }
auto variant = Variant(); auto variant = Variant();
variant.orderCode = variantXml.attribute("ordercode").toStdString(); variant.name = variantXml.attribute("ordercode").toStdString();
variant.pinoutName = variantXml.attribute("pinout").toLower().toStdString(); variant.pinoutName = variantXml.attribute("pinout").toLower().toStdString();
variant.package = variantXml.attribute("package").toUpper().toStdString(); variant.package = variantXml.attribute("package").toUpper().toStdString();
@@ -399,20 +380,15 @@ std::vector<Variant> TargetDescriptionFile::getVariants() const {
variant.disabled = (variantXml.attribute("disabled") == "1"); variant.disabled = (variantXml.attribute("disabled") == "1");
} }
output.push_back(variant); this->variants.push_back(variant);
} catch (const Exception& exception) { } catch (const Exception& exception) {
Logger::debug("Failed to extract variant from target description element - " + exception.getMessage()); Logger::debug("Failed to extract variant from target description element - " + exception.getMessage());
} }
} }
return output;
} }
const std::map<std::string, Pinout>& TargetDescriptionFile::getPinoutsMappedByName() const { void TargetDescriptionFile::loadPinouts() {
if (!this->cachedPinoutByNameMapping.has_value()) {
this->cachedPinoutByNameMapping = std::map<std::string, Pinout>();
auto pinoutNodes = this->xml.elementsByTagName("pinouts").item(0).toElement() auto pinoutNodes = this->xml.elementsByTagName("pinouts").item(0).toElement()
.elementsByTagName("pinout"); .elementsByTagName("pinout");
@@ -453,13 +429,10 @@ const std::map<std::string, Pinout>& TargetDescriptionFile::getPinoutsMappedByNa
pinout.pins.push_back(pin); pinout.pins.push_back(pin);
} }
this->cachedPinoutByNameMapping->insert(std::pair(pinout.name, pinout)); this->pinoutsMappedByName.insert(std::pair(pinout.name, pinout));
} catch (const Exception& exception) { } catch (const Exception& exception) {
Logger::debug("Failed to extract pinout from target description element - " + exception.getMessage()); Logger::debug("Failed to extract pinout from target description element - " + exception.getMessage());
} }
} }
} }
return this->cachedPinoutByNameMapping.value();
}

View File

@@ -36,15 +36,18 @@ namespace Bloom::Targets::TargetDescription
QDomDocument xml; QDomDocument xml;
QDomElement deviceElement; QDomElement deviceElement;
std::map<std::string, AddressSpace> addressSpacesMappedById;
std::map<std::string, PropertyGroup> propertyGroupsMappedByName;
std::map<std::string, Module> modulesMappedByName;
std::map<std::string, Module> peripheralModulesMappedByName;
std::vector<Variant> variants;
std::map<std::string, Pinout> pinoutsMappedByName;
void init(const QDomDocument& xml); void init(const QDomDocument& xml);
void init(const QString& xmlFilePath); void init(const QString& xmlFilePath);
private: private:
mutable std::optional<std::map<std::string, PropertyGroup>> cachedPropertyGroupMapping;
mutable std::optional<std::map<std::string, Module>> cachedModuleByNameMapping;
mutable std::optional<std::map<std::string, Module>> cachedPeripheralModuleByNameMapping;
mutable std::optional<std::map<std::string, Pinout>> cachedPinoutByNameMapping;
/** /**
* Constructs an AddressSpace object from an XML element. * Constructs an AddressSpace object from an XML element.
* *
@@ -77,6 +80,36 @@ namespace Bloom::Targets::TargetDescription
*/ */
static Register generateRegisterFromXml(const QDomElement& xmlElement); static Register generateRegisterFromXml(const QDomElement& xmlElement);
/**
* Extracts all address spaces and loads them into this->addressSpacesMappedById.
*/
void loadAddressSpaces();
/**
* Extracts all property groups and loads them into this->propertyGroupsMappedByName.
*/
void loadPropertyGroups();
/**
* Extracts all modules and loads them into this->modulesMappedByName.
*/
void loadModules();
/**
* Extracts all peripheral modules and loads them into this->peripheralModulesMappedByName.
*/
void loadPeripheralModules();
/**
* Extracts all variants and loads them into this->variants.
*/
void loadVariants();
/**
* Extracts all pinouts and loads them into this->pinoutsMappedByName.
*/
void loadPinouts();
public: public:
TargetDescriptionFile() = default; TargetDescriptionFile() = default;
@@ -104,51 +137,51 @@ namespace Bloom::Targets::TargetDescription
* *
* @return * @return
*/ */
std::string getTargetName() const; [[nodiscard]] std::string getTargetName() const;
/** /**
* Extracts all address spaces for the target. * Returns a mapping of all property groups, with the property group name being the key.
*
* Will return a mapping of the extracted address spaces, mapped by id.
* *
* @return * @return
*/ */
std::map<std::string, AddressSpace> getAddressSpacesMappedById() const; [[nodiscard]] const std::map<std::string, PropertyGroup>& getPropertyGroupsMappedByName() const {
return this->propertyGroupsMappedByName;
}
/** /**
* Extracts all property groups and returns a mapping of them, with the property group name being the key. * Returns a mapping of all modules, with the module name being the key.
* *
* @return * @return
*/ */
const std::map<std::string, PropertyGroup>& getPropertyGroupsMappedByName() const; [[nodiscard]] const std::map<std::string, Module>& getModulesMappedByName() const {
return this->modulesMappedByName;
}
/** /**
* Extracts all modules and returns a mapping of them, with the module name being the key. * Returns a mapping of all peripheral modules, with the peripheral module name being the key.
* *
* @return * @return
*/ */
const std::map<std::string, Module>& getModulesMappedByName() const; [[nodiscard]] const std::map<std::string, Module>& getPeripheralModulesMappedByName() const {
return this->peripheralModulesMappedByName;
}
/** /**
* Extracts all peripheral modules and returns a mapping of this, with the peripheral module name being * Returns all variants found in the TDF.
* the key.
* *
* @return * @return
*/ */
const std::map<std::string, Module>& getPeripheralModulesMappedByName() const; [[nodiscard]] const std::vector<Variant>& getVariants() const {
return this->variants;
}
/** /**
* Extracts all variants. * Returns a mapping of pinouts, with the pinout name being the key.
* *
* @return * @return
*/ */
std::vector<Variant> getVariants() const; [[nodiscard]] const std::map<std::string, Pinout>& getPinoutsMappedByName() const {
return this->pinoutsMappedByName;
/** }
* Extracts all pinouts and returns a mapping of them, with the pinout name being the key.
*
* @return
*/
const std::map<std::string, Pinout>& getPinoutsMappedByName() const;
}; };
} }

View File

@@ -6,7 +6,7 @@ namespace Bloom::Targets::TargetDescription
{ {
struct Variant struct Variant
{ {
std::string orderCode; std::string name;
std::string pinoutName; std::string pinoutName;
std::string package; std::string package;
bool disabled = false; bool disabled = false;