Data Path
Components of openDAQ SDK create a Data Path when they are connected. The components that form the data path are:
-
Connection,
-
Input Port,
A Connection object is created when a Signal is connected to an Input Port. When connected, Packets are transmitted from the source Signal and travel through the Connection and Input Port to its owner (usually a Function Block or a reader), where they are processed.
Connection
A Connection is an object that contains Packets in a queue. When a Packet is added to a Connection object, it is inserted into a queue of Packets and the Input Port attached to the Connection is notified.
Although it is possible to manually create a Connection object, the client code will rarely need this. A Connection is automatically created when a Signal is connected to the Input Port.
-
Cpp
-
Python
inputPort.connect(signal);
// connection object is now accessible on inputPort
daq::ConnectionPtr connection = inputPort.getConnection();
input_port.connect(signal)
# connection object is now accessible on input_port
connection = input_port.connection
Input Port
Input Ports are objects that accept a Signal and create a Connection object. A single Input Port accepts exactly one Signal. Most Input Ports require a Connection to Signal. In this case Function Block that owns the Input Port does not process the data and it enters an invalid state. Some Function Blocks may create optional Input Ports. In this case, the Function Block can process data (from other connected Input Ports) even if the optional Input Port is not connected.
Input Ports do not automatically dequeue the Packets from the Connection objects. The owner of the Input Port is responsible to dequeue the Packets and process them.
-
Cpp
-
Python
daq::PacketPtr packet = inputPort.getConnection().dequeue();
// process packet, i.e. read samples from the packet
processPacket(packet);
packet = input_port.connection.dequeue()
# process packet, i.e. read samples from the packet
process_packet(packet)
Input Port notifications
The owner of an Input Port can assign a notification event that is triggered when a Packet arrives at its Connection. The Input Port can be configured to trigger the notification event either:
-
within the same thread in which the Packet was added to the Signal,
-
is scheduled as a task, which is executed by the scheduler in an arbitrary worker thread.
Most often Input Ports of Function Blocks will schedule notifications on a worker thread in order not to interfere with the Signal producer thread.
Usually, the notification handler will deque the Packets from the Connection queue and process the data contained in the Packet.
Packet generation, transmission, and destruction
Packets are always produced by a component, such as a Channel, and inserted into the Data Path through a Signal. When a Packet is added to the Signal, it is immediately distributed to all connected Input Ports via Connection objects.
Packets (as all openDAQ objects) are reference counted. The Connection object only stores a reference to a Packet. If a Signal is connected to multiple Input Ports, only a single instance of the Packet will be referenced in all Connections.
Packets are automatically destroyed when they are no longer referenced by other objects.
Value and domain Packets
Input Ports connect value Signal. Domain Signals are usually not connected to an Input Port unless the domain Signal is treated as a value Signal. To correctly interpret the data, both value and domain Packets must be transmitted. If a value Packet that is transmitted on a Data Path has a reference to a domain Packet then the domain Packet will also be transmitted automatically.
Complex Data Path
When a Packet arrives at the Function Block or other component, it is processed and new Packets can be created in their Signal and distributed to other components. Function blocks can be chained to other Function Blocks. This way a complex Data Path is created.
Packet transmission over a network
Suppose openDAQ is used on a Device, as well as on a host computer. In that case, Packets are generated on the device where they are serialized to binary format, transmitted over a network, and deserialized on the host PC. On the host PC, the Packets are added to mirrored Signal which may be connected to other Input Ports.
The current implementation of openDAQ supports only device-to-host Packet transmission.
Extracting Packets
The client application should read the data from Signals using various types of readers. Using readers the application does not have to read the data from the Packets. However, in some cases, it might be beneficial to directly work with Packets. The easiest way to do this is to create a Packet reader. The Packet reader returns the Packets when the read function is called. It can also block the current thread until a Packet arrives or a timeout elapses.