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:
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.
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.
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).
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)
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.
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).
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.
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.
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).
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.
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.
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):
– Loggable
: Arp/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!");
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.