Added section on TC suspension, in TC documentation
This commit is contained in:
@@ -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
|
**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
|
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.
|
[The TargetControllerConsole class](#the-targetcontrollerconsole-class) section below.
|
||||||
|
|
||||||
Commands can be sent to the TargetController via the [`Bloom::TargetController::CommandManager`](./CommandManager.hpp)
|
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
|
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>`.
|
`readMemoryResponse` will be of type `std::unique_ptr<TargetController::Responses::TargetMemoryRead>`.
|
||||||
|
|
||||||
The `CommandManager::sendCommandAndWaitForResponse<CommandType>(std::unique_ptr<CommandType> command, std::chrono::milliseconds timeout)`
|
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
|
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
|
until a timeout has been reached. Because it is a template function, it is able to resolve the appropriate response
|
||||||
is able to resolve the appropriate response type at compile-time (see the `SuccessResponseType` alias in some command
|
type at compile-time (see the `SuccessResponseType` alias in some command classes). If the TargetController responds
|
||||||
classes). If the TargetController responds with an error, or the timeout is reached,
|
with an error, or the timeout is reached, `CommandManager::sendCommandAndWaitForResponse()` will throw an exception.
|
||||||
`CommandManager::sendCommandAndWaitForResponse()` will throw an exception.
|
|
||||||
|
|
||||||
#### The TargetControllerConsole class
|
#### 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
|
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
|
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
|
**should not** directly issue commands via the `Bloom::TargetController::CommandManager`, unless there is a very good
|
||||||
there is a very good reason to do so.
|
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.
|
TODO: Cover debug tool & target drivers.
|
||||||
|
|||||||
Reference in New Issue
Block a user