Device Managers

Figure shows a Node (Device Manager) as a smart phone with some example capabilities.
Figure shows a Node (Device Manager) as a smart phone with some example capabilities.

Device Managers (Nodes) group system resources for availability throughout a given Domain. These resources can be described by two very different categories of entities: Devices and Services. Moreover, Devices have two additional specialized subclasses, Loadable and Executable. In total, a Node can contain 4 different abstractions to manage and provide resources.

Devices and Services are very different in terms of out-of-the-box capabilities. Devices for example are rigorously defined by the SCA to be started, stopped, allocated, etc. A Service on the other hand does not, and cannot, do any of those tasks. It simply exists and performs whatever custom task the Developer creates.

Some examples are provided above. Executable Devices receive and execute Component software, if possible. A regular Device however might simply be allocated against for the sake of controlling its associated hardware. Nothing would ever allocate (reserve) the precision clock, and it would (hopefully) not stop and restart. Thus, a precision clock would be provided as a Service.

Devices

Header is a macro photo of a light house's rotor -- only provided for style.
Header is a macro photo of a light house’s rotor — only provided for style.

Per the underlying SCA specification, Devices are intended to be an abstraction of some hardware by defining its capabilities, attributes, and interfaces. Respectively, Devices are defined by three XML files: SPD 1, PRF 2, and SCD 3.

Devices can be represented as three different base classes though the differences between the three classes can be rather semantic. The order of inheritance is from Device to Loadable Device then to Executable Device. Under most circumstances the base Device is sufficient.

Devices extend the Component class by adding execution. Similarly, a Device can have any number of Ports for connectivity as well as any number of (potentially) custom-structured Properties to support execution, configuration, and allocation. Most often, this type would be implemented for Devices acting as front-ends to lower-level system drivers and libraries.

Loadable Devices gain load and unload calls with the anticipation that the Device would be given a data file when required thus consuming some resources. When not in use, the Device would be directed to unload the file (release the resource). These load and unload calls typically correlate to the associated Device Manager’s file system.

Executable Devices also gain an execute call which occurs after a Waveform successfully applies dependencies against the Device. This type gains that call expressly because it is the only Device type expected to receive, fork, and actually run Component software when a Waveform is launched. Usually the included GPP device is a sufficient stand-in for any onboard Executable Device since all of its properties can be changed to match a given CPU architecture.

Services

Stylish header is a close-up of the Scottish Parliament building in Edinburgh
Stylish header is a close-up of the Scottish Parliament building in Edinburgh

Compared to other REDHAWK entities, Services are very loosely defined — to the point of almost being a blank slate. The online documentation only states it is, "software available at Device Manager startup," which does not do the nuances of Services any justice. Some other key points of Services are:

  • Services have no Ports; other entities cannot connect directly to a Service. Instead a connection to a Service requires using FindBy in a Node or Waveform.
  • A Service has no Properties. Thus it is neither configurable nor allocable by dependencies. And consequently, it also cannot be adjusted from the Node containing it making the Service essentially immutable.
  • Services provide 4 exactly one IDL-defined interface. Frontend Interfaces contains several possible interface choices 5. All transfers are pull-oriented.
  • Services do not have start or stop methods or a serviceFunction. Each is created when its Node launches, and the rest is up to the developer.
  • Since the Service has no pre-defined run loop, a developer must create their own to retrieve and make available any data on the Service’s interface.
  • It is described by the SPD and SCD XML files providing information about its base name and the interface it provides.
  • The Service’s interface is public throughout the Domain as found by its instance name.

A common use of a Service is to provide a gateway between Domains. The designer would implement the proprietary connection within the Service and use its interface to provide asynchronous control and feedback to the system.

Another common use is making available a precision timer to the system. Because transfers are pull-oriented, users of the Service receive the freshest-possible data based on their own cycle.

Because Services are found by their instance names, one must be careful when deploying Services in Nodes to ensure each instance name is unique among all Nodes. Failing to do so results in a registration error when the Node attempts to announce the Service’s instance name to the Domain Manager.

Granularity Example

Designing a Service rarely includes a question on granularity. Services are name-unique in a Domain so whatever it represents must be found and used by that unique name. Furthermore since Services have no properties and are neither allocated, configured, loaded, or executed, the underlying granularity has nearly no impact on the Device Manager or the Application Factory.

A Device design, however, broaches several design questions where granularity can potentially have a large impact. In practical use, a given Device could represent a whole class of hardware capabilities or an individual capability. One example is how to represent a multi-channel radio.

Is it more sensible to make the Device be a controller of a single channel (for example, an API) or the whole interface to the radio equipment (for example, a driver)?

Case 1: Create 1 Device and copy it.

Writing a single Device to represent a channel and then replicating that Device N times in a Device Manager is certainly an object-oriented approach. The task of writing the code for that Device would (probably) be simplified since the amount of internal arbitration would be reduced since that responsibility would be entirely off-loaded to the REDHAWK Application Factory. While this may seem like a fantastic path to rapid development, let us examine the choice further.

First, each Device forks into its own thread when launched from an associated Device Manager. If the system cannot gracefully handle several concurrent threads, representing each channel as a Device will prove unfeasible as the number of channels increases. So while the Device is modular and individually re-usable, it (may) not scale well against CPU architectures.

Second, when the Application Factory searches for dependencies it scans the Domain for all Device Managers to locate those resources. This search requires XML parsing. Since each channel is an individual copy of the same Device XML, the resulting Device Manager’s XML grows to cover N copies of those underlying Device attributes and properties. As the number of channels increases, the resulting waveform deployment time also increases.

Case 2: Create 1 Device to manage the whole interface to multi-interface equipment.

The alternative case is to design a Device that detects the number of channels and then scales its interfaces accordingly with controller and listener identifiers 6. In this case the Device would represent the whole interface to the radio equipment. And while the detect-and-arbitrate design requires more effort up front, the designer also gains better control over how the design scales to different architectures.

Since the design is now a single Device, N channels does not necessarily require N threads. This allows the designer to ensure a Device scales down to lighter-weight embedded platforms more easily.

If the number of channels were to ever change, the auto-detection semantic allows the Device Manager to scale without having to modify the underlying XML. And depending on the how the Device manages the auto-detection, the Device Manager may not even require a restart.

The impact on the Application Factory is similar. As it scans the XML, it finds one copy of the allocable properties. It then calls allocate to see if the Device has any channel availability for the associated property-value pairs. This change decreases load from the Domain’s perspective since it is now parsing much less XML, and the Device is handling the required processing for analyzing the property-value pairs.


  1. Software Package Descriptor 
  2. Properties File 
  3. Software Component Descriptor 
  4. While not visible in the IDE, the interface is a Provides port type making it pull-oriented to any users (i.e., Uses port type). 
  5. Some examples include Analog and Digital Tuners as well as GPS. See the .idl files at frontendInterfaces for some useful examples. 
  6. See the USRP UHD Device for an example on how to arbitrate through Allocation properties. 

Recent Posts

Ready for an exciting change?

Work with US!