diff --git a/.gitignore b/.gitignore index 84bccfdc..2a966b00 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ build/cmake-build-debug build/cmake-build-release build/resources build/bin/bloom -build/bin/bloom.json +build/bin/bloom.yaml *.deb *.rpm *.pkg.tar.zst diff --git a/resources/help.txt b/resources/help.txt index 43e77e6e..b2850f77 100644 --- a/resources/help.txt +++ b/resources/help.txt @@ -10,6 +10,6 @@ Commands: --help, -h Displays this help text. --version, -v Displays Bloom's version number. --version-machine Outputs Bloom's version number in JSON format. - init Creates a new Bloom project configuration file (bloom.json), in the working directory. + init Creates a new Bloom project configuration file (bloom.yaml), in the working directory. For more information on getting started with Bloom, please visit https://bloom.oscillate.io/docs/getting-started. diff --git a/src/Application.cpp b/src/Application.cpp index 6a8bf33a..c2f78e81 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -234,22 +234,22 @@ namespace Bloom } void Application::loadProjectConfiguration() { - auto jsonConfigFile = QFile(QString::fromStdString(Paths::projectConfigPath())); + auto configFile = QFile(QString::fromStdString(Paths::projectConfigPath())); - if (!jsonConfigFile.exists()) { - throw InvalidConfig("Bloom configuration file (bloom.json) not found. Working directory: " + if (!configFile.exists()) { + throw InvalidConfig("Bloom configuration file (bloom.yaml) not found. Working directory: " + Paths::projectDirPath()); } - if (!jsonConfigFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - throw InvalidConfig("Failed to load Bloom configuration file (bloom.json) Working directory: " + if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + throw InvalidConfig("Failed to open Bloom configuration file (bloom.yaml) Working directory: " + Paths::projectDirPath()); } - const auto jsonObject = QJsonDocument::fromJson(jsonConfigFile.readAll()).object(); - jsonConfigFile.close(); + const auto configNode = YAML::Load(configFile.readAll().toStdString()); + configFile.close(); - this->projectConfig = ProjectConfig(jsonObject); + this->projectConfig = ProjectConfig(configNode); // Validate the selected environment if (!this->projectConfig->environments.contains(this->selectedEnvironmentName)) { @@ -337,7 +337,7 @@ namespace Bloom auto configFile = QFile(QString::fromStdString(Paths::projectConfigPath())); if (configFile.exists()) { - throw Exception("Bloom configuration file (bloom.json) already exists in working directory."); + throw Exception("Bloom configuration file (bloom.yaml) already exists in working directory."); } /* @@ -358,7 +358,7 @@ namespace Bloom } if (!configFile.open(QIODevice::ReadWrite)) { - throw Exception("Failed to create Bloom configuration file (bloom.json)"); + throw Exception("Failed to create Bloom configuration file (bloom.yaml)"); } configFile.write(templateConfigFile.readAll()); @@ -366,7 +366,7 @@ namespace Bloom configFile.close(); templateConfigFile.close(); - Logger::info("Bloom configuration file (bloom.json) created in working directory."); + Logger::info("Bloom configuration file (bloom.yaml) created in working directory."); return EXIT_SUCCESS; } diff --git a/src/DebugServer/DebugServerComponent.hpp b/src/DebugServer/DebugServerComponent.hpp index 9cb4bf5a..a3068476 100644 --- a/src/DebugServer/DebugServerComponent.hpp +++ b/src/DebugServer/DebugServerComponent.hpp @@ -43,7 +43,7 @@ namespace Bloom::DebugServer EventListenerPointer eventListener = std::make_shared("DebugServerEventListener"); /** - * Project configuration for the debug server (extracted from the user project's bloom.json). + * Project configuration for the debug server (extracted from the user project's bloom.yaml). */ DebugServerConfig debugServerConfig; @@ -62,7 +62,7 @@ namespace Bloom::DebugServer /** * Returns a mapping of server configuration names to lambdas/std::functions. * - * The server configuration name is what the user will use in their project configuration (bloom.json), when + * The server configuration name is what the user will use in their project configuration (bloom.yaml), when * selecting a debug server. It *must* be lower-case. * * The lambda should return an instance of the server implementation. diff --git a/src/DebugServer/Gdb/GdbDebugServerConfig.cpp b/src/DebugServer/Gdb/GdbDebugServerConfig.cpp index 7869becd..bd07ca56 100644 --- a/src/DebugServer/Gdb/GdbDebugServerConfig.cpp +++ b/src/DebugServer/Gdb/GdbDebugServerConfig.cpp @@ -1,18 +1,27 @@ #include "GdbDebugServerConfig.hpp" +#include "src/Helpers/YamlUtilities.hpp" +#include "src/Logger/Logger.hpp" + namespace Bloom::DebugServer::Gdb { GdbDebugServerConfig::GdbDebugServerConfig(const DebugServerConfig& debugServerConfig) : DebugServerConfig(debugServerConfig) { - if (debugServerConfig.jsonObject.contains("ipAddress")) { - this->listeningAddress = debugServerConfig.jsonObject.value("ipAddress").toString().toStdString(); + if (debugServerConfig.debugServerNode["ipAddress"]) { + if (!YamlUtilities::isType(debugServerConfig.debugServerNode["ipAddress"])) { + Logger::error( + "Invalid GDB debug server config parameter ('ipAddress') provided - must be a string. The " + "parameter will be ignored." + ); + } + + this->listeningAddress = debugServerConfig.debugServerNode["ipAddress"].as(); } - if (debugServerConfig.jsonObject.contains("port")) { - const auto portValue = debugServerConfig.jsonObject.value("port"); + if (debugServerConfig.debugServerNode["port"]) { this->listeningPortNumber = static_cast( - portValue.isString() ? portValue.toString().toInt(nullptr, 10) : portValue.toInt() + debugServerConfig.debugServerNode["port"].as() ); } } diff --git a/src/DebugServer/README.md b/src/DebugServer/README.md index 56bd2cdd..06596c2b 100644 --- a/src/DebugServer/README.md +++ b/src/DebugServer/README.md @@ -11,7 +11,7 @@ connected AVR target, by implementing the Each server must implement the interface defined in the [`ServerInterface` class](./ServerInterface.hpp). At startup, the DebugServer will select the appropriate server implementation, based on the user's project -configuration (bloom.json - see [`DebugServerConfig`](../ProjectConfig.hpp)). Each server implementation is mapped to a +configuration (bloom.yaml - see [`DebugServerConfig`](../ProjectConfig.hpp)). Each server implementation is mapped to a config name, which is to be used in the project configuration file. For the mapping, see `DebugServerComponent::getAvailableServersByName()`. After initialising the server (via `ServerInterface::init()`), control of the DebugServer thread will then be handed over to the server implementation (via `ServerInterface::run()`). diff --git a/src/Helpers/Paths.hpp b/src/Helpers/Paths.hpp index 7765cb9e..ea796a26 100644 --- a/src/Helpers/Paths.hpp +++ b/src/Helpers/Paths.hpp @@ -34,12 +34,12 @@ namespace Bloom } /** - * Returns the path to the current project's configuration file (bloom.json). + * Returns the path to the current project's configuration file (bloom.yaml). * * @return */ static std::string projectConfigPath() { - return Paths::projectDirPath() + "/bloom.json"; + return Paths::projectDirPath() + "/bloom.yaml"; } /** diff --git a/src/ProjectConfig.cpp b/src/ProjectConfig.cpp index e71bcdb6..f5adb2ad 100644 --- a/src/ProjectConfig.cpp +++ b/src/ProjectConfig.cpp @@ -1,111 +1,168 @@ #include "ProjectConfig.hpp" +#include "src/Helpers/String.hpp" #include "src/Logger/Logger.hpp" #include "src/Exceptions/InvalidConfig.hpp" namespace Bloom { - ProjectConfig::ProjectConfig(const QJsonObject& jsonObject) { - if (!jsonObject.contains("environments")) { + ProjectConfig::ProjectConfig(const YAML::Node& configNode) { + if (!configNode["environments"]) { throw Exceptions::InvalidConfig( - "No environments found - please review the bloom.json configuration file and ensure that " + "No environments found - please review the bloom.yaml configuration file and ensure that " "no syntax errors are present." ); } - // Extract all environment objects from JSON config. - auto environments = jsonObject.find("environments").value().toObject(); + if (!configNode["environments"].IsMap()) { + throw Exceptions::InvalidConfig( + "Invalid environments configuration provided - 'environments' must be of mapping type." + ); + } + + const auto& environments = configNode["environments"]; + for (auto environmentIt = environments.begin(); environmentIt != environments.end(); environmentIt++) { - auto environmentName = environmentIt.key().toStdString(); + auto environmentName = std::optional(std::nullopt); try { + environmentName = environmentIt->first.as(); + + if (!String::isAscii(environmentName.value())) { + throw Exceptions::InvalidConfig( + "Environment name ('" + environmentName.value() + "') is not in ASCII form." + ); + } + this->environments.insert( std::pair( - environmentName, - EnvironmentConfig(environmentName, environmentIt.value().toObject()) + environmentName.value(), + EnvironmentConfig(environmentName.value(), environmentIt->second) ) ); } catch (Exceptions::InvalidConfig& exception) { - Logger::error("Invalid environment config for environment '" + environmentName + "': " - + exception.getMessage() + " Environment will be ignored."); + Logger::error( + "Invalid environment config for environment '" + environmentName.value() + "': " + + exception.getMessage() + " Environment will be ignored." + ); + + } catch (YAML::BadConversion& exception) { + Logger::error( + "Invalid environment name provided. Environment names must be ASCII strings. Environment will be " + "ignored" + ); } } - if (jsonObject.contains("debugServer")) { - this->debugServerConfig = DebugServerConfig(jsonObject.find("debugServer")->toObject()); + if (configNode["debugServer"]) { + this->debugServerConfig = DebugServerConfig(configNode["debugServer"]); } - if (jsonObject.contains("insight")) { - this->insightConfig = InsightConfig(jsonObject.find("insight")->toObject()); + if (configNode["insight"]) { + this->insightConfig = InsightConfig(configNode["insight"]); } - if (jsonObject.contains("debugLoggingEnabled")) { - this->debugLoggingEnabled = jsonObject.find("debugLoggingEnabled").value().toBool(); + if (configNode["debugLoggingEnabled"]) { + this->debugLoggingEnabled = configNode["debugLoggingEnabled"].as(this->debugLoggingEnabled); } } - InsightConfig::InsightConfig(const QJsonObject& jsonObject) { - if (jsonObject.contains("enabled")) { - this->insightEnabled = jsonObject.find("enabled").value().toBool(); + InsightConfig::InsightConfig(const YAML::Node& insightNode) { + if (insightNode["enabled"]) { + this->insightEnabled = insightNode["enabled"].as(this->insightEnabled); } } - EnvironmentConfig::EnvironmentConfig(std::string name, QJsonObject jsonObject) { - if (!jsonObject.contains("debugTool")) { - throw Exceptions::InvalidConfig("No debug tool configuration provided."); + EnvironmentConfig::EnvironmentConfig(std::string name, const YAML::Node& environmentNode) + : name(std::move(name)) + { + if (!environmentNode["debugTool"]) { + throw Exceptions::InvalidConfig("Missing debug tool configuration."); } - if (!jsonObject.contains("target")) { - throw Exceptions::InvalidConfig("No target configuration provided."); + if (!environmentNode["debugTool"].IsMap()) { + throw Exceptions::InvalidConfig( + "Invalid debug tool configuration provided - 'debugTool' must be of mapping type." + ); } - this->name = std::move(name); - this->shutdownPostDebugSession = jsonObject.value( - "shutdownPostDebugSession" - ).toBool(this->shutdownPostDebugSession); - this->debugToolConfig = DebugToolConfig(jsonObject.find("debugTool")->toObject()); - this->targetConfig = TargetConfig(jsonObject.find("target")->toObject()); - - if (jsonObject.contains("debugServer")) { - this->debugServerConfig = DebugServerConfig(jsonObject.find("debugServer")->toObject()); + if (!environmentNode["target"]) { + throw Exceptions::InvalidConfig("Missing target configuration."); } - if (jsonObject.contains("insight")) { - this->insightConfig = InsightConfig(jsonObject.find("insight")->toObject()); + if (!environmentNode["target"].IsMap()) { + throw Exceptions::InvalidConfig( + "Invalid target configuration provided - 'target' must be of mapping type." + ); + } + + this->debugToolConfig = DebugToolConfig(environmentNode["debugTool"]); + this->targetConfig = TargetConfig(environmentNode["target"]); + + if (environmentNode["debugServer"]) { + if (!environmentNode["debugServer"].IsMap()) { + throw Exceptions::InvalidConfig( + "Invalid debug server configuration provided - 'debugServer' must be of mapping type." + ); + } + + this->debugServerConfig = DebugServerConfig(environmentNode["debugServer"]); + } + + if (environmentNode["insight"]) { + if (!environmentNode["insight"].IsMap()) { + throw Exceptions::InvalidConfig( + "Invalid insight configuration provided - 'insight' must be of mapping type." + ); + } + + this->insightConfig = InsightConfig(environmentNode["insight"]); + } + + if (environmentNode["shutdownPostDebugSession"]) { + this->shutdownPostDebugSession = environmentNode["shutdownPostDebugSession"].as( + this->shutdownPostDebugSession + ); } } - TargetConfig::TargetConfig(const QJsonObject& jsonObject) { - if (!jsonObject.contains("name")) { + TargetConfig::TargetConfig(const YAML::Node& targetNode) { + if (!targetNode["name"]) { throw Exceptions::InvalidConfig("No target name found."); } - this->name = jsonObject.find("name")->toString().toLower().toStdString(); + this->name = String::asciiToLower(targetNode["name"].as()); - if (jsonObject.contains("variantName")) { - this->variantName = jsonObject.find("variantName").value().toString().toLower().toStdString(); + if (targetNode["variantName"]) { + this->variantName = String::asciiToLower(targetNode["variantName"].as()); } - this->jsonObject = jsonObject; + this->targetNode = targetNode; } - DebugToolConfig::DebugToolConfig(const QJsonObject& jsonObject) { - if (!jsonObject.contains("name")) { + DebugToolConfig::DebugToolConfig(const YAML::Node& debugToolNode) { + if (!debugToolNode["name"]) { throw Exceptions::InvalidConfig("No debug tool name found."); } - this->name = jsonObject.find("name")->toString().toLower().toStdString(); + this->name = String::asciiToLower(debugToolNode["name"].as()); - if (jsonObject.contains("releasePostDebugSession")) { - this->releasePostDebugSession = jsonObject.find("releasePostDebugSession").value().toBool(); + if (debugToolNode["releasePostDebugSession"]) { + this->releasePostDebugSession = debugToolNode["releasePostDebugSession"].as( + this->releasePostDebugSession + ); } - this->jsonObject = jsonObject; + this->debugToolNode = debugToolNode; } - DebugServerConfig::DebugServerConfig(const QJsonObject& jsonObject) { - this->name = jsonObject.find("name")->toString().toLower().toStdString(); - this->jsonObject = jsonObject; + DebugServerConfig::DebugServerConfig(const YAML::Node& debugServerNode) { + if (!debugServerNode["name"]) { + throw Exceptions::InvalidConfig("No debug server name found."); + } + + this->name = String::asciiToLower(debugServerNode["name"].as()); + this->debugServerNode = debugServerNode; } } diff --git a/src/ProjectConfig.hpp b/src/ProjectConfig.hpp index 1b762408..12bcc248 100644 --- a/src/ProjectConfig.hpp +++ b/src/ProjectConfig.hpp @@ -3,41 +3,44 @@ #include #include #include -#include +#include namespace Bloom { /* - * Currently, all user configuration is stored in a JSON file (bloom.json), in the user's project directory. + * Currently, all user configuration is stored in a YAML file (bloom.yaml), in the user's project directory. * - * The JSON config file should define debugging environment objects. A debugging environment object is just - * a user defined JSON object that holds parameters relating to a specific debugging environment (e.g config params - * for the DebugTool, Target configuration and any debug server config). Because a config file - * can define multiple debugging environments, each object should be assigned a key in the config file. We use this - * key to allow users to select different debugging environments between debugging sessions. + * The YAML config file should define parameters for specific debug environments. Because a config file can define + * multiple debug environments, each environment must be assigned a unique name that can be used to identify the + * environment. This is why the 'environments' parameter is a YAML map, with the key being the environment name. * - * On application startup, we extract the config from this JSON file and generate an ProjectConfig object. + * On application startup, we extract the config from this YAML file and generate a ProjectConfig object. * See Application::loadProjectConfiguration() for more on this. * * Some config parameters are specific to certain entities within Bloom, but have no significance across the * rest of the application. For example, AVR8 targets require the 'physicalInterface' and other AVR8 specific * parameters. These are used to configure AVR8 targets, but have no significance across the rest of the - * application. This is why some configuration structs (like TargetConfig) include a QJsonObject member, typically - * named jsonObject. When instances of these structs are passed to the appropriate entities, any configuration - * required by those entities is extracted from the jsonObject member. This means we don't have to worry about any - * entity specific config parameters at the application level. We can simply extract what we need at an entity - * level and the rest of the application can remain oblivious. For an example on extracting entity specific - * config, see AVR8::preActivationConfigure(). + * application. This is why some configuration structs (like TargetConfig) include a YAML::Node member. + * When instances of these structs are passed to the appropriate entities, any configuration required by those + * entities is extracted from the YAML::Node member. This means we don't have to worry about any entity specific + * config parameters at the application level. We can simply extract what we need at an entity level and the rest + * of the application can remain oblivious. For an example on extracting entity specific config, see + * Avr8TargetConfig::Avr8TargetConfig() and Avr8::preActivationConfigure(). * * For more on project configuration, see Bloom documentation at https://bloom.oscillate.io/docs/configuration */ + /* + * Initially, we used the JSON format for project configuration files, but this was changed in version 0.11.0. + * See https://github.com/navnavnav/Bloom/issues/50 for more. + */ + /** * Configuration relating to a specific target. * * Please don't define any target specific configuration here, unless it applies to *all* targets across - * the application. If a target requires specific config, it should be extracted from the jsonObject member. - * This should be done in Target::preActivationConfigure(), to which an instance of TargetConfig is passed. + * the application. If a target requires specific config, it should be extracted from the YAML::Node (targetNode) + * member. This should be done in Target::preActivationConfigure(), to which an instance of TargetConfig is passed. * See the comment above on entity specific config for more on this. */ struct TargetConfig @@ -54,16 +57,20 @@ namespace Bloom */ std::optional variantName; - QJsonObject jsonObject; + /** + * For extracting any target specific configuration. See Avr8TargetConfig::Avr8TargetConfig() and + * Avr8::preActivationConfigure() for an example of this. + */ + YAML::Node targetNode; TargetConfig() = default; /** - * Obtains config parameters from JSON object. + * Obtains config parameters from YAML node. * - * @param jsonObject + * @param targetNode */ - explicit TargetConfig(const QJsonObject& jsonObject); + explicit TargetConfig(const YAML::Node& targetNode); }; /** @@ -71,7 +78,7 @@ namespace Bloom * * As with the TargetConfig struct, please don't add any manufacture/model specific configuration here. This * configuration should apply to all supported debug tools. Specific configuration can be extracted from the - * jsonObject member, as described in the TargetConfig comment above. + * YAML::Node (debugToolNode) member, as described in the TargetConfig comment above. */ struct DebugToolConfig { @@ -89,16 +96,19 @@ namespace Bloom */ bool releasePostDebugSession = true; - QJsonObject jsonObject; + /** + * For extracting any debug tool specific configuration. + */ + YAML::Node debugToolNode; DebugToolConfig() = default; /** - * Obtains config parameters from JSON object. + * Obtains config parameters from YAML node. * - * @param jsonObject + * @param debugToolNode */ - explicit DebugToolConfig(const QJsonObject& jsonObject); + explicit DebugToolConfig(const YAML::Node& debugToolNode); }; /** @@ -106,17 +116,25 @@ namespace Bloom */ struct DebugServerConfig { + /** + * The name of the selected debug server. + */ std::string name; - QJsonObject jsonObject; + + /** + * For extracting any debug server specific configuration. See GdbDebugServerConfig::GdbDebugServerConfig() and + * GdbRspDebugServer::GdbRspDebugServer() for an example of this. + */ + YAML::Node debugServerNode; DebugServerConfig() = default; /** - * Obtains config parameters from JSON object. + * Obtains config parameters from YAML node. * - * @param jsonObject + * @param debugServerNode */ - explicit DebugServerConfig(const QJsonObject& jsonObject); + explicit DebugServerConfig(const YAML::Node& debugServerNode); }; struct InsightConfig @@ -126,11 +144,11 @@ namespace Bloom InsightConfig() = default; /** - * Obtains config parameters from JSON object. + * Obtains config parameters from YAML node. * - * @param jsonObject + * @param insightNode */ - explicit InsightConfig(const QJsonObject& jsonObject); + explicit InsightConfig(const YAML::Node& insightNode); }; /** @@ -142,7 +160,7 @@ namespace Bloom struct EnvironmentConfig { /** - * The environment name is stored as the key to the JSON object containing the environment parameters. + * The environment name is stored as the key to the YAML map containing the environment parameters. * * Environment names must be unique. */ @@ -179,11 +197,12 @@ namespace Bloom std::optional insightConfig; /** - * Obtains config parameters from JSON object. + * Obtains config parameters from YAML node. * - * @param jsonObject + * @param name + * @param environmentNode */ - EnvironmentConfig(std::string name, QJsonObject jsonObject); + EnvironmentConfig(std::string name, const YAML::Node& environmentNode); }; /** @@ -211,10 +230,10 @@ namespace Bloom bool debugLoggingEnabled = false; /** - * Obtains config parameters from JSON object. + * Obtains config parameters from YAML node. * - * @param jsonObject + * @param configNode */ - explicit ProjectConfig(const QJsonObject& jsonObject); + explicit ProjectConfig(const YAML::Node& configNode); }; } diff --git a/src/TargetController/README.md b/src/TargetController/README.md index 2ea43080..6f963340 100644 --- a/src/TargetController/README.md +++ b/src/TargetController/README.md @@ -82,7 +82,7 @@ The TargetController possesses the ability to go into a suspended state. In this hardware is surrendered - Bloom will no longer be able to interact with the debug tool or target. The purpose of this state is to allow other programs access to the hardware, without requiring the termination of the Bloom process. The TargetController goes into a suspended state at the end of a debug session, if the user has enabled this via the -`releasePostDebugSession` debug tool parameter, in their project configuration file (bloom.json). See +`releasePostDebugSession` debug tool parameter, in their project configuration file (bloom.yaml). See `TargetControllerComponent::onDebugSessionFinishedEvent()` for more. When in a suspended state, the TargetController will reject most commands. More specifically, any command that diff --git a/src/Targets/Microchip/AVR/AVR8/Avr8.cpp b/src/Targets/Microchip/AVR/AVR8/Avr8.cpp index f2a75c8a..9d0de5b6 100644 --- a/src/Targets/Microchip/AVR/AVR8/Avr8.cpp +++ b/src/Targets/Microchip/AVR/AVR8/Avr8.cpp @@ -26,6 +26,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit void Avr8::preActivationConfigure(const TargetConfig& targetConfig) { Target::preActivationConfigure(targetConfig); + // Extract AVR8 specific target config this->targetConfig = Avr8TargetConfig(targetConfig); if (this->family.has_value()) { @@ -87,7 +88,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit "Failed to validate connected target - target signature mismatch.\nThe target signature" " (\"" + targetSignature.toHex() + "\") does not match the AVR8 target description signature (\"" + tdSignature.toHex() + "\"). This will likely be due to an incorrect target name in the configuration" - + " file (bloom.json)." + + " file (bloom.yaml)." ); } } diff --git a/src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.cpp b/src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.cpp index 7c5b9a74..63d0dd74 100644 --- a/src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.cpp +++ b/src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.cpp @@ -1,6 +1,6 @@ #include "Avr8TargetConfig.hpp" -#include "src/Logger/Logger.hpp" +#include "src/Helpers/String.hpp" #include "src/Exceptions/InvalidConfig.hpp" namespace Bloom::Targets::Microchip::Avr::Avr8Bit @@ -8,12 +8,13 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit Avr8TargetConfig::Avr8TargetConfig(const TargetConfig& targetConfig): TargetConfig(targetConfig) { using Bloom::Exceptions::InvalidConfig; - if (!targetConfig.jsonObject.contains("physicalInterface")) { + const auto& targetNode = targetConfig.targetNode; + + if (!targetNode["physicalInterface"]) { throw InvalidConfig("Missing physical interface config parameter for AVR8 target."); } - const auto physicalInterfaceName = targetConfig.jsonObject.value("physicalInterface").toString().toLower() - .toStdString(); + const auto physicalInterfaceName = String::asciiToLower(targetNode["physicalInterface"].as()); static const auto physicalInterfacesByName = Avr8TargetConfig::getPhysicalInterfacesByName(); @@ -23,26 +24,20 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit this->physicalInterface = physicalInterfacesByName.at(physicalInterfaceName); - if (targetConfig.jsonObject.contains("updateDwenFuseBit")) { - this->updateDwenFuseBit = targetConfig.jsonObject.value("updateDwenFuseBit").toBool(); + if (targetNode["updateDwenFuseBit"]) { + this->updateDwenFuseBit = targetNode["updateDwenFuseBit"].as(); } - if (targetConfig.jsonObject.contains("cycleTargetPowerPostDwenUpdate")) { - this->cycleTargetPowerPostDwenUpdate = targetConfig.jsonObject.value( - "cycleTargetPowerPostDwenUpdate" - ).toBool(); + if (targetNode["cycleTargetPowerPostDwenUpdate"]) { + this->cycleTargetPowerPostDwenUpdate = targetNode["cycleTargetPowerPostDwenUpdate"].as(); } - if (targetConfig.jsonObject.contains("disableDebugWirePreDisconnect")) { - this->disableDebugWireOnDeactivate = targetConfig.jsonObject.value( - "disableDebugWirePreDisconnect" - ).toBool(); + if (targetNode["disableDebugWirePreDisconnect"]) { + this->disableDebugWireOnDeactivate = targetNode["disableDebugWirePreDisconnect"].as(); } - if (targetConfig.jsonObject.contains("targetPowerCycleDelay")) { - this->targetPowerCycleDelay = std::chrono::milliseconds(targetConfig.jsonObject.value( - "targetPowerCycleDelay" - ).toInt(static_cast(this->targetPowerCycleDelay.count()))); + if (targetNode["targetPowerCycleDelay"]) { + this->targetPowerCycleDelay = std::chrono::milliseconds(targetNode["targetPowerCycleDelay"].as()); } } } diff --git a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp index e5f97150..8886966a 100644 --- a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "src/Helpers/Paths.hpp" #include "src/Logger/Logger.hpp" @@ -46,7 +47,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit::TargetDescription if (targetName.has_value() && matchingDescriptionFiles.empty()) { throw Exception("Failed to resolve target description file for target \"" + targetName.value() + "\" - target signature \"" + targetSignatureHex + "\" does not belong to target with name \"" + - targetName.value() + "\". Please review your bloom.json configuration."); + targetName.value() + "\". Please review your bloom.yaml configuration."); } if (matchingDescriptionFiles.size() == 1) {