Common classes

Common classes provide functions that may be helpful for programming. The PLCnext Technology-specific common classes are made available via the PLCnext Technology SDK. With the help of the SDK, it is possible to generate high-level-language programs in C++ for the PLCnext Technology framework. The SDK provides Arp firmware header files for this ("ARP SDK"). With the help of the ARP SDK, you can use common classes in your program. If you want to use a class, integrate it into your program via an #include command. Further information on the common classes and their applications is available directly in the code commentary. 

The useful common classes mentioned in the following sections are part of the Phoenix Contact SDK, for example. The classes are encapsulated in namespaces according to their subject areas. 

The Threading namespace

During threading, parts of a program are executed in parallel.

Risk of firmware instability due to high Linux priority

For threading in PLCnext Technology programs, always use value 0 for the Linux priority.

For threading under Linux in general, a priority value can be selected between 0 (none) and 99 (highest). Phoenix Contact recommends using priority 0 in order to not disturb the structure of the real-time threads. Otherwise, the stability of the firmware cannot be guaranteed. For performing time-critical tasks, programs in ESM tasks are intended.

The Threading namespace provides methods for separating a program into several strings for simultaneous execution, thus improving the performance of the overall system. Click on the corresponding class name to see the description:

CpuAffinityCpuAffinity

CpuAffinity is a bit mask in which one bit is available per processor core. The least significant bit represents processor core 1. If this bit is set, the scheduler may execute the thread on this processor core.

Several bits can be set simultaneously. In this case, the scheduler decides on which processor core the thread is to be started, and whether it can be executed in the runtime of another processor core.

If the value of the parameter is 0, the scheduler can execute the thread on any available processor cores.

ThreadThread

One instance of this class is used to manage one thread, respectively. You must specify the function or method that is to be executed in a thread during instantiation. If the Thread::Start method is called, the thread is executed.

The Thread class selects a low priority as standard. Phoenix Contact recommends retaining this priority in order not to endanger the priority structure of the various firmware and operating system tasks.

WorkerThreadWorkerThread

In contrast to the Thread class, an instance of the WorkerThread class is executed cyclically, as soon as the WorkerThread::Start method is executed. You can define cyclic execution of the thread via the idletime parameter. The value is specified in milliseconds (ms).

ThreadSettingsThreadSettings

The ThreadSettings class is an auxiliary class for passing the following thread parameters to a constructor of the Thread class:

  • Name
  • Priority
  • CPU affinity (which CPU has been released for the execution of the task)
  • Stack size (byte size)

MutexMutex

Using the Mutex class, you can prevent data of several threads being changed simultaneously. The Mutex class instances can have one of these statuses:

  • Locked 
  • Unlocked 

Once the Mutex:Lock method has been performed, i.e., the call from the method returns, the data is protected against modification by other threads. This status is retained until the instance calls the Unlock() command, therefore rescinding the locked status. A call is blocked until the thread which is in the Lock state is released again. To prevent a "deadlock", i.e., a status in which a locked thread cannot be unlocked again, you can use the LockGuard class. This class automates Lock and Unlock of a Mutex instance.

The Ipc namespace

The Ipc namespace (short for "inter-process communication") encapsulates classes which can be used to enable the communication between various processes on the same controller.

SemaphoreSemaphore

Using the Semaphore class, semaphores are implemented in order to synchronize processes or threads. In principle, semaphores are integer counters. If one of the various Wait methods is called, the internal counter is lowered by one. If the current value of the counter is zero when a Wait method is called, the call is blocked until a different thread on the same semaphore instance calls the Post method (the Post method increases the internal counter).

MessageQueueMessageQueue

Using the MessageQueue class, data can be exchanged between processes in the form of messages. The names of MessageQueue instances must begin with an "/" because otherwise, the call from the constructor will lead to an exception. The name of a queue corresponds to the file path in Linux.

The Chrono namespace

The Chrono namespace contains classes and functions with which the temporal sequences within an application can be controlled and influenced. This includes the high-resolution measurement of time elapsed so far, and also the triggering of actions after a predetermined period of time.

TimerTimer

The Timer class is a high-resolution chronometer for interval-based execution of methods. Instances of this class are used to execute one or more methods periodically at a defined interval. The Timer class calculates the next point in time at which the method is to be called. You only have to implement the methods that are to be called via the Timer definition.

The Io namespace

The Io namespace encapsulates all functions necessary for working with files and folders within the file system of the underlying operating system.

FileStreamFileStream

The FileStream class is for stream-based editing (opening, writing, reading) of files. The various values in the class define, for example, whether a file is to be overwritten, an already existing file is to be opened, or a new file is to be created.

The Net namespace

The Net namespace encapsulates all classes and functions that enable network-based communication between processes on the same controller or separate controllers.

For processes that run on the same controller, preferably use the functions from the Ipc namespace (see above).

SocketSocket

The Socket class is an interface for Ethernet-based communication. Use instances of this class to establish an Ethernet-to-peer connection. Currently, the UPD and TCP protocols (IPv4) and TLS (TlsSocket class) are supported.

The Runtime namespace

The Runtime namespace encapsulates functions for the manipulation of individual processes that are managed by the Arp firmware.

SharedLibrarySharedLibrary

Using the SharedLibrary class, shared libraries (.so files) are dynamically published in applications during runtime, or reloaded. If a library is successfully reloaded with the SharedLibrary::Load method, the symbols contained (global variables, classes, methods, functions, etc.) are then known in the current program.

The memory area can be requested with GetFunctionAddress in order for the functions of the library to be used in the program currently running.

ProcessProcess

The Process class is a high-level API for creating and managing new processes.

Logging (Output.log)

PLCnext Technology provides a log file on the controller file system in which information on the system behavior of the PLCnext Technology firmware, warnings, error messages, and debugging messages are logged. You will therefore find valuable information that can help you in finding the cause of problems. 

Use a suitable SFTP client software for this, e.g., WinSCP.

Template LoggableTemplate Loggable

You can include theTemplate Loggable<> template class to automatically apply a tag to log messages. A tag can be used to determine from which component, program or other code element the message originates.

To use this class, you have to include (#include) the corresponding header file (.hpp):

– LoggableArp/System/Commons/Logging.h

PLCnext CLI adds the required lines to the program and component.

The following log levels are supported. For each log level, a suitable method can be called.

  • Info
  • Warning
  • Error
  • Fatal

Example call:

log.info ("Info!");

Static callStatic call

Alternatively, you can also perform logging without the Loggable class. Messages can be written without creating a special logger using the root logger with the static Log class. The root tag is assigned to the message. The source of the message is thus not visible in the log file.

Log::Error ("Error!");

It is also possible to pass and format variables. Placeholders in the form {x} are used for the variables; where x is the index of the variable.

("Variable a={0} b={1}", a, b)

Diagnostic log file Diagnostic log file

The Output.log diagnostic log file contains status information, warnings, error messages, and debugging messages.

See the output.log topic for more information.

 

 


• Published/reviewed: 2024-09-24   ☀  Revision 073 •