#pragma once #include #include #include #include "TargetMemory.hpp" namespace Targets { enum class TargetExecutionState: std::uint8_t { UNKNOWN, STOPPED, RUNNING, STEPPING, }; enum class TargetMode: std::uint8_t { DEBUGGING, PROGRAMMING, }; static_assert(std::atomic::is_always_lock_free); static_assert(std::atomic::is_always_lock_free); static_assert(std::atomic>::is_always_lock_free); struct TargetState { std::atomic executionState = TargetExecutionState::UNKNOWN; std::atomic mode = TargetMode::DEBUGGING; /** * Current program counter - only populated when TargetState::executionState == TargetExecutionState::STOPPED */ std::atomic> programCounter = {}; TargetState() = default; TargetState( TargetExecutionState executionState, TargetMode mode, std::optional 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); } }; }