Propagazione costante
Con il CODESYS Static Analysis versione V5.0.0.0, l'analisi del codice si basa sulla propagazione costante. I risultati della propagazione costante vengono utilizzati per vari controlli. Ad esempio, controlla se i puntatori non sono uguali a 0 o se gli indici dell'array non rientrano nell'intervallo valido.
Puoi supportare efficacemente l'analisi statica semplicemente conoscendo come funziona questa analisi e quali sono i suoi limiti.
Propagazione costante
L'analisi statica tenta di determinare il valore di una variabile in base al suo utilizzo.
PROGRAM PLC_PRG //Declaration VAR x: INT; bTest: BOOL; END_VAR
//Implementation x := 99; IF x < 100 THEN bTest := TRUE; END_IF
Nell'implementazione della riga 1 la propagazione costante registra il valore 99
per la variabile x
utilizzare questo valore per ulteriori analisi. L'analisi riconosce quindi l'espressione seguente IF
-Costante di istruzione TRUE
È.
Propagazione costante eseguita localmente
Un valore viene determinato solo localmente nel blocco funzione. È irrilevante il modo in cui viene passato un input. Anche i risultati delle chiamate di funzione sono irrilevanti.
FUNCTION Func : BOOL //Declaration VAR_INPUT bText : BOOL; END_VAR
//Implementation IF bTest THEN Func := OtherFunc(TRUE); END_IF
Anche se il parametro bTest
è impostato per TRUE
ad ogni chiamata ciò non ha alcun effetto sulla propagazione costante. Anche se OtherFunc(TRUE)
ritorna sempre TRUE
, questo non ha alcun effetto sulla propagazione costante.
Solo le variabili temporanee hanno valori iniziali.
Le variabili locali statiche nei programmi e nei blocchi funzione non hanno alcun valore iniziale presunto. Le variabili mantengono i valori dell'ultima chiamata e quindi in linea di principio possono essere "qualsiasi cosa".
Le variabili locali nelle funzioni e le variabili temporanee hanno un valore iniziale ad ogni chiamata. La propagazione costante viene calcolata con questo valore iniziale.
PROGRAM PLC_PRG //Declaration VAR x: INT := 6; bTest: BOOL; END_VAR VAR_TEMP y : INT := 8; END_VAR
bText := x < y;
La variabile y
viene eseguito ogni volta PLC_PRG
hanno il valore 8. La variabile x
, tuttavia, non necessariamente. Pertanto, la propagazione costante viene utilizzata solo per y
assumere un valore, ma non per x
.
Si consiglia di dichiarare variabili che vengono sempre scritte prima e poi lette come variabili temporanee.
La propagazione costante determina gli intervalli di valori per i tipi di dati numerici.
Per ridurre la complessità, per ciascuna variabile viene determinato un intervallo di valori con limiti superiore e inferiore.
PROGRAM PLC_PRG VAR x: INT := 6; bTest: BOOL; y : INT; END_VAR
//Implementation IF bTest THEN x := 1; ELSSE x := 100; END_IF IF x = 77 THEN y := 13; END_IF
Ecco l'intervallo di valori [1..100]
è determinato per la variabile x
. Di conseguenza, alla riga 7, il confronto x = 77
non è riconosciuto come espressione costante perché 77
rientra nell'intervallo di valori.
Le espressioni complesse ricorrenti non vengono riconosciute come la stessa variabile.
Alle espressioni complesse potrebbe non essere assegnato un valore. Se tali espressioni ricorrono più volte, è utile introdurre una variabile ausiliaria.
PROGRAM PLC_PRG VAR x: DINT; py : POINTER TO INT; y : INT; testArray : ARRAY [0..4] OF DINT; END_VAR
//Implementation IF py^ >= 0 AND py^<= 4 THEN x := testArray[py^]; END_IF y := py^; IF y <= 0 AND y <=4 THEN x := testArray[y]; END_IF
Alla riga 2 viene emesso un errore per un possibile accesso tramite puntatore ad un valore, sebbene venga controllata l'area puntata dal puntatore. Se il valore viene prima copiato in una variabile locale e il suo intervallo viene controllato, la propagazione costante può determinare l'intervallo di valori per quella variabile e consentire l'accesso all'array alla riga 7.
Ramificazione
Per quanto riguarda la ramificazione, i singoli rami vengono calcolati separatamente. Gli intervalli di valori dei singoli intervalli vengono quindi combinati per formare un nuovo intervallo di valori.
//Implementation IF func(TRUE) THEN x := 1; ELSE x := 10; END_IF IF func(FALSE) THEN y := x; ELSE Y := 2*x; END_IF
Sulla linea 6, x
ha la portata [1..10]
. Dopo la linea 11, y
ha l'intervallo di valori [1..20]
; questo risulta dall'unione dei due intervalli di valori [1..10]
E [2..20]
.
Condizioni
Le condizioni possono limitare l'intervallo di valori di una variabile in un blocco di codice. È possibile combinare diverse condizioni. Condizioni che si escludono a vicenda possono anche risultare in un intervallo di valori vuoto.
IF y > 0 AND y < 10 THEN x := y; ELSE x:= 0; END_IF IF x < 0 THEN i := 99; END_IF
y ha l'intervallo di valori [1..9]
sulla riga 2. Ciò risulta nell'intervallo di valori [0..9]
per x
alla riga 6. Combinato con la condizione x < 0
, il risultato è un insieme vuoto di possibili valori per x
alla riga 8. Il codice non è accessibile. L'analisi statica riporterà la condizione x < 0
ritorna sempre FALSE
a questo punto.
Ciclo
La propagazione costante eseguirà il loop del codice finché i valori delle variabili nel loop non cambieranno più. Si presuppone che un ciclo possa essere eseguito un numero qualsiasi di volte. I valori finora determinati vengono combinati con i valori precedenti. Le variabili che vengono modificate all'interno del ciclo hanno un intervallo crescente. In questo caso la propagazione costante non accetta tutti i valori possibili per gli intervalli, ma utilizza solo i limiti presenti nel codice e anche i valori 0, 1, 2, 3 e 10 perché questi sono spesso rilevanti.
Il modo più semplice per descrivere la procedura è tramite un esempio:
PROGRAM PLC_PRG VAR x: DINT; i : DINT; y : DINT; END_VAR
//Implementation x := 0; y := 0; FOR i := 0 TO 5 DO x := x + 1; y := i; END_FOR
La propagazione costante conosce quanto segue riguardo al ciclo:
i
, x
, E y
sono 0 all'inizio della prima esecuzione del ciclo. La condizione i <= 5
si applica al codice nel loop. La condizione i > 5
si applica al codice dopo il ciclo.
Per i valori delle variabili nel ciclo, la propagazione costante determina i seguenti valori:
|
|
| ||
---|---|---|---|---|
|
|
|
Nel dettaglio si attraversano i seguenti passaggi intermedi:
Passaggio |
|
|
| |
---|---|---|---|---|
1 | 0 |
|
|
|
2 |
|
|
| |
6 |
|
|
| Innanzitutto, la gamma |
7 |
|
|
| |
10 |
|
|
|
|
11 |
|
|
|
|
A partire dalle 11 | Dall'undicesimo passaggio i valori nel ciclo non cambieranno. La propagazione è terminata. |
Inoltre, i = 6
si applica al codice che segue questo ciclo. La gamma [0..6]
viene determinato nel ciclo e questo viene combinato con la condizione i > 5
, che risulta esattamente nel valore 6.