Introduced concept of programming mode

This commit is contained in:
Nav
2022-06-05 16:13:43 +01:00
parent accea6a08c
commit cfe533e5db
11 changed files with 172 additions and 0 deletions

View File

@@ -40,6 +40,10 @@ namespace Bloom::TargetController::Commands
return false; return false;
} }
[[nodiscard]] virtual bool requiresDebugMode() const {
return true;
}
private: private:
static inline std::atomic<CommandIdType> lastCommandId = 0; static inline std::atomic<CommandIdType> lastCommandId = 0;
}; };

View File

@@ -24,5 +24,7 @@ namespace Bloom::TargetController::Commands
SET_TARGET_PIN_STATE, SET_TARGET_PIN_STATE,
GET_TARGET_STACK_POINTER, GET_TARGET_STACK_POINTER,
GET_TARGET_PROGRAM_COUNTER, GET_TARGET_PROGRAM_COUNTER,
ENABLE_PROGRAMMING_MODE,
DISABLE_PROGRAMMING_MODE,
}; };
} }

View File

@@ -0,0 +1,27 @@
#pragma once
#include "Command.hpp"
namespace Bloom::TargetController::Commands
{
class DisableProgrammingMode: public Command
{
public:
static constexpr CommandType type = CommandType::DISABLE_PROGRAMMING_MODE;
static inline const std::string name = "DisableProgrammingMode";
DisableProgrammingMode() = default;
[[nodiscard]] CommandType getType() const override {
return DisableProgrammingMode::type;
}
[[nodiscard]] bool requiresStoppedTargetState() const override {
return true;
}
[[nodiscard]] bool requiresDebugMode() const override {
return false;
}
};
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include "Command.hpp"
namespace Bloom::TargetController::Commands
{
class EnableProgrammingMode: public Command
{
public:
static constexpr CommandType type = CommandType::ENABLE_PROGRAMMING_MODE;
static inline const std::string name = "EnableProgrammingMode";
EnableProgrammingMode() = default;
[[nodiscard]] CommandType getType() const override {
return EnableProgrammingMode::type;
}
[[nodiscard]] bool requiresStoppedTargetState() const override {
return true;
}
[[nodiscard]] bool requiresDebugMode() const override {
return false;
}
};
}

View File

@@ -17,5 +17,9 @@ namespace Bloom::TargetController::Commands
[[nodiscard]] CommandType getType() const override { [[nodiscard]] CommandType getType() const override {
return GetTargetDescriptor::type; return GetTargetDescriptor::type;
} }
[[nodiscard]] bool requiresDebugMode() const override {
return false;
}
}; };
} }

View File

@@ -42,5 +42,9 @@ namespace Bloom::TargetController::Commands
[[nodiscard]] bool requiresStoppedTargetState() const override { [[nodiscard]] bool requiresStoppedTargetState() const override {
return true; return true;
} }
[[nodiscard]] bool requiresDebugMode() const override {
return this->memoryType == Targets::TargetMemoryType::RAM;
}
}; };
} }

View File

@@ -34,5 +34,9 @@ namespace Bloom::TargetController::Commands
[[nodiscard]] bool requiresStoppedTargetState() const override { [[nodiscard]] bool requiresStoppedTargetState() const override {
return true; return true;
} }
[[nodiscard]] bool requiresDebugMode() const override {
return this->memoryType == Targets::TargetMemoryType::RAM;
}
}; };
} }

View File

@@ -40,6 +40,8 @@ namespace Bloom::TargetController
using Commands::SetTargetPinState; using Commands::SetTargetPinState;
using Commands::GetTargetStackPointer; using Commands::GetTargetStackPointer;
using Commands::GetTargetProgramCounter; using Commands::GetTargetProgramCounter;
using Commands::EnableProgrammingMode;
using Commands::DisableProgrammingMode;
using Responses::Response; using Responses::Response;
using Responses::TargetRegistersRead; using Responses::TargetRegistersRead;
@@ -311,6 +313,12 @@ namespace Bloom::TargetController
throw Exception("Illegal target state - command requires target to be stopped"); throw Exception("Illegal target state - command requires target to be stopped");
} }
if (this->target->programmingModeEnabled() && command->requiresDebugMode()) {
throw Exception(
"Illegal target state - command cannot be serviced whilst the target is in programming mode."
);
}
this->registerCommandResponse( this->registerCommandResponse(
commandId, commandId,
this->commandHandlersByCommandType.at(commandType)(*(command.get())) this->commandHandlersByCommandType.at(commandType)(*(command.get()))
@@ -420,6 +428,8 @@ namespace Bloom::TargetController
this->deregisterCommandHandler(SetTargetPinState::type); this->deregisterCommandHandler(SetTargetPinState::type);
this->deregisterCommandHandler(GetTargetStackPointer::type); this->deregisterCommandHandler(GetTargetStackPointer::type);
this->deregisterCommandHandler(GetTargetProgramCounter::type); this->deregisterCommandHandler(GetTargetProgramCounter::type);
this->deregisterCommandHandler(EnableProgrammingMode::type);
this->deregisterCommandHandler(DisableProgrammingMode::type);
this->eventListener->deregisterCallbacksForEventType<Events::DebugSessionFinished>(); this->eventListener->deregisterCallbacksForEventType<Events::DebugSessionFinished>();
@@ -506,6 +516,14 @@ namespace Bloom::TargetController
std::bind(&TargetControllerComponent::handleGetTargetProgramCounter, this, std::placeholders::_1) std::bind(&TargetControllerComponent::handleGetTargetProgramCounter, this, std::placeholders::_1)
); );
this->registerCommandHandler<EnableProgrammingMode>(
std::bind(&TargetControllerComponent::handleEnableProgrammingMode, this, std::placeholders::_1)
);
this->registerCommandHandler<DisableProgrammingMode>(
std::bind(&TargetControllerComponent::handleDisableProgrammingMode, this, std::placeholders::_1)
);
this->eventListener->registerCallbackForEventType<Events::DebugSessionFinished>( this->eventListener->registerCallbackForEventType<Events::DebugSessionFinished>(
std::bind(&TargetControllerComponent::onDebugSessionFinishedEvent, this, std::placeholders::_1) std::bind(&TargetControllerComponent::onDebugSessionFinishedEvent, this, std::placeholders::_1)
); );
@@ -706,6 +724,18 @@ namespace Bloom::TargetController
EventManager::triggerEvent(std::make_shared<Events::TargetReset>()); EventManager::triggerEvent(std::make_shared<Events::TargetReset>());
} }
void TargetControllerComponent::enableProgrammingMode() {
this->target->enableProgrammingMode();
EventManager::triggerEvent(std::make_shared<Events::ProgrammingModeEnabled>());
}
void TargetControllerComponent::disableProgrammingMode() {
this->target->disableProgrammingMode();
EventManager::triggerEvent(std::make_shared<Events::ProgrammingModeDisabled>());
}
Targets::TargetDescriptor& TargetControllerComponent::getTargetDescriptor() { Targets::TargetDescriptor& TargetControllerComponent::getTargetDescriptor() {
if (!this->cachedTargetDescriptor.has_value()) { if (!this->cachedTargetDescriptor.has_value()) {
this->cachedTargetDescriptor = this->target->getDescriptor(); this->cachedTargetDescriptor = this->target->getDescriptor();
@@ -815,6 +845,12 @@ namespace Bloom::TargetController
const auto bufferSize = command.buffer.size(); const auto bufferSize = command.buffer.size();
const auto bufferStartAddress = command.startAddress; const auto bufferStartAddress = command.startAddress;
const auto& targetDescriptor = this->getTargetDescriptor();
if (command.memoryType == targetDescriptor.programMemoryType && !this->target->programmingModeEnabled()) {
throw Exception("Cannot write to program memory - programming mode not enabled.");
}
this->target->writeMemory(command.memoryType, bufferStartAddress, buffer); this->target->writeMemory(command.memoryType, bufferStartAddress, buffer);
EventManager::triggerEvent( EventManager::triggerEvent(
std::make_shared<Events::MemoryWrittenToTarget>(command.memoryType, bufferStartAddress, bufferSize) std::make_shared<Events::MemoryWrittenToTarget>(command.memoryType, bufferStartAddress, bufferSize)
@@ -822,6 +858,7 @@ namespace Bloom::TargetController
if ( if (
EventManager::isEventTypeListenedFor(Events::RegistersWrittenToTarget::type) EventManager::isEventTypeListenedFor(Events::RegistersWrittenToTarget::type)
&& command.memoryType == targetDescriptor.programMemoryType
&& this->registerDescriptorsByMemoryType.contains(command.memoryType) && this->registerDescriptorsByMemoryType.contains(command.memoryType)
) { ) {
/* /*
@@ -908,4 +945,20 @@ namespace Bloom::TargetController
) { ) {
return std::make_unique<TargetProgramCounter>(this->target->getProgramCounter()); return std::make_unique<TargetProgramCounter>(this->target->getProgramCounter());
} }
std::unique_ptr<Response> TargetControllerComponent::handleEnableProgrammingMode(EnableProgrammingMode& command) {
if (!this->target->programmingModeEnabled()) {
this->enableProgrammingMode();
}
return std::make_unique<Response>();
}
std::unique_ptr<Response> TargetControllerComponent::handleDisableProgrammingMode(DisableProgrammingMode& command) {
if (this->target->programmingModeEnabled()) {
this->disableProgrammingMode();
}
return std::make_unique<Response>();
}
} }

View File

@@ -37,6 +37,8 @@
#include "Commands/SetTargetPinState.hpp" #include "Commands/SetTargetPinState.hpp"
#include "Commands/GetTargetStackPointer.hpp" #include "Commands/GetTargetStackPointer.hpp"
#include "Commands/GetTargetProgramCounter.hpp" #include "Commands/GetTargetProgramCounter.hpp"
#include "Commands/EnableProgrammingMode.hpp"
#include "Commands/DisableProgrammingMode.hpp"
// Responses // Responses
#include "Responses/Response.hpp" #include "Responses/Response.hpp"
@@ -292,6 +294,17 @@ namespace Bloom::TargetController
*/ */
void resetTarget(); void resetTarget();
/**
* Puts the target into programming mode and disables command handlers for debug commands (commands that serve
* debug operations such as SetBreakpoint, ResumeTargetExecution, etc).
*/
void enableProgrammingMode();
/**
* Pulls the target out of programming mode and enables command handlers for debug commands.
*/
void disableProgrammingMode();
/** /**
* Returns a cached instance of the target's TargetDescriptor. * Returns a cached instance of the target's TargetDescriptor.
* *
@@ -344,5 +357,7 @@ namespace Bloom::TargetController
std::unique_ptr<Responses::TargetProgramCounter> handleGetTargetProgramCounter( std::unique_ptr<Responses::TargetProgramCounter> handleGetTargetProgramCounter(
Commands::GetTargetProgramCounter& command Commands::GetTargetProgramCounter& command
); );
std::unique_ptr<Responses::Response> handleEnableProgrammingMode(Commands::EnableProgrammingMode& command);
std::unique_ptr<Responses::Response> handleDisableProgrammingMode(Commands::DisableProgrammingMode& command);
}; };
} }

View File

@@ -20,6 +20,8 @@
#include "Commands/SetTargetPinState.hpp" #include "Commands/SetTargetPinState.hpp"
#include "Commands/GetTargetStackPointer.hpp" #include "Commands/GetTargetStackPointer.hpp"
#include "Commands/GetTargetProgramCounter.hpp" #include "Commands/GetTargetProgramCounter.hpp"
#include "Commands/EnableProgrammingMode.hpp"
#include "Commands/DisableProgrammingMode.hpp"
namespace Bloom::TargetController namespace Bloom::TargetController
{ {
@@ -40,6 +42,8 @@ namespace Bloom::TargetController
using Commands::SetTargetPinState; using Commands::SetTargetPinState;
using Commands::GetTargetStackPointer; using Commands::GetTargetStackPointer;
using Commands::GetTargetProgramCounter; using Commands::GetTargetProgramCounter;
using Commands::EnableProgrammingMode;
using Commands::DisableProgrammingMode;
using Targets::TargetDescriptor; using Targets::TargetDescriptor;
using Targets::TargetState; using Targets::TargetState;
@@ -214,4 +218,18 @@ namespace Bloom::TargetController
this->defaultTimeout this->defaultTimeout
); );
} }
void TargetControllerConsole::enableProgrammingMode() {
this->commandManager.sendCommandAndWaitForResponse(
std::make_unique<EnableProgrammingMode>(),
this->defaultTimeout
);
}
void TargetControllerConsole::disableProgrammingMode() {
this->commandManager.sendCommandAndWaitForResponse(
std::make_unique<DisableProgrammingMode>(),
this->defaultTimeout
);
}
} }

View File

@@ -183,6 +183,20 @@ namespace Bloom::TargetController
*/ */
void resetTarget(); void resetTarget();
/**
* Enables programming mode on the target.
*
* From the point of invoking this function, the TargetController will reject any subsequent commands for
* debug operations (such as ResumeTargetExecution, ReadTargetRegisters, etc), until programming mode has
* been disabled.
*/
void enableProgrammingMode();
/**
* Disables programming mode on the target.
*/
void disableProgrammingMode();
private: private:
CommandManager commandManager = CommandManager(); CommandManager commandManager = CommandManager();