Replaced static TargetController state object access with new GetState command
This corrects a bug where the DebugServer checks if the TargetController is in service just before it's about to suspend. The DebugServer then attempts to start a new debug session, only for the TargetController to go into a suspended state. A fatal error occurs and a shutdown follows. This bug is only apparent when the user stops and starts debug sessions very quickly, with releasePostDebugSession set to true.
This commit is contained in:
@@ -7,6 +7,7 @@ namespace Bloom::TargetController::Commands
|
|||||||
enum class CommandType: std::uint8_t
|
enum class CommandType: std::uint8_t
|
||||||
{
|
{
|
||||||
GENERIC,
|
GENERIC,
|
||||||
|
GET_STATE,
|
||||||
GET_TARGET_DESCRIPTOR,
|
GET_TARGET_DESCRIPTOR,
|
||||||
STOP_TARGET_EXECUTION,
|
STOP_TARGET_EXECUTION,
|
||||||
RESUME_TARGET_EXECUTION,
|
RESUME_TARGET_EXECUTION,
|
||||||
|
|||||||
29
src/TargetController/Commands/GetState.hpp
Normal file
29
src/TargetController/Commands/GetState.hpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Command.hpp"
|
||||||
|
|
||||||
|
#include "src/TargetController/Responses/State.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::TargetController::Commands
|
||||||
|
{
|
||||||
|
class GetState: public Command
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using SuccessResponseType = Responses::State;
|
||||||
|
|
||||||
|
static constexpr CommandType type = CommandType::GET_STATE;
|
||||||
|
static inline const std::string name = "GetState";
|
||||||
|
|
||||||
|
[[nodiscard]] CommandType getType() const override {
|
||||||
|
return GetState::type;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool requiresActiveState() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool requiresDebugMode() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ namespace Bloom::TargetController::Responses
|
|||||||
{
|
{
|
||||||
GENERIC,
|
GENERIC,
|
||||||
ERROR,
|
ERROR,
|
||||||
|
STATE,
|
||||||
TARGET_DESCRIPTOR,
|
TARGET_DESCRIPTOR,
|
||||||
TARGET_REGISTERS_READ,
|
TARGET_REGISTERS_READ,
|
||||||
TARGET_MEMORY_READ,
|
TARGET_MEMORY_READ,
|
||||||
|
|||||||
24
src/TargetController/Responses/State.hpp
Normal file
24
src/TargetController/Responses/State.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Response.hpp"
|
||||||
|
|
||||||
|
#include "src/TargetController/TargetControllerState.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::TargetController::Responses
|
||||||
|
{
|
||||||
|
class State: public Response
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr ResponseType type = ResponseType::STATE;
|
||||||
|
|
||||||
|
TargetControllerState state;
|
||||||
|
|
||||||
|
explicit State(TargetControllerState state)
|
||||||
|
: state(state)
|
||||||
|
{}
|
||||||
|
|
||||||
|
[[nodiscard]] ResponseType getType() const override {
|
||||||
|
return State::type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ namespace Bloom::TargetController
|
|||||||
using Commands::CommandIdType;
|
using Commands::CommandIdType;
|
||||||
|
|
||||||
using Commands::Command;
|
using Commands::Command;
|
||||||
|
using Commands::GetState;
|
||||||
using Commands::GetTargetDescriptor;
|
using Commands::GetTargetDescriptor;
|
||||||
using Commands::GetTargetState;
|
using Commands::GetTargetState;
|
||||||
using Commands::StopTargetExecution;
|
using Commands::StopTargetExecution;
|
||||||
@@ -109,10 +110,6 @@ namespace Bloom::TargetController
|
|||||||
this->shutdown();
|
this->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetControllerState TargetControllerComponent::getState() {
|
|
||||||
return TargetControllerComponent::state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TargetControllerComponent::registerCommand(std::unique_ptr<Command> command) {
|
void TargetControllerComponent::registerCommand(std::unique_ptr<Command> command) {
|
||||||
auto commandQueueLock = TargetControllerComponent::commandQueue.acquireLock();
|
auto commandQueueLock = TargetControllerComponent::commandQueue.acquireLock();
|
||||||
TargetControllerComponent::commandQueue.getValue().push(std::move(command));
|
TargetControllerComponent::commandQueue.getValue().push(std::move(command));
|
||||||
@@ -171,6 +168,9 @@ namespace Bloom::TargetController
|
|||||||
TargetControllerComponent::checkUdevRules();
|
TargetControllerComponent::checkUdevRules();
|
||||||
|
|
||||||
// Register command handlers
|
// Register command handlers
|
||||||
|
this->registerCommandHandler<GetState>(
|
||||||
|
std::bind(&TargetControllerComponent::handleGetState, this, std::placeholders::_1)
|
||||||
|
);
|
||||||
|
|
||||||
this->registerCommandHandler<GetTargetDescriptor>(
|
this->registerCommandHandler<GetTargetDescriptor>(
|
||||||
std::bind(&TargetControllerComponent::handleGetTargetDescriptor, this, std::placeholders::_1)
|
std::bind(&TargetControllerComponent::handleGetTargetDescriptor, this, std::placeholders::_1)
|
||||||
@@ -761,6 +761,10 @@ namespace Bloom::TargetController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Responses::State> TargetControllerComponent::handleGetState(GetState& command) {
|
||||||
|
return std::make_unique<Responses::State>(this->state);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Responses::TargetDescriptor> TargetControllerComponent::handleGetTargetDescriptor(
|
std::unique_ptr<Responses::TargetDescriptor> TargetControllerComponent::handleGetTargetDescriptor(
|
||||||
GetTargetDescriptor& command
|
GetTargetDescriptor& command
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
#include "Commands/Command.hpp"
|
#include "Commands/Command.hpp"
|
||||||
|
#include "Commands/GetState.hpp"
|
||||||
#include "Commands/GetTargetDescriptor.hpp"
|
#include "Commands/GetTargetDescriptor.hpp"
|
||||||
#include "Commands/GetTargetState.hpp"
|
#include "Commands/GetTargetState.hpp"
|
||||||
#include "Commands/StopTargetExecution.hpp"
|
#include "Commands/StopTargetExecution.hpp"
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
|
|
||||||
// Responses
|
// Responses
|
||||||
#include "Responses/Response.hpp"
|
#include "Responses/Response.hpp"
|
||||||
|
#include "Responses/State.hpp"
|
||||||
#include "Responses/TargetDescriptor.hpp"
|
#include "Responses/TargetDescriptor.hpp"
|
||||||
#include "Responses/TargetState.hpp"
|
#include "Responses/TargetState.hpp"
|
||||||
#include "Responses/TargetRegistersRead.hpp"
|
#include "Responses/TargetRegistersRead.hpp"
|
||||||
@@ -86,8 +88,6 @@ namespace Bloom::TargetController
|
|||||||
*/
|
*/
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
static TargetControllerState getState();
|
|
||||||
|
|
||||||
static void registerCommand(std::unique_ptr<Commands::Command> command);
|
static void registerCommand(std::unique_ptr<Commands::Command> command);
|
||||||
|
|
||||||
static std::optional<std::unique_ptr<Responses::Response>> waitForResponse(
|
static std::optional<std::unique_ptr<Responses::Response>> waitForResponse(
|
||||||
@@ -111,7 +111,7 @@ namespace Bloom::TargetController
|
|||||||
* The TC starts off in a suspended state. TargetControllerComponent::resume() is invoked from the startup
|
* The TC starts off in a suspended state. TargetControllerComponent::resume() is invoked from the startup
|
||||||
* routine.
|
* routine.
|
||||||
*/
|
*/
|
||||||
static inline std::atomic<TargetControllerState> state = TargetControllerState::SUSPENDED;
|
TargetControllerState state = TargetControllerState::SUSPENDED;
|
||||||
|
|
||||||
ProjectConfig projectConfig;
|
ProjectConfig projectConfig;
|
||||||
EnvironmentConfig environmentConfig;
|
EnvironmentConfig environmentConfig;
|
||||||
@@ -334,6 +334,7 @@ namespace Bloom::TargetController
|
|||||||
void onDebugSessionFinishedEvent(const Events::DebugSessionFinished& event);
|
void onDebugSessionFinishedEvent(const Events::DebugSessionFinished& event);
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
std::unique_ptr<Responses::State> handleGetState(Commands::GetState& command);
|
||||||
std::unique_ptr<Responses::TargetDescriptor> handleGetTargetDescriptor(Commands::GetTargetDescriptor& command);
|
std::unique_ptr<Responses::TargetDescriptor> handleGetTargetDescriptor(Commands::GetTargetDescriptor& command);
|
||||||
std::unique_ptr<Responses::TargetState> handleGetTargetState(Commands::GetTargetState& command);
|
std::unique_ptr<Responses::TargetState> handleGetTargetState(Commands::GetTargetState& command);
|
||||||
std::unique_ptr<Responses::Response> handleStopTargetExecution(Commands::StopTargetExecution& command);
|
std::unique_ptr<Responses::Response> handleStopTargetExecution(Commands::StopTargetExecution& command);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#include "TargetControllerConsole.hpp"
|
#include "TargetControllerConsole.hpp"
|
||||||
|
|
||||||
#include "TargetControllerComponent.hpp"
|
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
|
#include "Commands/GetState.hpp"
|
||||||
#include "Commands/GetTargetDescriptor.hpp"
|
#include "Commands/GetTargetDescriptor.hpp"
|
||||||
#include "Commands/GetTargetState.hpp"
|
#include "Commands/GetTargetState.hpp"
|
||||||
#include "Commands/StopTargetExecution.hpp"
|
#include "Commands/StopTargetExecution.hpp"
|
||||||
@@ -25,6 +24,7 @@
|
|||||||
|
|
||||||
namespace Bloom::TargetController
|
namespace Bloom::TargetController
|
||||||
{
|
{
|
||||||
|
using Commands::GetState;
|
||||||
using Commands::GetTargetDescriptor;
|
using Commands::GetTargetDescriptor;
|
||||||
using Commands::GetTargetState;
|
using Commands::GetTargetState;
|
||||||
using Commands::StopTargetExecution;
|
using Commands::StopTargetExecution;
|
||||||
@@ -62,7 +62,10 @@ namespace Bloom::TargetController
|
|||||||
using Targets::TargetPinStateMappingType;
|
using Targets::TargetPinStateMappingType;
|
||||||
|
|
||||||
TargetControllerState TargetControllerConsole::getTargetControllerState() {
|
TargetControllerState TargetControllerConsole::getTargetControllerState() {
|
||||||
return TargetControllerComponent::getState();
|
return this->commandManager.sendCommandAndWaitForResponse(
|
||||||
|
std::make_unique<GetState>(),
|
||||||
|
this->defaultTimeout
|
||||||
|
)->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TargetControllerConsole::isTargetControllerInService() noexcept {
|
bool TargetControllerConsole::isTargetControllerInService() noexcept {
|
||||||
|
|||||||
Reference in New Issue
Block a user