Global Function Blocks in PLCnext Engineer
This topic contains the following sections:
- General information on global function blocks
- Display of global function blocks in the 'PLCnext' PLANT node
- Protecting concurrent access to shared data with Mutex and Semaphore
- Mutex
- Semaphore
General information on global function blocks
PLCnext Engineer allows to create global function block instances. Global means, the same instance of the function block can be called from different program POUs, i.e., the function block can be accessed from multiple program POUs within the same project.
A function block with the 'Usage' 'External' in the variables table of the calling POU or the 'Usage' 'Global' in the Data List generates a global function block. (Declaring an external function block in the variables table of a POU leads to an automatically generated global function block in the Data List.)
The following applies for global function blocks:
- Global SFC function blocks are supported. The user is responsible for a careful design, so that synchronization works well (see the section "Protecting concurrent access to shared data with Mutex and Semaphore" below).
- EN/ENO for Global SFC function blocks is supported. The user is responsible for a careful design, so that synchronization works well.
- Nested local and global function blocks are supported. The user is responsible for a careful design, so that synchronization works well.
- Global variables in global function blocks are supported.
- Calling a global function block out of a (local or global) function block method is supported.
- Global function blocks can be organized in namespaces.
- The online values of global function blocks are synchronized according to the Task and Events configuration.
- A safety-related resource does not support global function blocks.
- A global function block does not have an HMI tag in the Data List.
- Global function blocks are not available in the GDS Port List.
- A global function block can not be connected to Process Data Items.
- Refactoring for a global function block instance collects all external variables and all function block calls.
- A compiler warning is issued in the Error List in the Messages window if a global function block is used in several tasks.
- A compiler error is issued in the Error List in the Messages window if a global function block contains instance variables.
Display of global function blocks in the 'PLCnext' PLANT node
Global function blocks are displayed in the 'PLCnext' PLANT node with the overlay icon .
Protecting concurrent access to shared data with Mutex and Semaphore
Global function blocks can be called by several tasks at the same time. Without synchronization of the concurrent accesses, race conditions or inconsistent data may occur. For example, a global function block for a motor controller is used by two tasks: Task A changes the speed to 100 rpm and task B changes the speed to 50 rpm at the same time. This can lead to data loss or an inconsistent state. In order to avoid this, synchronization techniques such as mutex and semaphore are used.
In general, a mutex and a semaphore are both synchronization mechanisms that are used for managing concurrent access to shared data. Mutex (short for "mutual exclusion") is a locking mechanism that ensures that only one task can access a resource at a time. A semaphore is a signaling mechanism that controls how many tasks can access a resource. The semaphore counts the number of processes that have access to the shared data.
Mutex vs. Semaphore
Feature | Mutex | Semaphore |
---|---|---|
Purpose | Mutual exclusion (only 1 task) | Resource counting or signaling |
Ownership | Only the task that locked it can unlock | Only a task that acquires the semaphore can release it |
Use case | Protect a shared resource | Coordinate access to multiple resources or signal between tasks |
Blocking? | Yes, if already locked | Depends on value (blocks if current count > maximum count) |
Mutex:
Counting Semaphore:
Mutex
To ensure that only one task can access the shared data at a time, a mutex is used. The mutex is a locking mechanism that:
- Prevents simultaneous access: Ensures that only one task can execute the code between the synchronization methods at a time.
- Avoids race conditions: Protects against unpredictable behavior (unpredictable values) due to concurrent access.
- Ensures data consistency.
How a Mutex works
As mentioned above, the mutex acts as a locking mechanism for tasks that use shared data. A mutex has a locked and an unlocked status. When a task wants to access shared data, it must first acquire the mutex. If the mutex is not locked by any other task, the task locks the mutex and continues executing. If the mutex is already locked by another task, the requesting task waits for the mutex to be unlocked. The task will be blocked until the mutex is released. Tasks that are in the waiting state are added to the mutex queue. After completing the operation on the shared data, the task releases the mutex (unlocks it), allowing other tasks to acquire it and access the shared data.
Note
In case of a mutex lock, a task watchdog can occur. It is therefore recommended to use a TRYLOCK method as follows instead of a LOCK method (see also the following table). IF myMX.TRYLOCK() // critical section myMX.UNLOCK() END_IF |
Implementation of a Mutex in PLCnext Engineer
For synchronizing the concurrent accesses to shared data in PLCnext Engineer, the MUTEX object-oriented function block is available (contained in the 'IEC 61131-3 | Functions & Function Blocks | Syncronization of Concurrent Execution' category in the COMPONENTS). This function block provides the following methods that are used for interacting with a mutex:
Function block method | Behavior | |
---|---|---|
LOCK | Locks the mutex (becomes the owner of the mutex). If the mutex is already locked by another task, the task will wait (block) until it's available (unlocked by another task).
|
|
UNLOCK | Unlocks the mutex, allowing the next waiting task to become the owner of the mutex (to lock the mutex).Must always be called after a successful TRYLOCK (return value TRUE).
|
|
TRYLOCK | Tries to lock the mutex (to become the owner of the mutex). It checks if the mutex is available:
|
|
IS_ENTERED | Checks whether the current task holds the lock on the specified mutex.
|
Example of a Mutex in ST
In the following example, the global function block FB_counter uses a mutex to protect the access to the shared variable internalCounter. An instance of FB_counter is used in the programs MyProgramA and MyProgramB. MyProgramA is called from TaskA and MyProgramB from TaskB. With help of the mutex, it is ensured that only one call can update (increment) the internalCounter at a time. Once the counter is incremented, the mutex is unlocked, allowing the next waiting task to access the shared variable.
Further Info
See the topic "Methods of FBs in PLCnext Engineer" how to use FB methods. |
Semaphore
A semaphore is a synchronization mechanism that allows a specified number of tasks to access a resource. It's like a counter that counts how many tasks can access a resource at the same time. The initial value of the semaphore counter is the number of resource accesses that will be allowed immediately (default value is 0). The maximum value of the counter is the highest count the semaphore can reach (specified with the variable MaximumCount of the SEMA function block; see below). That is, the total number of resources that will be granted concurrent access.
Implementation of a Semaphore in PLCnext Engineer
To limit the number of concurrent tasks accessing a specific resource in PLCnext Engineer, the SEMA object-oriented function block is available (contained in the 'IEC 61131-3 | Functions & Function Blocks | Syncronization of Concurrent Execution' category in the COMPONENTS). This function block provides the methods described in the following table and an initial value that are used for interacting with a semaphore.
The initial value is the initial number of resources that can be accessed by the tasks. Counting starts at 0. The MaximumCount value provided as INT variable by the function block specifies the maximum number of times the resource can be accessed simultaneously (default value is 0). If this value is reached, the semaphore blocks the access to the resource until another task releases the semaphore. For example, a semaphore with a MaximumCount value of two can handle up to three concurrent accesses.
Note
In case of a semaphore acquire, a task watchdog can occur. It is therefore recommended to use a TRY_ACQUIRE method as follows instead of an ACQUIRE method (see also the following table). IF TRY_ACQUIRE // critical section RELEASE END_IF |
Function block method | Behavior | |
---|---|---|
ACQUIRE | Tries to get access to the resource.
|
|
RELEASE | Releases (frees) the previously accessed resource. This allows other tasks to acquire it later. | |
TRY_ACQUIRE | Tries to get access to the resource without waiting (blocking).
|
Example of a semaphore in ST
Let us assume that there are three tasks (Task1, Task2, and Task3) that want to access the shared variable sharedResource at a time. However, only two tasks at a time will be granted access and the next task has to wait until the resource gets available again. The maximum number of simultaneous tasks is specified with the semaphore counter (variable MaximumCount := INT#2; INT variable of the SEMA function block). If the counter is less than two, a task can acquire the semaphore and proceed to access the resource. If the counter is already two, the task must wait until the semaphore counter is less than two.