This site uses cookies for functional purposes. To continue please read and agree to our Data Privacy.

By closing this message, you consent to our use of cookies on this device.

The basic integration of a component into PLCnext is implemented by means of derivation from the ComponentBase class or via the IComponent interface. There are specialized components for various purposes. These specializations are performed by implementing additional interfaces that are described in the following subchapters. To use the classes, you have to include („#include“) the corresponding header files (.hpp).

  • „IComponent“: Arp/System/Acf/IComponent.hpp
  • „ComponentBase“: Arp/System/Afc/ComponentBase.hpp

The following IComponent operations are called up for each component by the PLM:

  • void Initialize(void)
  • void SubscribeServices(void)
  • void LoadSettings(const string & settingsPath)
  • void SetupSettings(void)
  • void PublishServices(void)

In the second phase, the project configuration is loaded and set up. If an exception occurs here, the project configuration is unloaded again and the controller starts with an empty configuration. The start operation of the components that implement the IControllerComponent is called up. The system manager calls up the following IComponent operations:

  • void LoadConfig(void)
  • void SetupConfig(void)


Initialization of the components (instance) is done by means of the following functions. These have to be implemented in the component class. For each instantiated component, the PLCnext firmware first calls up the following function:

virtual void Initialize(void);


Resources that have been allocated/initiated in „Initialize()“ have to be enabled in „Dispose()“. Thereafter, the firmware calls up the following function for each instantiated component. In this function, a component can obtain RSC services that have already been registered.

virtual void SubscribeServices(void);


Subsequently, the following function is called up. The „settingsPath“ for the respective component (instance) can be provided in the *.acf.config file. The format and content of this configuration file have to be specified by the respective component (type). The PLCnext Technology firmware does not make any assumptions about this.

virtual void LoadSettings(const String& settingsPath);


After the „settingsPath“ has been announced, the settings can be applied. The following function is used for that:

virtual void SetupSettings(void);


The PLM does not call up the „PublishServices“ function. Creation and registration of RSC services are done by the core components only:

virtual void PublishServices(void);


When the project is subsequently loaded, the following functions are called up:

virtual void LoadConfig(void);
virtual void SetupConfig(void);


The configuration of the components is reset with the following function:

virtual void ResetConfig(void);

The interface is identical for the user program and the internal user component, it is simply called up at different times. The system manager manages components that are available provided by user programs. The SystemManager configures these in a file referenced by „/opt/plcnext/projects/Default/Plc/Plm/Plm.acf.config“.


A component is stopped after the following function is called up, that is the counterpart to SetupSettings() and LoadSettings():

virtual void Dispose(void);

IProgramComponent and IProgramProvider

A component that can instantiate user programs is derived from „IProgramComponent“.

To use the classes, you have to include („#include“) the corresponding header files (.hpp).

  • „IProgramComponent“: Arp/Plc/Esm/IProgramComponent.hpp
  • „IProgramProvider“: Arp/Plc/Esm/IProgramProvider.hpp

With this, you implement the following function:

IProgramProvider* GetProgramProvider(void);

The ProgramProvider in turn makes the following function available for instantiating programs. The PLCnext Technology firmware calls up this function when loading the PLC program:

IProgram* CreateProgram(const String& programName,const String& programType);

In the process, the following parameters are transferred as defined in the *.esm.config files:

programName Instance name of the program
The instance name is configured in the task editor of PC Worx Engineer or manually by means of the *.esm.config file.
programType Class name of the program
Which programs (type) a component (type) can generate are described in *.compmeta and *.progmeta files for the respective component.

The Eclipse® add-in creates such a component class that already implements an IProgramProvider and a user program class.
If a component class is to be able to instantiate several program classes, the following steps are necessary:

  1. Create the class (.h, .c)
  2. For each program class, create a *.progmeta file.
  3. Integrate this into the *.compmeta file of the component.
  4. Supplement the program classes in the „CreateProgram()“ function.

IProgram or ProgramBase

An instantiated user program implements the „IProgram“ interface. As a result, a constructor to which the instance name is transferred and the „Execute()“ function that is called up by the ESM task during each pass are available. The Eclipse® add-in creates such a user program class that inherits the „IProgram“ interface by means of derivation from the „ProgramBase“ base class. Additionally, the „ProgramBase“ base class provides the „AddPortInfo()“ function. This makes it possible to make the addresses of the IN and OUT ports known to the GDS (Global Data Space) in the constructor.
To use the classes, you have to include („#include“) the corresponding header files (.hpp).

  • „IProgram“: Arp/Plc/Esm/IProgram.hpp
  • „ProgramBase“: Arp/Plc/Esm/ProgramBase.hpp
class ProgramBase : public IProgram
public: // construction/destruction
    ProgramBase(const String& programName);
    virtual ~ProgramBase(void) = default;

public: // IProgram implementation
    const String&   GetFullName(void)const override;
    bool            GetPortInfo(const String& portName, PortInfo& portInfo)const override;
    void            SetInitialValues(void) override;

public: // abstract IProgram operations
    virtual void    Execute(void) = 0;

protected: // operations
    template<class T>
    void    AddPortInfo(const String& portName, T& portValue);


An internal user component can need own lower-priority threads to perform longer tasks outside of the ESM task. To this end, the internal user component can implement the „IControllerComponent“ interface in addition to „IComponent“.

The „IControllerComponent“ defines the following two functions:

void Start (void);
void Stop (void);

If the component is managed by the PLC Manager:

  • During cold and warm start of the PLC application, the „Start()“ function is called up after all program objects of the component have been generated. This is an ideal time to start own, lower-priority threads to which the programs delegate tasks.
  • The „Stop()“ function is called up when the PLC application is stopped, before the programs are destroyed. At this point, the created threads can be destroyed again.

To use the class, you have to include („#include“) the corresponding header file (.hpp). Both components and programs can be derived from this template class.

  • „IProgram“: Arp/System/Acf/IControllerComponent.hpp

Note: If you use the Eclipse® add-in, it creates the following functions with a functional implementation. In many cases, that is sufficient. If you have special requirements that go beyond this, the following descriptions will help you understand the functions.

Each class is defined in an own header file (*.hpp). To use the class, you have to include it („#include“).

  • „ILibrary“: Arp/System/Acf/ILibrary.hpp
  • „LibraryBase“: Arp/System/Acf/LibraryBase.hpp

In a shared object, there can be exactly one library class (Singleton pattern). The PLCnext firmware initializes the *.so after it has been loaded, by calling up the following function:

extern "C" ARP_CXX_SYMBOL_EXPORT void DynamicLibrary_Main (AppDomain& appDomain);

The PLCnext firmware queries the library object as follows:

extern "C" ARP_CXX_SYMBOL_EXPORT ILibrary* DynamicLibrary_GetInstance(void);

The library object implements the “ILibrary” interface by deriving it from the “LibraryBase” class. These in turn implements the following function in particular:

IComponentFactory& ILibrary::GetComponentFactory(void);

The PLCnext firmware can thus create instances of the components when loading the PLC program.

ILibrary::getComponentFactory() .CreateComponent(IApplication& application, const String&componentType, const String&componentName);

The component instances that the PLCnext Technology firmware creates is defined in the *.acf.config files.
The following parameters are transferred in the process:

componentType Class name of the component
Which components (type) a library can generate are described in in *.libmeta and *.compmeta files for the respective library, in addition to the implementation.
componentName Instance name of the component
This is automatically configured in PC Worx Engineer during instantiation of programs, or manually by means of the *.acf.config file.

AppDomain and IApplication

If you use the Eclipse® add-in, the required header files are included automatically.

  • “AppDomain”: Arp/System/Core/AppDomain.hpp
  • “IApplication”: Arp/System/Acf/IApplication.hpp

The PLCnext Technology firmware is distributed among several operating system processes.


An “AppDomain” represents such an operating system process. If a library is to be used in several processes, the Singleton implementation is performed for each process. To this end, the “AppDomain” class is used. Since the PLCnext Technology firmware for user components use the same mechanism for instantiation, initialization and administration as for core components, the “AppDomain” is used here as well.

The operating system is represented by the “IApplication” interface.

Page 1 of 3

We have 39 guests and no members online