ADTF  3.18.2
uCOM Architecture

Micro Component Object Model (uCOM)

The Automotive Data and Time-Triggered Framework (ADTF) follows a strict object-oriented approach and supports a component-based procedure for the development of software. The implementation is based on the possibilities of C++ and relies largely on the principles and Software Template of a Component Object Model (COM). Here, ADTF limits itself to the essentials and implements these in the Micro Component Object Model (uCOM).

The essential statement of the Micro Component Object Model is that the components are binary compatible with one another and therefore the dependencies on the source code for the integration no longer exist. uCOM defines the path for how the developer requests and uses the objects encapsulated by a component and their open interfaces.

The approach addresses functions of the individual objects no longer as member functions of real classes, but rather abstracting these via clearly defined interfaces encapsulates the implementation of the individual software modules. A component demonstrates many parallels to classes—and actually, a component can also be implemented in form of a class. However, as the implementation is encapsulated behind the interfaces, a much more complex structure of classes and partial modules can be hiding behind this.

Based on the theoretical definition of components as abstraction of classes and modules, the Micro Component Model determines the type and manner for how components are used within the framework.

Interaction of components

A prerequisite for the development of more complex software systems is the interaction between individual components. The basis for this is the specification of a default interface that each component has to support within the framework in a certain way as an "interface contract". The default interface serves as the lowest common denominator for addressing all extended—i.e. all application-dependent—functions. Concretely this means that the default interface has to offer the opportunity to request the specific interfaces and to use them.

An additional task that must be taken care of via the basic interface is the control over the lifetime of an object. Objects instances are generated dynamically in the system, are referenced in random places via the public interfaces, and must be destroyed again in controlled fashion. The problems from the multiple use of the same instance are solved within the implementation via Reference counting provided by the uCOM. If the last caller releases the interface, then the instance can be destroyed (or destroy itself). This way, the generator of a concrete instance does not also have to be the destroyer of this instance.

Note
In C++, interfaces are realized via abstract base classes, methods have to be declared as pure virtual.

Within uCOM, the default interface (quasi-compatible with COM) is defined as follows by the IObject.

The central method of the IObject default interface is IObject::GetInterface. Via the unique identifier riid (Requested Interface Identifier) a special interface is requested. If the components support the interface, it is returned via o_pInterface. Usually, a reference counter is used to mark up the interface is used outside by another component. The main differences between the ADTF 2 and ADTF 3 is the separation of retrieving these interface (The ucom_cast<> in depth explanation) and the Reference counting provided by the uCOM itself. The developer of an interface decides either a reference counting is necessary to use or not. The GetInterface method is protected to another use outside the ucom_cast implementation.

IMyInterface* pInterface = ucom_cast<IMyInterface* >(pComponent);
if (pInterface)
{
// succeeded GetInterface call
}
object_ptr<cMyComponent> pComponent = make_object_ptr<cMyComponent>();
object_ptr<IMyInterface> pInterface = pComponent;
if (pInterface)
{
// succeeded GetInterface call and reference counter was increased
}

After the interface is no longer needed by the application and a reference counter was used a Unref call to the refernce counter is called. If necessary to destroy the instance it will be done through the automatic call of the method IObject::Destroy(). (See detailed information on Reference counting provided by the uCOM)

Plugin concept

In order to work around the weaknesses of the programming language C++ already mentioned, uCOM defines an uniform format for dynamically-loadable components. Insofar as the corresponding interfaces are adhered to, the framework can load any number of components at runtime and thus realize complex yet completely modular applications.

uCOM Plugins may contain any number of components. Components are addressed via unique names, but not via type definitions (independence from the source code).

Plugins are realized as dynamically-loadable libraries. Under Windows these are called Dynamic Link Libraries (DLLs) and under Linux Shared Objects. Even if the file extension of the library files is changed to .adtfplugin (adtf plugin library), these are, now as before, system-compatible modules.

uCOM plugins have to export the C functions UCOM_LoadPlugin3 and UCOM_UnloadPlugin3. These functions form the "DLL interface" and serve as the entry point in order to request the components implemented in the plugin and their interfaces. Class instances cannot be requested, all instances are created within the plugins.

Via the exported fucntion UCOM_LoadPlugin3 uCOM Plugins publish the IPlugin interface, via which the implementation of a class factory is to be achieved simultanously. Using the general interface IClassFactory and the associated function SC T.

Within the Plugin, individual objects can be generated. The destruction of the objects takes place, as described above, using Reference counting provided by the uCOM and using the object itself.

Components of a Plugin can implement as many interfaces as desired. The basis is always the default interface IObject in order to query the available interfaces in an uniform way.

References