Added section on TC suspension, in TC documentation

This commit is contained in:
Nav
2022-05-02 16:36:23 +01:00
parent d0ca05f9e9
commit 9b2537553d

View File

@@ -19,7 +19,7 @@ All TargetController commands can be found in [src/TargetController/Commands](./
**NOTE:** Components within Bloom do not typically concern themselves with the TargetController command-response
mechanism. Instead, they use the `TargetControllerConsole` class, which encapsulates the command-response mechanism and
provides a simplified means for other components to interact with the connected hardware. For more, see
provides a simplified means for interaction with the connected hardware. For more, see
[The TargetControllerConsole class](#the-targetcontrollerconsole-class) section below.
Commands can be sent to the TargetController via the [`Bloom::TargetController::CommandManager`](./CommandManager.hpp)
@@ -42,17 +42,16 @@ const auto readMemoryResponse = tcCommandManager.sendCommandAndWaitForResponse(
std::chrono::milliseconds(1000) // Response timeout
);
const auto& data = readmemoryResponse->data;
const auto& data = readMemoryResponse->data;
```
`readMemoryResponse` will be of type `std::unique_ptr<TargetController::Responses::TargetMemoryRead>`.
The `CommandManager::sendCommandAndWaitForResponse<CommandType>(std::unique_ptr<CommandType> command, std::chrono::milliseconds timeout)`
member function is a template function. It will issue the command to the TargetController and wait for a response, or
until a timeout has been reached. Because `CommandManager::sendCommandAndWaitForResponse()` is a template function, it
is able to resolve the appropriate response type at compile-time (see the `SuccessResponseType` alias in some command
classes). If the TargetController responds with an error, or the timeout is reached,
`CommandManager::sendCommandAndWaitForResponse()` will throw an exception.
until a timeout has been reached. Because it is a template function, it is able to resolve the appropriate response
type at compile-time (see the `SuccessResponseType` alias in some command classes). If the TargetController responds
with an error, or the timeout is reached, `CommandManager::sendCommandAndWaitForResponse()` will throw an exception.
#### The TargetControllerConsole class
@@ -71,11 +70,45 @@ const auto data = tcConsole.readMemory(
```
The `TargetControllerConsole` class does not require any dependencies at construction. It can be constructed in
different threads and used freely to gain access to the connected hardware.
different threads and used freely to gain access to the connected hardware, from any component within Bloom.
All components within Bloom should use the `TargetControllerConsole` class to interact with the connected hardware. They
**should not** directly issue commands via the [`Bloom::TargetController::CommandManager`](./CommandManager.hpp) unless
there is a very good reason to do so.
`
**should not** directly issue commands via the `Bloom::TargetController::CommandManager`, unless there is a very good
reason to do so.
### TargetController suspension
The TargetController possesses the ability to go into a suspended state. In this state, control of the connected
hardware is surrendered - Bloom will no longer be able to interact with the debug tool or target. The purpose of this
state is to allow other programs access to the hardware, without requiring the termination of the Bloom process. The
TargetController goes into a suspended state at the end of a debug session, if the user has enabled this via the
`releasePostDebugSession` debug tool parameter, in their project configuration file (bloom.json). See
`TargetControllerComponent::onDebugSessionFinishedEvent()` for more.
When in a suspended state, the TargetController will reject most commands. More specifically, any command that
requires access to the debug tool or target. Issuing any of these commands whilst the TargetController is suspended
will result in an error response.
Upon suspension, the TargetController will trigger a `Bloom::Events::TargetControllerStateChanged` event. Other
components listen for this event to promptly perform the necessary actions in response to the state change. For example,
the [GDB debug server implementation](../DebugServer/Gdb/README.md) will terminate any active debug session:
```c++
void GdbRspDebugServer::onTargetControllerStateChanged(const Events::TargetControllerStateChanged& event) {
if (event.state == TargetControllerState::SUSPENDED && this->activeDebugSession.has_value()) {
Logger::warning("TargetController suspended unexpectedly - terminating debug session");
this->terminateActiveDebugSession();
}
}
```
In some cases, the TargetController may be forced to go into a suspended state. This could be in response to another
program stealing control of the hardware. Actually, this is what led to the introduction of TargetController suspension.
See the corresponding [GitHub issue](https://github.com/navnavnav/Bloom/issues/3) for more.
For more on TargetController suspension, see `TargetControllerComponent::suspend()` and
`TargetControllerComponent::resume()`.
---
TODO: Cover debug tool & target drivers.