2021-04-04 21:04:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
#include <cstdint>
|
|
|
|
|
#include <atomic>
|
|
|
|
|
#include <optional>
|
|
|
|
|
|
|
|
|
|
#include "TargetMemory.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace Targets
|
2021-04-04 21:04:12 +01:00
|
|
|
{
|
2024-07-23 21:14:22 +01:00
|
|
|
enum class TargetExecutionState: std::uint8_t
|
2021-04-04 21:04:12 +01:00
|
|
|
{
|
|
|
|
|
UNKNOWN,
|
|
|
|
|
STOPPED,
|
|
|
|
|
RUNNING,
|
2024-07-23 21:14:22 +01:00
|
|
|
STEPPING,
|
2021-04-04 21:04:12 +01:00
|
|
|
};
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
enum class TargetMode: std::uint8_t
|
|
|
|
|
{
|
|
|
|
|
DEBUGGING,
|
|
|
|
|
PROGRAMMING,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static_assert(std::atomic<TargetExecutionState>::is_always_lock_free);
|
|
|
|
|
static_assert(std::atomic<TargetMode>::is_always_lock_free);
|
|
|
|
|
static_assert(std::atomic<std::optional<TargetMemoryAddress>>::is_always_lock_free);
|
|
|
|
|
|
|
|
|
|
struct TargetState
|
|
|
|
|
{
|
|
|
|
|
std::atomic<TargetExecutionState> executionState = TargetExecutionState::UNKNOWN;
|
|
|
|
|
std::atomic<TargetMode> mode = TargetMode::DEBUGGING;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Current program counter - only populated when TargetState::executionState == TargetExecutionState::STOPPED
|
|
|
|
|
*/
|
|
|
|
|
std::atomic<std::optional<TargetMemoryAddress>> programCounter = {};
|
|
|
|
|
|
|
|
|
|
TargetState() = default;
|
|
|
|
|
|
|
|
|
|
TargetState(
|
|
|
|
|
TargetExecutionState executionState,
|
|
|
|
|
TargetMode mode,
|
|
|
|
|
std::optional<TargetMemoryAddress> programCounter = std::nullopt
|
|
|
|
|
)
|
|
|
|
|
: executionState(executionState)
|
|
|
|
|
, mode(mode)
|
|
|
|
|
, programCounter(programCounter)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
TargetState(const TargetState& other)
|
|
|
|
|
: executionState(other.executionState.load())
|
|
|
|
|
, mode(other.mode.load())
|
|
|
|
|
, programCounter(other.programCounter.load())
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
TargetState& operator = (const TargetState& other) {
|
|
|
|
|
this->executionState = other.executionState.load();
|
|
|
|
|
this->mode = other.mode.load();
|
|
|
|
|
this->programCounter = other.programCounter.load();
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator == (const TargetState& other) const {
|
|
|
|
|
return
|
|
|
|
|
this->executionState.load() == other.executionState.load()
|
|
|
|
|
&& this->mode.load() == other.mode.load()
|
|
|
|
|
&& this->programCounter.load() == other.programCounter.load()
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator != (const TargetState& other) const {
|
|
|
|
|
return !(*this == other);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|