Replaced project configuration format from JSON to YAML
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Bloom::DebugServer
|
||||
EventListenerPointer eventListener = std::make_shared<EventListener>("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.
|
||||
|
||||
@@ -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<std::string>(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<std::string>();
|
||||
}
|
||||
|
||||
if (debugServerConfig.jsonObject.contains("port")) {
|
||||
const auto portValue = debugServerConfig.jsonObject.value("port");
|
||||
if (debugServerConfig.debugServerNode["port"]) {
|
||||
this->listeningPortNumber = static_cast<std::uint16_t>(
|
||||
portValue.isString() ? portValue.toString().toInt(nullptr, 10) : portValue.toInt()
|
||||
debugServerConfig.debugServerNode["port"].as<int>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()`).
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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::string>(std::nullopt);
|
||||
|
||||
try {
|
||||
environmentName = environmentIt->first.as<std::string>();
|
||||
|
||||
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<bool>(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<bool>(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<bool>(
|
||||
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<std::string>());
|
||||
|
||||
if (jsonObject.contains("variantName")) {
|
||||
this->variantName = jsonObject.find("variantName").value().toString().toLower().toStdString();
|
||||
if (targetNode["variantName"]) {
|
||||
this->variantName = String::asciiToLower(targetNode["variantName"].as<std::string>());
|
||||
}
|
||||
|
||||
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<std::string>());
|
||||
|
||||
if (jsonObject.contains("releasePostDebugSession")) {
|
||||
this->releasePostDebugSession = jsonObject.find("releasePostDebugSession").value().toBool();
|
||||
if (debugToolNode["releasePostDebugSession"]) {
|
||||
this->releasePostDebugSession = debugToolNode["releasePostDebugSession"].as<bool>(
|
||||
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<std::string>());
|
||||
this->debugServerNode = debugServerNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,41 +3,44 @@
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <QJsonObject>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
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<std::string> 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> 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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<std::string>());
|
||||
|
||||
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<bool>();
|
||||
}
|
||||
|
||||
if (targetConfig.jsonObject.contains("cycleTargetPowerPostDwenUpdate")) {
|
||||
this->cycleTargetPowerPostDwenUpdate = targetConfig.jsonObject.value(
|
||||
"cycleTargetPowerPostDwenUpdate"
|
||||
).toBool();
|
||||
if (targetNode["cycleTargetPowerPostDwenUpdate"]) {
|
||||
this->cycleTargetPowerPostDwenUpdate = targetNode["cycleTargetPowerPostDwenUpdate"].as<bool>();
|
||||
}
|
||||
|
||||
if (targetConfig.jsonObject.contains("disableDebugWirePreDisconnect")) {
|
||||
this->disableDebugWireOnDeactivate = targetConfig.jsonObject.value(
|
||||
"disableDebugWirePreDisconnect"
|
||||
).toBool();
|
||||
if (targetNode["disableDebugWirePreDisconnect"]) {
|
||||
this->disableDebugWireOnDeactivate = targetNode["disableDebugWirePreDisconnect"].as<bool>();
|
||||
}
|
||||
|
||||
if (targetConfig.jsonObject.contains("targetPowerCycleDelay")) {
|
||||
this->targetPowerCycleDelay = std::chrono::milliseconds(targetConfig.jsonObject.value(
|
||||
"targetPowerCycleDelay"
|
||||
).toInt(static_cast<int>(this->targetPowerCycleDelay.count())));
|
||||
if (targetNode["targetPowerCycleDelay"]) {
|
||||
this->targetPowerCycleDelay = std::chrono::milliseconds(targetNode["targetPowerCycleDelay"].as<int>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#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) {
|
||||
|
||||
Reference in New Issue
Block a user