2022-03-31 17:56:45 +01:00
|
|
|
## DebugServer
|
|
|
|
|
|
|
|
|
|
The DebugServer component exposes an interface to the connected target, for third-party programs such as IDEs. The
|
2022-03-31 17:58:20 +01:00
|
|
|
DebugServer runs on a dedicated thread. The entry point is `DebugServerComponent::run()`. Bloom's main thread will start
|
2022-03-31 17:56:45 +01:00
|
|
|
the DebugServer thread once the TargetController has been started. See `Applciation::startDebugServer()` for more.
|
|
|
|
|
|
|
|
|
|
The DebugServer is designed to accommodate numerous server implementations. The interface exposed by the server is
|
2022-03-31 21:52:46 +01:00
|
|
|
implementation-defined. For example, the [AVR GDB server](./Gdb/AvrGdb/AvrGdbRsp.hpp) exposes an interface to the
|
2022-03-31 17:56:45 +01:00
|
|
|
connected AVR target, by implementing the
|
|
|
|
|
[GDB Remote Serial Protocol](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html), over a TCP/IP connection.
|
2022-03-31 17:58:20 +01:00
|
|
|
Each server must implement the interface defined in the [`ServerInterface` class](./ServerInterface.hpp).
|
2022-03-31 17:56:45 +01:00
|
|
|
|
|
|
|
|
At startup, the DebugServer will select the appropriate server implementation, based on the user's project
|
|
|
|
|
configuration (bloom.json - see [`DebugServerConfig`](../ProjectConfig.hpp)). Each server implementation is mapped to a
|
|
|
|
|
config name, which is to be used in the project configuration file. For the mapping, see
|
|
|
|
|
`DebugServerComponent::getAvailableServersByName()`. After initialising the server (via `ServerInterface::init()`),
|
|
|
|
|
control of the DebugServer thread will then be handed over to the server implementation (via `ServerInterface::run()`).
|
|
|
|
|
For more on this, see `DebugServerComponent::startup()` and `DebugServerComponent::run()`.
|
|
|
|
|
|
|
|
|
|
#### Servicing events
|
|
|
|
|
|
|
|
|
|
During startup, the DebugServer will register event handlers for certain events. Once control of the DebugServer thread
|
|
|
|
|
has been handed over to the selected server implementation, the server must ensure that any incoming events are
|
|
|
|
|
processed ASAP. How this is done is implementation-defined. A reference to the DebugServer's event listener
|
|
|
|
|
(`DebugServerComponent::eventListener`) can be passed to the server if need be (see
|
|
|
|
|
`DebugServerComponent::getAvailableServersByName()` for an example of this).
|
|
|
|
|
|
2022-03-31 21:23:04 +01:00
|
|
|
A server implementation does not have to service events - it can simply return from `ServerInterface::run()` upon
|
2022-03-31 17:56:45 +01:00
|
|
|
an event being triggered. Returning from that function will allow control of the thread to be handed back to
|
|
|
|
|
`DebugServerComponent::run()`, where any pending events will be processed. Afterwards, if the DebugServer is still
|
|
|
|
|
running (it hasn't received an event which triggers a shutdown), the `ServerInterface::run()` function will be called
|
|
|
|
|
again, and control will be handed back to the server implementation. The AVR GDB server implementation employs this
|
|
|
|
|
method to ensure that events are processed ASAP. See the relevant documentation for more.
|
|
|
|
|
|
2022-04-03 02:13:06 +01:00
|
|
|
---
|
|
|
|
|
|
2022-03-31 21:23:04 +01:00
|
|
|
Any blocking I/O employed by a server implementation can support event interrupts using an
|
2022-04-15 22:05:50 +01:00
|
|
|
[`EventFdNotifier`](../Helpers/EventFdNotifier.hpp) and [`EpollInstance`](../Helpers/EpollInstance.hpp).
|
2022-03-31 21:23:04 +01:00
|
|
|
|
|
|
|
|
Key points:
|
2022-04-15 22:05:50 +01:00
|
|
|
- The `EventFdNotifier` class is an RAII wrapper for a Linux
|
|
|
|
|
[eventfd object](https://man7.org/linux/man-pages/man2/eventfd.2.html). It implements the
|
|
|
|
|
[`NotifierInterface`](../Helpers/NotifierInterface.hpp). An event can be recorded against the eventfd
|
|
|
|
|
object via a call to `EventFdNotifier::notify()`.
|
|
|
|
|
- The [`EventListener`](../EventManager/EventListener.hpp) class can accept an `NotifierInterface` object via
|
|
|
|
|
`EventListener::setInterruptEventNotifier()`. If a `NotifierInterface` has been set on an `EventListener`, the
|
|
|
|
|
`EventListener` will call `NotifierInterface::notify()` everytime an event is registered for that listener.
|
2022-03-31 21:23:04 +01:00
|
|
|
- The `EpollInstance` class is an RAII wrapper for a Linux
|
|
|
|
|
[epoll instance](https://man7.org/linux/man-pages/man7/epoll.7.html). It allows us to wait for any activity on a set
|
|
|
|
|
of file descriptors. File descriptors can be added and removed from the epoll instance via `EpollInstance::addEntry()`
|
|
|
|
|
and `EpollInstance::removeEntry()`. Calling `EpollInstance::waitForEvent()` will block until there is activity on at
|
|
|
|
|
least one of the file descriptors, or a timeout has been reached.
|
|
|
|
|
|
2022-04-15 22:05:50 +01:00
|
|
|
With an `EventFdNotifier` and `EpollInstance`, one can perform a blocking I/O operation which can be interrupted by an
|
2022-03-31 21:23:04 +01:00
|
|
|
event. For an example of this, see the AVR GDB server implementation - it employs the method described above to allow
|
|
|
|
|
the interruption of blocking I/O operations when an event is triggered. Specifically,
|
2022-03-31 21:52:46 +01:00
|
|
|
[`GdbRspDebugServer::waitForConnection()`](./Gdb/GdbRspDebugServer.hpp) or
|
|
|
|
|
[`Gdb::Connection::read()`](./Gdb/Connection.hpp).
|
2022-03-31 21:23:04 +01:00
|
|
|
|
2022-04-03 02:13:06 +01:00
|
|
|
---
|
|
|
|
|
|
2022-03-31 17:56:45 +01:00
|
|
|
### Server implementations
|
|
|
|
|
|
2022-03-31 17:58:20 +01:00
|
|
|
Currently, there is only one server implementation. Others may be added upon request.
|
2022-03-31 17:56:45 +01:00
|
|
|
|
2022-04-03 02:13:06 +01:00
|
|
|
| Server Name | Brief Description | Documentation |
|
|
|
|
|
|----------------|-------------------------------------------------------------------------------|---------------------------------------------------|
|
|
|
|
|
| AVR GDB Server | An AVR-specific implementation of the GDB Remote Serial Protocol over TCP/IP. | [/src/DebugServer/Gdb/README.md](./Gdb/README.md) |
|
2022-03-31 17:58:20 +01:00
|
|
|
|
|
|
|
|
#### Adding new server implementations
|
|
|
|
|
|
|
|
|
|
If you're considering adding a new server implementation, please discuss this with me (Nav) before you begin. Creating
|
|
|
|
|
a new server implementation is not a trivial task.
|