Introduction to the Kinds
From an object-oriented perspective, adding Properties to an entity results in a public class member on the resulting class declaration 1. Likewise, Properties can be defined with a variety of primitive types as scalar values or structures as well as arrays of those types. When an entity is running, readable Properties can also be viewed from the Python shell via the entity’s api()
method 2.
The IDE will assist in adding default values and range limits to Properties. It is important to note however that at this time these range limits take no form in the generated code, only the XML files. This exclusion makes range values simply a designer’s footnotes to a user of the entity. And, for reasons that will be discussed in the following sections, default values are irrelevant for the Message kind.
All stated, Devices and Components share an almost identical set of Property behaviors called kinds
. Since a Component is never allocated against, it lacks the Allocate kind 3. Besides this exclusion, these kinds can roughly fit into three categories: Device Matching, Attribute Management, and Action.
Device Matching
Earlier versions of REDHAWK had an execparam
kind which represented a property value that is provided to the entity upon creation. These properties then can also be considered roughly analogous to arguments passed to a constructor method in object-oriented sense. The entity requires a value to operate correctly and will receive the call to set the value once. Starting with REDHAWK 2.0, this kind is now analgous to a property
with the Pass on command line
flag set in the IDE. This flag is only allowed for simple
-type properties (scalar values).
Examples of kind would follow the same thought. For a Device, it might be a hardware ID to locate on its PCI bus or a network port to open. For a Component, it could be to kick off building a lengthy interpolation table for making a lighter-weight filter. In both cases the decision would be to do work before the entity is requested or commanded to start.
Attribute Management
These kinds result in method calls on the entity instance (configure()
and allocateCapacity()
/deallocateCapacity()
, respectively). Both calls can happen multiple times over the lifespan of the entity depending on the use case.
Property
The property
kind in general has replaced the configure
kind starting with REDHAWK 2.0. It can be thought of as a traditional get/set public interface. It has a default defined in the entity which can be overwritten by the parent entity (Waveform or Node) as long as the access method permits it (read, write, etc.).
This kind can also be altered at any time after the entity has initialized to both monitor or control the entity in some way either by the Python shell or the IDE (for example, the SCA Explorer). In both cases, the configure()
4 method is used by the third party to write the value and the queryValue()
method is for reading.
Based on that description, it is intuitive then to consider this kind as an optional override. The entity can safely assume a value will exist for that Property before starting. Otherwise, something severe happened elsewhere in the system.
Allocation
The allocation
kind only apply to Devices since it is the receiver of an allocation dependencies by way of the allocateCapacity()
method 5. Calls for allocation occur after the initial configuration of the Device has occurred. This leads to a Waveform launch-oriented dependency mechanism that can also be regarded as a hardware reservation.
From a Component’s perspective, the most common examples of allocation tend to focus on use of memory or storage by declaring Dependencies. A Waveform on the other hand can also establish a usesdevice
relationship against this kind to make Port connections depend on finding an appropriate Device with both the allocable properties and named Port.
Another example would be to maintain a set of flags for the number of Components that could request control over a multi-channel Device 6. When the last flag is reserved, all other allocations would be rejected 7 until a flag is returned.
When the Application Factory releases a Waveform, the Component instances are also released. Any associated dependencies (and usesdevice
relationships) involved in originally launching that Waveform are then deallocated using the deallocateCapacity()
8 method on the associated Devices. This release can occur from deliberate operator action or automatically when the Waveform itself loses its depended-upon resources at some point during its own life cycle.
Action
Action-type Properties are event channel -based making each asynchronous and pull-oriented actions initiated by the receiver of the data. And in one case, the Message, a Port is required to handle the data.
Event
The event
Property kind existed in versions of REDHAWK earlier than 2.0 and would also instantiate a propEvent
port for carrying the event. Beginning with 2.0 however, the effective behavior is now built into the the parent entity’s interfaces by the Component or Device being part of the PropertyEmitter
interface. This kind is now simply part of the property
kind as well, meaning any property
Property can potentially be watched by a downstream listener.
Message
The message
Property kind is oriented towards a point-to-point coordination between entities, but it can be used in multipoint mechanism as well since it inherits from the underlying Event services. The user must add at least one MessageEvent
Port to carry the Message out of the entity. This difference allows the user to either output different Messages together on the same Port or implement separate Ports for each Message.
The message kind ideally suited then as an optional control loop element. The Device or Component could operate fine without this information, but if it is received, would treat it as newly-commanded data. And since this kind is inherits from Event, it can pass through FindBy
and into its own named channel in the system for even more exotic control schemes.
Properties Example
REDHAWK properties provide an assortment of options in architecting a given system. This figure above focuses on a few possibilities involving properties (white, black outline) and ports (blue or green). The interconnections and flow of data are shown by the various arrows between the properties and ports; each is covered in detail in this section.
Initialization
Starting from the top, the Device’s on_command_line
property is of kind property
with the Pass on command line
option set (also, it is a simple
type). As mentioned previously, this kind of property is set shortly after the Device’s class constructor is called (i.e., initialization) and before any of the other property
properties. This initial configure()
call ignores the access type (i.e., it can be written a value even if it is defined as readonly
). Moreover any callbacks associated with setting the property at this step are not called.
Similarly the configurable_property
is of kind property
which will have its value set shortly after the on_command_line
properties are set. Along with a default value in the Device definition, it too can be overwritten at the Node level. However it differs from on_command_line
in that its read/write settings could also permit its being changed at runtime from either the Python shell or IDE interfaces 9.
Interconnections
The Component and Device have 3 paths of communication between them and all are realized in the form of Ports. These data paths are:
- BULKIO data flowing from
data_output
todata_input
- A bidirectional
message
structure,message_property
- Any number of Device
property
properties listened to remotely (by the Component) at some interval
Usesdevice
The interconnections for data_input
/data_output
and message_property
are established using a shared usesdevice
relationship as described in the Waveform. In this case, the relationship uses the allocable_property
ID (kind: allocation
) to locate the required Device for mapping each pair of ports.
The usesdevice
is resolved by the Domain Manager’s Application Factory after the Device has already received its other property settings and, potentially, after an allocation has already occurred. The behavior is the equivalent of letting a Waveform dictate some additional parameter adjustments to the Device prior to connecting the stream and starting the Component as long as the Device agrees that those adjustments are possible.
By Reference
The event_properties
(kind: property
) are not using ports anymore. Previously a propEvent
port would be provided for conveying specifically-marked properties downstream to a listener, and the designer of the source had control over when those events were pushed. With REDHAWK 2.0, the port is gone and any property
Property can be listened to for changes by some downstream entities by the listener defining the interval to check for changes.
One subscribes to property change events either using the IDE or programmatically by using a PropertyChangeListener
or an Event Channel. Both are a bit more involved and covered at greater length in our other training (Events and Channels).
FindBy
One method that is not shown in this figure is called FindBy
. When designing a Node or Waveform, one can add this simple anchor to the diagram to either locate or create named Event Channels (among other things). This allows one to attach the Message Event port to the FindBy
and any downstream listeners can do the same, treating it as a point to multi-point broadcasting system. Once the channel is established, the Domain Manager then handles the exchange of those events at runtime. These exchanges can also be monitored through REDHAWK’s event viewing facilities 10.
- For Java and C++ only since Python does not make a distinction. ↩
- The exception is the Message kind. ↩
- However, the IDE will show it as a possible selection in REDHAWK 1.9.0. ↩
- Each implementation language has its own variation on this method. ↩
- Each implementation language has its own variation of this method. ↩
-
The
USRP_UHD
example in the REDHAWK GitHub repository is a good example of this behavior. ↩ -
Rejection occurs when a Device’s
allocateCapacity
implementation returnsfalse
. ↩ - Each implementation language has some variation of this method. ↩
- Either the Eclipse project editor or the SCA Explorer could be used. ↩
-
These facilities include the command line utility
eventviewer
and the Python shell. ↩