Services - tools - models - for embedded software development
Embecosm divider strip
Prev  Next

2.5.2.  Implementing Server Code on the Target

This is the usual approach for embedded systems, and is the strategy encapsulated in the server stubs supplied with the GDB source code.

There are two key components of the code:

  1. Code to establish the serial connection with the client GDB session.

  2. Code for the target's interrupt handlers, so all exceptions are routed through the RSP server.

In the stub code, the user must implement the serial connection by supplying functions getDebugChar () and putDebugChar (). The user must supply the function exceptionHandler () to set up exception handling.

The serial connection is usually established on the first call to getDebugChar (). This is standard POSIX code to access either the serial device, or to listen for a TCP/IP or UDP/IP connection. The target may choose to block here, if it does not wish to run without control from a GDB client.

If the serial connection chooses not to block on getDebugChar () then the exception handler should be prepared for this response, allowing the exception to be processed as normal.

[Note]Note

The stub RSP server code supplied with the GDB source distribution assumes getDebugChar () blocks until the connection is established.

In general the server interacts with the client only when it has received control due to a target exception.

At start up, the first time this occurs, the target will be waiting for the GDB client to send a packet to which it can respond. These dialogs will continue until the client GDB session wishes to continue or step the target (c, C, i, I, s or S packet).

Thereafter control is received only when another exception has occurred, following a continue or step. In this case, the first action of the target RSP server should be to send the reply packet back to the client GDB session.

[Caution]Caution

The key limitation in the stub RSP server code supplied with the GDB source distribution is that it only deals with the second case. In other words, it always sends a reply packet to the client, even on first execution.

This causes two problems. First, the putDebugChar () is called before getDebugChar (), so it must be able to establish the connection.

Secondly, the initial reply is sent without a request packet from the client GDB session. As a result this reply will typically be queued and appear as the reply to the first request packet from GDB. The client interface is quite robust and usually quietly rejects unexpected packets, but there is potential for client requests and server responses to get out of step. It certainly does not represent good program design.

The final issue that server code needs to address is the issue of BREAK signaling from the client. This is a raw 0x03 byte sent from the client between packets. Typically this is in response to a ctrl-C from the client GDB session.

If the target server wishes to handle such signaling, it must provide an event driven getDebugChar (), triggered when data is received, which can act on such BREAK signals.

Embecosm divider strip