Added config struct for RISC-V debug translator implementation, and WCH debug tools.

Also some tidying in the `DebugToolConfig` struct
This commit is contained in:
Nav
2024-10-06 23:32:36 +01:00
parent a1dfa56913
commit 418db1df99
14 changed files with 142 additions and 35 deletions

View File

@@ -44,9 +44,11 @@ target_sources(
# RISC-V debug tools # RISC-V debug tools
${CMAKE_CURRENT_SOURCE_DIR}/WCH/Protocols/WchLink/WchLinkInterface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/WCH/Protocols/WchLink/WchLinkInterface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/WCH/WchLinkToolConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/WCH/WchLinkBase.cpp ${CMAKE_CURRENT_SOURCE_DIR}/WCH/WchLinkBase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/WCH/WchLinkE/WchLinkE.cpp ${CMAKE_CURRENT_SOURCE_DIR}/WCH/WchLinkE/WchLinkE.cpp
# RISC-V Debug Translator implementation # RISC-V Debug Translator implementation
${CMAKE_CURRENT_SOURCE_DIR}/Protocols/RiscVDebugSpec/DebugTranslatorConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Protocols/RiscVDebugSpec/DebugTranslator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Protocols/RiscVDebugSpec/DebugTranslator.cpp
) )

View File

@@ -50,10 +50,12 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
DebugTranslator::DebugTranslator( DebugTranslator::DebugTranslator(
DebugTransportModuleInterface& dtmInterface, DebugTransportModuleInterface& dtmInterface,
const DebugTranslatorConfig& config,
const TargetDescriptionFile& targetDescriptionFile, const TargetDescriptionFile& targetDescriptionFile,
const RiscVTargetConfig& targetConfig const RiscVTargetConfig& targetConfig
) )
: dtmInterface(dtmInterface) : dtmInterface(dtmInterface)
, config(config)
, targetDescriptionFile(targetDescriptionFile) , targetDescriptionFile(targetDescriptionFile)
, targetConfig(targetConfig) , targetConfig(targetConfig)
{} {}
@@ -130,12 +132,15 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
controlRegister.haltRequest = true; controlRegister.haltRequest = true;
this->writeDebugModuleControlRegister(controlRegister); this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
auto statusRegister = this->readDebugModuleStatusRegister(); auto statusRegister = this->readDebugModuleStatusRegister();
for (auto attempts = 1; !statusRegister.allHalted && attempts <= maxAttempts; ++attempts) { for (
std::this_thread::sleep_for(std::chrono::microseconds{10}); auto attempts = 1;
!statusRegister.allHalted
&& (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout;
++attempts
) {
std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY);
statusRegister = this->readDebugModuleStatusRegister(); statusRegister = this->readDebugModuleStatusRegister();
} }
@@ -154,12 +159,15 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
controlRegister.resumeRequest = true; controlRegister.resumeRequest = true;
this->writeDebugModuleControlRegister(controlRegister); this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
auto statusRegister = this->readDebugModuleStatusRegister(); auto statusRegister = this->readDebugModuleStatusRegister();
for (auto attempts = 1; !statusRegister.allResumeAcknowledge && attempts <= maxAttempts; ++attempts) { for (
std::this_thread::sleep_for(std::chrono::microseconds{10}); auto attempts = 1;
!statusRegister.allResumeAcknowledge
&& (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout;
++attempts
) {
std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY);
statusRegister = this->readDebugModuleStatusRegister(); statusRegister = this->readDebugModuleStatusRegister();
} }
@@ -203,12 +211,15 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
controlRegister.ndmReset = false; controlRegister.ndmReset = false;
this->writeDebugModuleControlRegister(controlRegister); this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
auto statusRegister = this->readDebugModuleStatusRegister(); auto statusRegister = this->readDebugModuleStatusRegister();
for (auto attempts = 1; !statusRegister.allHaveReset && attempts <= maxAttempts; ++attempts) { for (
std::this_thread::sleep_for(std::chrono::microseconds{10}); auto attempts = 1;
!statusRegister.allHaveReset
&& (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout;
++attempts
) {
std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY);
statusRegister = this->readDebugModuleStatusRegister(); statusRegister = this->readDebugModuleStatusRegister();
} }
@@ -595,12 +606,15 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
controlRegister.selectedHartIndex = this->selectedHartIndex; controlRegister.selectedHartIndex = this->selectedHartIndex;
this->writeDebugModuleControlRegister(controlRegister); this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
controlRegister = this->readDebugModuleControlRegister(); controlRegister = this->readDebugModuleControlRegister();
for (auto attempts = 1; !controlRegister.debugModuleActive && attempts <= maxAttempts; ++attempts) { for (
std::this_thread::sleep_for(std::chrono::microseconds{10}); auto attempts = 1;
!controlRegister.debugModuleActive
&& (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout;
++attempts
) {
std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY);
controlRegister = this->readDebugModuleControlRegister(); controlRegister = this->readDebugModuleControlRegister();
} }
@@ -615,12 +629,15 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
controlRegister.selectedHartIndex = this->selectedHartIndex; controlRegister.selectedHartIndex = this->selectedHartIndex;
this->writeDebugModuleControlRegister(controlRegister); this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
controlRegister = this->readDebugModuleControlRegister(); controlRegister = this->readDebugModuleControlRegister();
for (auto attempts = 1; controlRegister.debugModuleActive && attempts <= maxAttempts; ++attempts) { for (
std::this_thread::sleep_for(std::chrono::microseconds{10}); auto attempts = 1;
controlRegister.debugModuleActive
&& (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout;
++attempts
) {
std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY);
controlRegister = this->readDebugModuleControlRegister(); controlRegister = this->readDebugModuleControlRegister();
} }
@@ -741,9 +758,13 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
return abstractStatusRegister.commandError; return abstractStatusRegister.commandError;
} }
constexpr auto maxAttempts = 10; for (
for (auto attempts = 1; abstractStatusRegister.busy && attempts <= maxAttempts; ++attempts) { auto attempts = 1;
std::this_thread::sleep_for(std::chrono::microseconds{10}); abstractStatusRegister.busy
&& (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout;
++attempts
) {
std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY);
abstractStatusRegister = this->readDebugModuleAbstractControlStatusRegister(); abstractStatusRegister = this->readDebugModuleAbstractControlStatusRegister();
} }

View File

@@ -3,6 +3,7 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
#include <chrono>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <optional> #include <optional>
@@ -11,6 +12,7 @@
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp" #include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp"
#include "DebugTransportModuleInterface.hpp" #include "DebugTransportModuleInterface.hpp"
#include "DebugTranslatorConfig.hpp"
#include "src/Targets/RiscV/TargetDescriptionFile.hpp" #include "src/Targets/RiscV/TargetDescriptionFile.hpp"
#include "src/Targets/RiscV/RiscVTargetConfig.hpp" #include "src/Targets/RiscV/RiscVTargetConfig.hpp"
@@ -40,6 +42,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
public: public:
DebugTranslator( DebugTranslator(
DebugTransportModuleInterface& dtmInterface, DebugTransportModuleInterface& dtmInterface,
const DebugTranslatorConfig& config,
const ::Targets::RiscV::TargetDescriptionFile& targetDescriptionFile, const ::Targets::RiscV::TargetDescriptionFile& targetDescriptionFile,
const ::Targets::RiscV::RiscVTargetConfig& targetConfig const ::Targets::RiscV::RiscVTargetConfig& targetConfig
); );
@@ -85,7 +88,10 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
) override; ) override;
private: private:
static constexpr auto DEBUG_MODULE_RESPONSE_DELAY = std::chrono::microseconds{10};
DebugTransportModuleInterface& dtmInterface; DebugTransportModuleInterface& dtmInterface;
const DebugTranslatorConfig& config;
const ::Targets::RiscV::TargetDescriptionFile& targetDescriptionFile; const ::Targets::RiscV::TargetDescriptionFile& targetDescriptionFile;
const ::Targets::RiscV::RiscVTargetConfig& targetConfig; const ::Targets::RiscV::RiscVTargetConfig& targetConfig;

View File

@@ -0,0 +1,12 @@
#include "DebugTranslatorConfig.hpp"
namespace DebugToolDrivers::Protocols::RiscVDebugSpec
{
DebugTranslatorConfig::DebugTranslatorConfig(const YAML::Node& configNode) {
if (configNode["targetResponseTimeout"]) {
this->targetResponseTimeout = std::chrono::microseconds{
configNode["targetResponseTimeout"].as<int>(this->targetResponseTimeout.count())
};
}
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <chrono>
#include <yaml-cpp/yaml.h>
namespace DebugToolDrivers::Protocols::RiscVDebugSpec
{
struct DebugTranslatorConfig
{
public:
/**
* Microsecond timeout for the RISC-V target to action or respond to a command.
*/
std::chrono::microseconds targetResponseTimeout = std::chrono::microseconds{100};
DebugTranslatorConfig() = default;
explicit DebugTranslatorConfig(const YAML::Node& configNode);
};
}

View File

@@ -11,12 +11,14 @@ namespace DebugToolDrivers::Wch
using Exceptions::DeviceInitializationFailure; using Exceptions::DeviceInitializationFailure;
WchLinkBase::WchLinkBase( WchLinkBase::WchLinkBase(
const DebugToolConfig& toolConfig,
WchLinkVariant variant, WchLinkVariant variant,
std::uint16_t vendorId, std::uint16_t vendorId,
std::uint16_t productId, std::uint16_t productId,
std::uint8_t wchLinkUsbInterfaceNumber std::uint8_t wchLinkUsbInterfaceNumber
) )
: UsbDevice(vendorId, productId) : UsbDevice(vendorId, productId)
, toolConfig(WchLinkToolConfig{toolConfig})
, variant(variant) , variant(variant)
, wchLinkUsbInterfaceNumber(wchLinkUsbInterfaceNumber) , wchLinkUsbInterfaceNumber(wchLinkUsbInterfaceNumber)
{} {}
@@ -77,6 +79,7 @@ namespace DebugToolDrivers::Wch
if (!this->wchRiscVTranslator) { if (!this->wchRiscVTranslator) {
this->wchRiscVTranslator = std::make_unique<DebugTranslator>( this->wchRiscVTranslator = std::make_unique<DebugTranslator>(
*(this->wchLinkInterface.get()), *(this->wchLinkInterface.get()),
this->toolConfig.riscVDebugTranslatorConfig,
targetDescriptionFile, targetDescriptionFile,
targetConfig targetConfig
); );

View File

@@ -8,6 +8,9 @@
#include "src/DebugToolDrivers/USB/UsbDevice.hpp" #include "src/DebugToolDrivers/USB/UsbDevice.hpp"
#include "src/DebugToolDrivers/USB/UsbInterface.hpp" #include "src/DebugToolDrivers/USB/UsbInterface.hpp"
#include "WchLinkToolConfig.hpp"
#include "src/ProjectConfig.hpp"
#include "Protocols/WchLink/WchLinkInterface.hpp" #include "Protocols/WchLink/WchLinkInterface.hpp"
#include "src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.hpp" #include "src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.hpp"
@@ -20,6 +23,7 @@ namespace DebugToolDrivers::Wch
{ {
public: public:
WchLinkBase( WchLinkBase(
const DebugToolConfig& toolConfig,
WchLinkVariant variant, WchLinkVariant variant,
std::uint16_t vendorId, std::uint16_t vendorId,
std::uint16_t productId, std::uint16_t productId,
@@ -64,6 +68,7 @@ namespace DebugToolDrivers::Wch
) override; ) override;
protected: protected:
WchLinkToolConfig toolConfig;
bool initialised = false; bool initialised = false;
WchLinkVariant variant; WchLinkVariant variant;

View File

@@ -2,8 +2,9 @@
namespace DebugToolDrivers::Wch namespace DebugToolDrivers::Wch
{ {
WchLinkE::WchLinkE() WchLinkE::WchLinkE(const DebugToolConfig& toolConfig)
: WchLinkBase( : WchLinkBase(
toolConfig,
WchLinkVariant::LINK_E_CH32V307, WchLinkVariant::LINK_E_CH32V307,
WchLinkE::USB_VENDOR_ID, WchLinkE::USB_VENDOR_ID,
WchLinkE::USB_PRODUCT_ID, WchLinkE::USB_PRODUCT_ID,

View File

@@ -5,6 +5,8 @@
#include "src/DebugToolDrivers/WCH/WchLinkBase.hpp" #include "src/DebugToolDrivers/WCH/WchLinkBase.hpp"
#include "src/ProjectConfig.hpp"
namespace DebugToolDrivers::Wch namespace DebugToolDrivers::Wch
{ {
/** /**
@@ -21,7 +23,7 @@ namespace DebugToolDrivers::Wch
static const inline std::uint16_t USB_PRODUCT_ID = 0x8010; static const inline std::uint16_t USB_PRODUCT_ID = 0x8010;
static const inline std::uint8_t WCH_LINK_INTERFACE_NUMBER = 0; static const inline std::uint8_t WCH_LINK_INTERFACE_NUMBER = 0;
WchLinkE(); WchLinkE(const DebugToolConfig& toolConfig);
std::string getName() override { std::string getName() override {
return "WCH-LinkE"; return "WCH-LinkE";

View File

@@ -0,0 +1,16 @@
#include "WchLinkToolConfig.hpp"
namespace DebugToolDrivers::Wch
{
WchLinkToolConfig::WchLinkToolConfig(const DebugToolConfig& toolConfig)
: DebugToolConfig(toolConfig)
{
const auto& toolNode = toolConfig.toolNode;
if (toolNode["riscVDebugTranslator"]) {
this->riscVDebugTranslatorConfig = Protocols::RiscVDebugSpec::DebugTranslatorConfig{
toolNode["riscVDebugTranslator"]
};
}
}
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include <yaml-cpp/yaml.h>
#include "src/ProjectConfig.hpp"
#include "src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslatorConfig.hpp"
namespace DebugToolDrivers::Wch
{
/**
* Extending the generic DebugToolConfig struct to accommodate WCH-Link configuration parameters.
*/
struct WchLinkToolConfig: public DebugToolConfig
{
public:
Protocols::RiscVDebugSpec::DebugTranslatorConfig riscVDebugTranslatorConfig = {};
explicit WchLinkToolConfig(const DebugToolConfig& toolConfig);
};
}

View File

@@ -212,19 +212,19 @@ TargetConfig::TargetConfig(const YAML::Node& targetNode) {
this->targetNode = targetNode; this->targetNode = targetNode;
} }
DebugToolConfig::DebugToolConfig(const YAML::Node& debugToolNode) { DebugToolConfig::DebugToolConfig(const YAML::Node& toolNode) {
if (!debugToolNode.IsMap()) { if (!toolNode.IsMap()) {
throw Exceptions::InvalidConfig{ throw Exceptions::InvalidConfig{
"Invalid debug tool configuration provided - node must take the form of a YAML mapping." "Invalid debug tool configuration provided - node must take the form of a YAML mapping."
}; };
} }
if (!debugToolNode["name"]) { if (!toolNode["name"]) {
throw Exceptions::InvalidConfig{"No debug tool name found."}; throw Exceptions::InvalidConfig{"No debug tool name found."};
} }
this->name = StringService::asciiToLower(debugToolNode["name"].as<std::string>()); this->name = StringService::asciiToLower(toolNode["name"].as<std::string>());
this->debugToolNode = debugToolNode; this->toolNode = toolNode;
} }
DebugServerConfig::DebugServerConfig(const YAML::Node& debugServerNode) { DebugServerConfig::DebugServerConfig(const YAML::Node& debugServerNode) {

View File

@@ -107,16 +107,16 @@ struct DebugToolConfig
/** /**
* For extracting any debug tool specific configuration. * For extracting any debug tool specific configuration.
*/ */
YAML::Node debugToolNode; YAML::Node toolNode;
DebugToolConfig() = default; DebugToolConfig() = default;
/** /**
* Obtains config parameters from YAML node. * Obtains config parameters from YAML node.
* *
* @param debugToolNode * @param toolNode
*/ */
explicit DebugToolConfig(const YAML::Node& debugToolNode); explicit DebugToolConfig(const YAML::Node& toolNode);
}; };
/** /**

View File

@@ -373,8 +373,8 @@ namespace TargetController
}, },
{ {
"wch-link-e", "wch-link-e",
[] { [this] {
return std::make_unique<DebugToolDrivers::Wch::WchLinkE>(); return std::make_unique<DebugToolDrivers::Wch::WchLinkE>(this->environmentConfig.debugToolConfig);
} }
}, },
}; };