TestAndSet

TestAndSet 1:

Mit der Funktion können Sie ein Flag prüfen und setzen, ohne dass dies unterbrochen werden kann. Dadurch können Datenzugriffe synchronisiert werden. Mit TestAndSet kann die Funktionsweise eines Semaphors erreicht werden.

Bei erfolgreichem Funktionsaufruf liefert die Funktion TRUE zurück und auf die gewünschten Daten darf zugegriffen werden. Bei erfolglosem Funktionsaufruf liefert die Funktion FALSE zurück und auf die gewünschten Daten darf nicht zugegriffen werden. In diesem Fall muss applikativ eine Alternativbehandlung vorgesehen werden.

TestAndSet 2: Ein-/Ausgänge

VAR_IN_OUT
    Flag : BOOL; (* Flag to check if TRUE or FALSE *)
END_VAR

Name

Typ

Beschreibung

Flag 

BOOL

Boolesches Flag, das geprüft wird

  • war es FALSE, dann war das Flag frei und wird gesetzt (blockiert von nun an), die Funktion liefert TRUE
  • war es TRUE, dann war das Flag bereits belegt (blockiert), die Funktion liefert FALSE

Beispiel

VAR_GLOBAL
    bGlobalTestFlag : BOOL;
END_VAR
VAR
    nLocalBlockedCounter : DINT;
END_VAR
IF TestAndSet(GVL.bGlobalTestFlag) THEN
    (* bGlobalTestFlag was FALSE, nobody was blocking, NOW
    bGlobalTestFlag is set to TRUE and blocking others *)
    
    (* ... *)
    
    (* remove blocking by resetting the flag *) 
    GVL.bGlobalTestFlag := FALSE;
ELSE
    (* bGlobalTestFlag was TRUE, somebody is blocking *)
    nLocalBlockedCounter := nLocalBlockedCounter + 1;
    
    (* ... *)
END_IF

NEGATIV-Beispiel

Vorsicht ist bei einer weiteren Kapselung, z. B. in einem Funktionsbaustein, geboten, da dies die gewünschte atomare Operation zunichtemachen kann. Eine sichere Synchronisierung von Datenzugriffen kann dann nicht mehr erfolgen. Im Folgenden ist ein NEGATIV-Beispiel eingefügt, welches zeigt, wie die Funktion NICHT verwendet werden darf. Sollten bei dieser Implementierung zwei Kontexte zugleich Zugriff erbitten, so könnten beide davon ausgehen, dass der Zugriff erlaubt ist und es würde ein zeitgleicher, ungesicherter Zugriff auf die Daten stattfinden.

FUNCTION_BLOCK FB_MyGlobalLock
VAR_INPUT
    bLock    : BOOL; // set TRUE to lock & set FALSE to unlock
END_VAR
VAR_OUTPUT
    bLocked : BOOL;
END_VAR

IF bLock THEN
    TestAndSet(bLocked);
ELSE // unlock
    bLocked := FALSE;
END_IF
IF NOT GVL.fbGlobalLock.bLocked THEN
    GVL.fbGlobalLock(bLock := TRUE);
    
    (* ... *)
    
    GVL.fbGlobalLock(bLock := FALSE);
END_IF
TestAndSet 3:

Mit dem Funktionsbaustein FB_IecCriticalSection wird die Verwendung von kritischen Bereichen als alternatives Mutex-Verfahren angeboten.

Voraussetzungen

Entwicklungsumgebung

Zielplattform

Einzubindende SPS-Bibliotheken (Kategoriegruppe)

TwinCAT v3.1.0

PC oder CX (x86, x64, ARM)

Tc2_System (System)