Cleaned up AVR8 part description file loading

This commit is contained in:
Nav
2021-05-02 15:50:07 +01:00
parent 821947d610
commit 4a10ad4c35
5 changed files with 53 additions and 34 deletions

View File

@@ -118,12 +118,13 @@ namespace Bloom
for (auto targetIt = targets.begin(); targetIt != targets.end(); targetIt++) { for (auto targetIt = targets.begin(); targetIt != targets.end(); targetIt++) {
auto targetName = targetIt->toObject().find("targetName").value().toString() auto targetName = targetIt->toObject().find("targetName").value().toString()
.toLower().toStdString(); .toLower().toStdString();
auto targetSignatureHex = mapIt.key().toLower().toStdString();
if (!mapping.contains(targetName)) { if (!mapping.contains(targetName)) {
mapping.insert({ mapping.insert({
targetName, targetName,
[targetName]() { [targetName, targetSignatureHex]() {
return std::make_unique<Avr8>(targetName); return std::make_unique<Avr8>(targetName, TargetSignature(targetSignatureHex));
} }
}); });
} }

View File

@@ -40,24 +40,27 @@ void Avr8::preActivationConfigure(const TargetConfig& targetConfig) {
} }
void Avr8::postActivationConfigure() { void Avr8::postActivationConfigure() {
auto targetSignature = this->getId(); if (!this->partDescription.has_value()) {
auto partDescription = PartDescriptionFile( this->loadPartDescription();
targetSignature.toHex(),
(!this->name.empty()) ? std::optional(this->name) : std::nullopt
);
auto pdSignature = partDescription.getTargetSignature();
if (targetSignature != pdSignature) {
// This should never happen. If it does, someone has screwed up the part description mapping file.
throw Exception("Failed to activate target - target signature mismatch.\nThe target signature (\""
+ targetSignature.toHex() + "\") does not match the AVR8 part description signature (\""
+ pdSignature.toHex() + "\"). Please review your target configuration in bloom.json");
} }
this->partDescription = partDescription; /*
this->id = partDescription.getTargetSignature(); * The signature obtained from the device should match what is in the part description file
this->name = partDescription.getTargetName(); *
this->family = partDescription.getFamily(); * We don't use this->getId() here as that could return the ID that was extracted from the part description file
* (which it would, if the user specified the exact target name in their project config - see Avr8::getId() and
* TargetController::getSupportedTargets() for more).
*/
auto targetSignature = this->avr8Interface->getDeviceId();
auto pdSignature = this->partDescription->getTargetSignature();
if (targetSignature != pdSignature) {
throw Exception("Failed to validate connected target - target signature mismatch.\nThe target signature"
"(\"" + targetSignature.toHex() + "\") does not match the AVR8 part description signature (\""
+ pdSignature.toHex() + "\"). This will likely be due to an incorrect target name in the configuration file"
+ " (bloom.json)."
);
}
} }
void Avr8::postPromotionConfigure() { void Avr8::postPromotionConfigure() {
@@ -66,6 +69,18 @@ void Avr8::postPromotionConfigure() {
this->loadTargetVariants(); this->loadTargetVariants();
} }
void Avr8::loadPartDescription() {
auto targetSignature = this->getId();
auto partDescription = PartDescriptionFile(
targetSignature.toHex(),
(!this->name.empty()) ? std::optional(this->name) : std::nullopt
);
this->partDescription = partDescription;
this->name = partDescription.getTargetName();
this->family = partDescription.getFamily();
}
void Avr8::loadPadDescriptors() { void Avr8::loadPadDescriptors() {
auto& targetParameters = this->getTargetParameters(); auto& targetParameters = this->getTargetParameters();

View File

@@ -73,9 +73,13 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
*/ */
virtual void loadTargetVariants(); virtual void loadTargetVariants();
void loadPartDescription();
public: public:
explicit Avr8() = default; explicit Avr8() = default;
Avr8(const std::string& name): name(name) {}; Avr8(const std::string& name, const TargetSignature& signature): name(name) {
this->id = signature;
};
/* /*
* The functions below implement the Target interface for AVR8 targets. * The functions below implement the Target interface for AVR8 targets.

View File

@@ -14,40 +14,40 @@ PartDescriptionFile::PartDescriptionFile(const std::string& targetSignatureHex,
if (mapping.contains(qTargetSignatureHex)) { if (mapping.contains(qTargetSignatureHex)) {
// We have a match for the target signature. // We have a match for the target signature.
auto descriptionFilesJsonArray = mapping.find(qTargetSignatureHex).value().toArray(); auto descriptionFilesJsonArray = mapping.find(qTargetSignatureHex).value().toArray();
auto descriptionFiles = std::vector<QJsonValue>(); auto matchingDescriptionFiles = std::vector<QJsonValue>();
std::copy_if( std::copy_if(
descriptionFilesJsonArray.begin(), descriptionFilesJsonArray.begin(),
descriptionFilesJsonArray.end(), descriptionFilesJsonArray.end(),
std::back_inserter(descriptionFiles), std::back_inserter(matchingDescriptionFiles),
[&targetName] (const QJsonValue& value) { [&targetName] (const QJsonValue& value) {
auto pdTargetName = value.toObject().find("targetName")->toString().toLower().toStdString(); auto pdTargetName = value.toObject().find("targetName")->toString().toLower().toStdString();
return !targetName.has_value() || (targetName.has_value() && targetName.value() == pdTargetName); return !targetName.has_value() || (targetName.has_value() && targetName.value() == pdTargetName);
} }
); );
if (targetName.has_value() && descriptionFiles.empty()) { if (targetName.has_value() && matchingDescriptionFiles.empty()) {
throw Exception("Failed to resolve target description file for target \"" + targetName.value() throw Exception("Failed to resolve target description file for target \"" + targetName.value()
+ "\" - target signature \"" + targetSignatureHex + "\" does not belong to target with name \"" + + "\" - target signature \"" + targetSignatureHex + "\" does not belong to target with name \"" +
targetName.value() + "\". Please review your bloom.json configuration."); targetName.value() + "\". Please review your bloom.json configuration.");
} }
if (descriptionFiles.size() == 1) { if (matchingDescriptionFiles.size() == 1) {
// Attempt to load the XML part description file // Attempt to load the XML part description file
auto descriptionFilePath = QString::fromStdString(Application::getApplicationDirPath()) + "/" auto descriptionFilePath = QString::fromStdString(Application::getApplicationDirPath()) + "/"
+ descriptionFiles.front().toObject().find("targetDescriptionFilePath")->toString(); + matchingDescriptionFiles.front().toObject().find("targetDescriptionFilePath")->toString();
Logger::debug("Loading AVR8 part description file: " + descriptionFilePath.toStdString()); Logger::debug("Loading AVR8 part description file: " + descriptionFilePath.toStdString());
this->init(descriptionFilePath); this->init(descriptionFilePath);
} else if (descriptionFiles.size() > 1) { } else if (matchingDescriptionFiles.size() > 1) {
/* /*
* There are numerous part description files mapped to this target signature. There's really not * There are numerous part description files mapped to this target signature. There's really not
* much we can do at this point, so we'll just instruct the user to use a more specific target name. * much we can do at this point, so we'll just instruct the user to use a more specific target name.
*/ */
QStringList targetNames; QStringList targetNames;
std::transform( std::transform(
descriptionFiles.begin(), matchingDescriptionFiles.begin(),
descriptionFiles.end(), matchingDescriptionFiles.end(),
std::back_inserter(targetNames), std::back_inserter(targetNames),
[](const QJsonValue& descriptionFile) { [](const QJsonValue& descriptionFile) {
return QString("\"" + descriptionFile.toObject().find("targetName")->toString().toLower() + "\""); return QString("\"" + descriptionFile.toObject().find("targetName")->toString().toLower() + "\"");

View File

@@ -139,13 +139,12 @@ namespace Bloom::Targets
* begin the target configuration and activation process, we are able to learn a lot more about the target. * begin the target configuration and activation process, we are able to learn a lot more about the target.
* For AVR8 targets, we extract the target signature shortly after activation, and with that signature we find * For AVR8 targets, we extract the target signature shortly after activation, and with that signature we find
* the appropriate part description file, which has all of the information regarding the target that we could * the appropriate part description file, which has all of the information regarding the target that we could
* possibly need. * possibly need. So, by the time we have activated the target, we will know a lot more about it, and it is at
* So, by the time we have activated the target, we will know a lot more about it, and it is at this point, where * this point, where we may want to promote it to a more specific target class (from the generic Avr8 target
* we may want to promote it to a more specific target class (from the generic Avr8 target class). The generic * class). The generic AVR8 target class will attempt to promote the target to one that is more specific to
* AVR8 target class will attempt to promote the target to one that is more specific to the target's AVR8 family * the target's AVR8 family (ATmega, XMega, Tiny, etc). These classes can then also perform promotion of their
* (ATmega, XMega, Tiny, etc). These classes can then also perform promotion of their own, if required, where * own, if required, where they could promote to a class that's not only specific to an AVR8 family, but to a
* they could promote to a class that's not only specific to an AVR8 family, but to a particular target model (for * particular target model (for example, a target class that was written specifically for the ATmega328P target).
* example, a target class that was written specifically for the ATmega328P target).
* *
* This method should attempt to promote the current target class to one that is more specific to the connected * This method should attempt to promote the current target class to one that is more specific to the connected
* target, with the information it currently holds on the target. * target, with the information it currently holds on the target.