Embedded Systems C Bridge API: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
Zeile 134: Zeile 134:
==== Reguests (from expecco to cBridge) ====
==== Reguests (from expecco to cBridge) ====


===== PROTOCOL =====
Sent from expecco to change the protocol.
This will only be sent iff the bridge announced the availability of another protocol (via a HELLO event),
AND expecco decides to another.
Expecco will choose the first within the list of available protocols, which is also supported by the expecco side.

{
"type": "request", // required
"message": "protocol", // required
"seq": sequenceNr // required
"protocol": "protocolToUse", // required
}

when this message arrives, the response MUST be sent in the current protocol mode.
Then, any further communication MUST be performed in the new protocol.


==== Events (from cBridge to expecco) ====
==== Events (from cBridge to expecco) ====

Version vom 1. September 2019, 13:18 Uhr

Embedded Systems C Bridge API[Bearbeiten]

We provide the CBridge code both as a DLL (shared object) and as a static link library upon request. If linked against the application, or dynamically loaded into the application, expecco can interact with - even if the target is an embedded system.

Architecture[Bearbeiten]

The CBridge opens a socket and listens for an incoming connection. Only one such connection may be active at any time. Once connected, expecco will send requests and receive responses, which are exchanged in human readable JSON format, which is very similar to the ChromeV8 debug interface message format.

The set of supported messages is defined by the target system - therefore customers have full control over which messages are allowed to be interchanged, and how they are handled. This is done before the bridge is activated by so called message registration calls.

The bridge code as provided by exept includes handlers for various common tasks, which can be registered as option. Except also provides a ready-to-run cBridge executable, which is configured to register handlers for remote code execution (i.e. for Bridged C Actions).

As an alternative to using the library, customers can also implement the wire protocol, which is described below.

CBridge Message Interchange Sequence Diagram[Bearbeiten]

In the following swim lane diagram,

  • function calls are marked as "=====>"
  • socket messages as "------>"
  • parallel execution as "||"
  • thread blocking (suspend / wait) as "***"
  • normal thread execution as "..."
expecco side         target                                cBridge library          cBridge thread
--------------------+-------------------------------------+------------------------+----------------------------
     ...            |    ...                              |                        | 
                    |initialization:                      |                        |
                    |  cBrige_registerHandler(...) =======> register handler       |
                    |                                     | immediate return       |
                    |                              <=======                        |
                    |     ...                             |                        | 
                    |  cBrige_registerHandler(...) =======> register handler       |
                    |                                     | immediate return       |
                    |                              <=======                        |
                    |     ...                             |                        | 
                    |  cBrige_startAsync(...)      =======> starts cBridge thread  | thread started    
                    |                                     | immediate return       | opens listen socket
                    |     ...                      <=======                        | await connection       
                    |  target runs as usual               |                        | ***
                    |     ...                             |                        | await incoming message
                    |                                     |                        | ***
     ...            |                                     |                        |
   send request -------------------------------------------------------------------> receive request (JSON)
   await response   |                                     |                        | decode request
     ***            |                                     |                        | prepare response object
                    |                                     |                        | call handler(req, resp)
                    |     ... || handler in target        <=========================
                    |     ... || fills response           |                        |
                    |     ... ||                          =========================> send response
                    |                                     |                        | encode response
   send request <------------------------------------------------------------------- send response (JSON)
     ...            |     ...                             |                        | await incoming message
                    |                                     |                        | ***

Different Threading Models[Bearbeiten]

The bridge library can be used in various different configurations:

Threaded with separate Socket handling code[Bearbeiten]

This is the easiest mode to use. The socket handler is started as a separate thread, which blocks in the listen() and read() calls to the socket. The target code must be changed to perform a single call into the cLibrary (to start the asynchronous bridge thread), in addition to the handler registration, which is required in all configurations (and of course, the handlers code).

This mode should be used if the target is a Windows program or if the target's operating system supports Posix threads.

Non-Threaded with Socket Polling[Bearbeiten]

In this mode, the main application should poll (or select on) the socket itself, and call into the cLibrary when either a connection is established, or an incoming message is received.

In addition to the handler registration calls and handler code implementation, the target needs to ne changed to call the library's incomingMessage handler.

This mode can be used when no thread support is provided by the operating system, or if there already exists an event handling loop which selects on input streams (eg. Qt, X11 or OSX main event loops), and sockets are to be used for bridge communication.

Non Threaded with Packet Delivery (non-Socket Communication)[Bearbeiten]

In this mode, the main application should use any mechanism available to exchange messages via any external port (USB, serial, socket) or via shared memory, and call into the cLibrary when an incoming message arrived. It must also register a packet delivery function, for the cLibrary to send back responses.

This mode must be used, if no socket communication is possible.

Different Memory Allocation Models[Bearbeiten]

As JSON objects vary in size and structure, these objects must use dynamically allocated memory. because many embedded systems will not allow or support the use of "malloc/free", the library can be configured to:

  • either use malloc / free dynamically (i.e. for every object) (dynamic malloc scheme)
  • or to use a single malloc'd area, which is allocated once at startup (single malloc scheme)
  • or to not use malloc/free at all, but instead use a static memory area for temporary data (static data scheme)

Memory needs to be dynamically allocated whenever an incoming message is parsed from JSON into a jsonObject, when additional fields are added to a jsonObject (i.e. when a requestHandler constructs a response object), or when a jsonObject response is finally encoded into JSON and set back to expecco.

All memory which is allocated for the request and response objects will be released when the message handler's response object has been sent to expecco. Pointers into it and field references are no longer valid, as the memory will be reused for the next request/response.

Dynamic Malloc Scheme[Bearbeiten]

This is the standard behavior when the target runs on Windows or Unix systems.

Allocations will be done by calling "malloc" multiple times, once for each individual jsonObject field and possibly for field values.

Single Malloc Scheme[Bearbeiten]

This should be used if the target system does provide malloc, but dynamic malloc is not allowed or not wanted due to other constraints (thread safety, predictability, real time constraints etc.).

A single memory area is allocated using "malloc" at startup time. All jsonObject fields will be allocated inside this arena, which will never be freed. The size of the arena defines the maximum JSON message size which can be interchanged, and an operation may fail due to that constraint.

Static Data Scheme[Bearbeiten]

This mode should be used, if no malloc is available or allowed at all inside the target system.

Similar to the previous scheme, but static memory (a data buffer provided by the target) is used, and malloc/free is never called.

CBridge Library[Bearbeiten]

JSON Library[Bearbeiten]

Messages are interchanged as JSON encoded packages. For this, a JSON library is part of the cLibrary, to parse and generate JSON.

Bridge Wire Protocol[Bearbeiten]

Frame Format[Bearbeiten]

A packets payload is always encoded as a JSON object. This payload can be delivered in one of the following frames:

  • HTTP/REST frame
    the payload is the POST data of an HTTP packet; the payload length is provided by the HTTP header.
  • a binary frame, consisting of 4 bytes of payload length, followed by the payload.
  • a textual frame, consisting of the payload length as ascii string, a space as separator, followed by the payload.

Currently, the HTML/REST format is not yet supported directly by the cBridge library. It can be used if the target app already includes an HTTP/REST service.


Reguests (from expecco to cBridge)[Bearbeiten]

PROTOCOL[Bearbeiten]

Sent from expecco to change the protocol. This will only be sent iff the bridge announced the availability of another protocol (via a HELLO event), AND expecco decides to another. Expecco will choose the first within the list of available protocols, which is also supported by the expecco side.


{
    "type":      "request",                    // required
    "message":   "protocol",                   // required
    "seq":       sequenceNr                    // required
    "protocol":  "protocolToUse",              // required
}

when this message arrives, the response MUST be sent in the current protocol mode. Then, any further communication MUST be performed in the new protocol.

Events (from cBridge to expecco)[Bearbeiten]

HELLO[Bearbeiten]

Sent from the bridge to expecco to provide version and protocol formats.

{
    "type":      "event",                      // required
    "message":   "hello",                      // required
    "seq":       sequenceNr                    // required
    "version":   "<version string>",           // optional
    "protocols": [ "<supported1>", ... ]       // optional
}

Used to announce version information and available protocols. Each <supported> element describes a protocol which is supported by the target/cLibrary, in order of preference (the targets preference). The <supported> strings are of the form: "frame/payload[/version], where frame describes the frame format, payload the encoding of the payload and the optional version further details on the used payload format. A missing version part defaults to "1".

Currently known protocols are:

  • text/json/1 - JSON encoded payload, in a text frame (i.e. prefixed by payload size in ascii and space)
  • binary/json/1 - JSON encoded payload, in a binary frame (i.e. prefixed by 4 bytes of payload size)
  • http/json/1 - JSON encoded payload, in an HTTP frame

The partner (expecco) may decide to switch the protocol, based on the returned information.

Requests (from cBridge to expecco)[Bearbeiten]



Copyright © 2014-2024 eXept Software AG