Overview of the Waveform

Figure shows two Waveforms re-using available resources
Figure shows two Waveforms re-using available resources

Waveforms 1 give an operational context to associated Domain resources. Similar to a personal computing application, a REDHAWK Waveform is launched when required and cleaned up when no longer useful. Much of this management is automated in REDHAWK and can be monitored easily.

The image at the start of this section provides two different examples of Waveforms (the logic of which is in the gray boxes). In each example, the black arrows indicate connections as well as the demarcation of processing stages in the Waveform.

A Waveform is not required to start or end with a connection to a Device or Service as shown in the examples. In fact, the the flow of a Waveform could just as easily setup some flow of data, pass it to an FPGA Service for higher-speed processing, retrieve the results, and continue processing for the final output to simply be available on a port when connected to by the user at runtime.

Waveforms really only contain one type of user-programmable entity: Components. The Waveform then describes the interconnections between these deployed components and any system resources using a variety of tools and facilities. These topics in more detail throughout this section.

Components

Components are transient entities: they exist for as long as required and are then released. The SCA specification states these are modules deployable by the Application Factory; a definition which provides for a reliable analogy: an operating system versus user’s applications.

The operating system remains running while the user launches office utilities, browsers, etc. to accomplish his or her tasks. When the work is finished, the applications are closed but the operating system remains. In REDHAWK terms, the individual user applications would be Components while the overall task would be the Waveform.

A task could re-use applications several times similar to a Waveform reusing Components.

Continuing with the analogy, a Waveform can implement any number of Components (up to system resource capabilities, of course). All allocation and configuration overrides are contained in the Waveform’s definition along with all connectivity (between Components and to Devices).

Another similarity to the analogy is how reusable the individual user applications are. With each being very specific to a function and yet basically generic, one ends up having many reusable modules but a more thread-heavy design. On the other hand, if the Components group sub-tasks together, the individual parts are less reusable but potentially much lighter-weight on embedded systems.

Some examples for Components are filters, multipliers, transfer functions, etc. Each could be a fairly abstract but complex function on its own once configured appropriately or very specialized and non-transportable. In any case, Components have Properties, Implementations, and Dependencies to support a variety of use cases.

Properties

To support reconfigurability and control, Components support user-defined properties including series (arrays) and structures. Each property can be any one of several different primitives such as integers or reals with unique IDs apart from the proper name. Components support the following property sub-types: allocate, configure, event, and message 2. In object-oriented terms, REDHAWK Properties become class members.

Implementations

A Component can have several implementations specified with each providing a separate source tree 3. Each implementation can specify different compiler executables and flags to support building for multiple architectures, etc. Component Implementations gain the most importance during the Waveform launching process by way of associating its OS and Processor dependencies with the properties of any available Executable Device 4.

Dependencies

Each Implementation has its own Dependencies list. Categorically, Component-level dependencies can be separated into architectural (operating system and processor), Property, and SoftPkg. All dependencies specified on the Component must be met by the an Executable Device when the parent Waveform is attempting to launch.

Judiciously choose Component dependencies when developing. Doing so will not arbitrarily limit the Waveform’s deployment options, especially if using Collocation.

Architectural

The operating system and processor dependency lists are user-specified fields. A starting list is provided though adding others is simply a matter of typing the choice into the placeholder.

These dependencies are matched as a logical OR for each. For example, if the Component’s processor dependency list contains x86 and x86_64, a Device will be found with processor_name matching either of those two values. Therefore the benefit of architectural dependencies is to make a Component reusable across several system architectures.

Property

Property dependencies, as the name suggests, cross-reference against Device Properties. These can follow a matching, allocation, or other mechanism. In all cases, the referenced Property must have its Kind marked as allocation.

The matching type will attempt to evaluate a logic EQUALS with the name-value pair if the named Property is found on a Device. It is a way to discover if a Device exists that already has the named property set to a particular value. It is not an attempt to modify the Device property; for that behavior, use allocation.

When allocation is selected, the associated Device will receive a call to allocate the name-value pair. Typically it can be an effective resource reservation mechanism in the overall system design 5.

The other type of dependency matching is open to being defined by the Device designer. Consider it the very customizable but loosely supported route.

SoftPkg

As of REDHAWK 1.9.0, SoftPkg (software package) dependencies have gained additional support. The concept behind a SoftPkg dependency is to deploy additional software with a Component (for example, a library) to the targeted Executable Device. It ensures the Device has the not only the software but also the correct version of software.

For example, a Component’s C++ implementation includes a header and links to a library for signal processing version 1.2, but the target Device only has 1.1 installed. A SoftPkg dependency will temporarily install the 1.2 library onto the destination and modify the system path to allow the Component to dynamically link against it.

Resource Connections

Accessing resources from a Waveform can take three forms: FindBy, External Ports, and UsesDevice relationships. Connections to resources ultimately resolve to Ports; some are intended for mass data transfer (BULKIO) while others are intended for asynchronous messaging and events.

FindBy

‘FindBy’ as seen in the IDE. Note the available options.

The FindBy block provides access to a variety of resources including Event Channels and Services 6 which are typically accessed by name. At deployment, the block resolves its connection to be of the appropriate Port type (if applicable).

External Ports

External Ports can be used to interconnect Waveforms together. These connections can be easily configured from the IDE in the Waveform’s properties, and the connection is manually established after deployment once both Waveforms have started by using the Python shell interface 7.

Because these connections are manually established, each is unmanaged by the Domain Manager. Implicitly then if a Waveform is released because resources are no longer available, any connected Waveform is not also automatically released since it is an unmanaged connection 8.

Usesdevice Relationship

The usesdevice relationship can be most easily understood as a Waveform dependency that applies to a Component’s Port(s). Established in the Waveform’s XML file, the Application Factory evaluates these dependencies separately from the Component’s own Dependencies 9.

The result of this dependency type being resolved is a connection between the associated Ports in addition to any other appropriate calls that would occur for resolving Component Dependencies (for example, allocation). This allows a usesdevice relationship to also allocate (setup) a Device before the Port association is established.

The usesdevice relationship permits the developer one more layer of control to ensure data flows between Device Managers and Waveforms in a very flexible way. For example, a Component can be deployed and executed on Device A but map a connection to Device B’s port(s) with the potential of each being on different Nodes across the Domain (network).

A common application of this is connecting FrontEnd Interface Devices (tuners, etc.) to Components that will be ingesting the data. For these cases, the REDHAWK 2.0 Waveform editor (in the IDE) provides for Use FrontEnd Tuner Device — a wizard which helps you configure the allocation properties associated with the Device before dropping the element into the Waveform and connecting it to the affected Componenet Ports.

Understanding a Launch

The Domain Manager’s Application Factory is responsible for arbitrating a Waveform’s launch. The overarching goals of the process are:

  • Resolve Component Dependencies Against Devices
  • Deploy Components to Targeted Devices
  • Resolve All Interconnections Including usesdevice Dependencies
  • Start the Assembly Controller

When a Waveform is launched, Component dependencies are checked against available resources. The Application Factory will search for a Executable Device that can support any one of the Component’s Implementations based on each set of dependencies.

If all dependencies are appropriately resolved for one of the available Component Implementations, the associated Component’s binary image is copied to the Executable Device to be executed remotely as a separate thread on that Device.

If all Components could be deployed, the interconnections are established (Ports, FindBy, and usesdevice), and the Assembly Controller is started. The designated Assembly Controller finishes the launching process by calling start on the downstream Components.

Load Balancing

REDHAWK provides a framework for highly flexible distributed application development by two major mechanisms. These mechanisms are the compartmentalizing a Component’s executable and establishing data transfers.

Recall that Components are small modules (programs) that can execute independently of one another, and using a Waveform, each can also be interconnected to build more complex logic using Ports (whether high-speed Ports such as BULKIO or asynchronous event channels). When that Waveform is launched, it is possible for each Component to be deployed across several different Executable Devices potentially separated by the underlying network connection.

Thanks to its SCA and CORBA underpinnings, data transfers (connections) in REDHAWK are sorted at deployment to either be local copies or network transfers. The decision for which is chosen is driven by whether or not the two ports exist on the same network connection.

Both features offer great flexibility load balancing all running applications but by default are decided automatically by the Application Factory. For load balancing then one must leverage one of two features: collocation or manual assignment.

Collocation

REDHAWK Waveforms have a deployment feature called Collocation. It allows the Waveform designer to specify Components that must be deployed together onto the same Executable Device.

This feature uses the superset of collocated Component dependencies to identify a target Executable Device. If any dependency fails in this set, the Waveform will not be launched.

One of the primary advantages to Collocation is that it still permits the Application Factory to automatically scan for any suitable Executable Device to host the Components. This can be useful if you know the Components need to process and transfer large amounts of data between each without much concern for where the processing actually takes place.

Manual Assignment

Another option is to define explicitly which Devices, by unique instance ID, must be used for deployment of a specific Component. In this case, the Application Factory’s scan-and-deploy mechanism is limited further by only looking for the specific Device. If the Device is unable to allocate and accept the Component, the Waveform launch will fail.

Manual assignment is specified when a Waveform is launched rather than through Components’s Dependencies or the Waveform’s usesdevice relationships. Its use case might be as simple as forcing collocation of Components in a one-off launch of a Waveform.


  1. Interchangeably referred to as an Application in the REDHAWK documentation. 
  2. These topics are covered in greater depth in a document titled: Property Types
  3. These separate source trees can be unified using operating system-level linking, if supported. 
  4. See the document titled: Device Managers
  5. For an excellent example, see the USRP UHD’s mechanism for implementing the Digital Tuner Frontend Interface. It uses unique IDs to permit Components to reserve one of the USRP UHD Device’s available tuners for control or pure-listener behaviors. 
  6. A name-unique entity instantiated in a Device Manager. 
  7. From the Python shell, see help(ossie.utils.redhawk) for more details. 
  8. One can observe these changes using the ODM and IDM Event Channels from a Python Shell to administer manually-connected Waveform relationships. 
  9. Previously one would have to create a gateway-like Component to capture and forward Device data. 

Recent Posts

Ready for an exciting change?

Work with US!