Attributo: pack_mode
Il pragma definisce come una struttura di dati viene impacchettata durante l'allocazione. L'attributo deve essere inserito sopra la struttura dati e influisce sull'imballaggio dell'intera struttura.
Sintassi:
{attribute 'pack_mode' := ' <pack mode value> '}
Inserisci posizione: sopra la dichiarazione della struttura dati
<pack mode value>
<valore della modalità pacchetto> | Metodo di imballaggio associato | Descrizione |
---|---|---|
0 | Allineato | Tutte le variabili sono allocate a indirizzi di byte. Non ci sono vuoti di memoria. |
1 | Allineato a 1 byte | |
2 | Allineato a 2 byte | . Ci sono
|
4 | Allineato a 4 byte | . Ci sono
|
8 | Allineato a 8 byte | . Ci sono
|
Suggerimento
A seconda della struttura, potrebbe non esserci alcuna differenza nella mappatura della memoria delle singole modalità. Ad esempio, la distribuzione della memoria di una struttura con {attribute 'pack mode' := '4'}
pragma può corrispondere a quello di {attribute 'pack mode' := '8'}
.
Suggerimento
Matrici di strutture
Se le strutture sono combinate in matrici, i byte vengono aggiunti alla fine della struttura in modo che la struttura successiva sia allineata.
Importante
Se la Layout di compatibilità l'opzione è selezionata nella configurazione del simbolo e contemporaneamente l'attributo 'pack_mode'
viene utilizzato nel codice, possono verificarsi problemi a causa di un disallineamento involontario della memoria.
Esempio 1
{attribute 'pack_mode' := '1'} TYPE myStruct: STRUCT Enable: BOOL; Counter: INT; MaxSize: BOOL; MaxSizeReached: BOOL; END_STRUCT END_TYPE
L'intervallo di memoria per una variabile del tipo di dati myStruct
è allocato "allineato". Se l'indirizzo di archiviazione del suo componente Enable
è 0x0100
, ad esempio, quindi il componente Counter
segue all'indirizzo 0x0101
, MaxSize
all'indirizzo 0x0103
e MaxSizeReached
all'indirizzo 0x0104
. In caso di 'pack_mode':=2
, Counter
sarebbe a 0x0102
, MaxSize
a 0x0104
e MaxSizeReached
a 0x0105
.
Esempio 2
STRUCT Var1 : BOOL := 16#01; Var2 : BYTE := 16#11; Var3 : WORD := 16#22; Var4 : BYTE := 16#44; Var5 : DWORD := 16#88776655; Var6 : BYTE := 16#99; Var7 : BYTE := 16#AA; Var8 : DWORD := 16#AA; END_TYPE
pack_mode = 8 | pack_mode = 0 | pack_mode = 1 | pack_mode = 2 | pack_mode = 4 | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Variabile | Valore | Variabile | Valore | Variabile | Valore | Variabile | Valore | Variabile | Valore | |
0 |
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
|
|
|
3 | … |
| … |
| … |
| … |
| … |
|
4 |
|
|
|
|
|
|
|
|
|
|
5 |
|
|
|
| ||||||
6 | … |
| … |
|
|
| ||||
7 | … |
| … |
| … |
| ||||
8 |
|
| … |
| … |
| … |
|
|
|
9 | … |
|
|
|
|
| … |
| … |
|
10 | … |
|
|
|
|
|
|
| … |
|
11 | … |
|
|
|
|
|
|
| … |
|
12 |
|
| … |
| … |
|
|
|
|
|
13 |
|
| … |
| … |
| … |
|
|
|
14 | … |
| … |
| … |
| ||||
15 | … |
| ||||||||
16 |
|
|
|
| ||||||
17 | … |
| … |
| ||||||
18 | … |
| … |
| ||||||
19 | … |
| … |
| ||||||
20 | ||||||||||
21 | ||||||||||
22 | ||||||||||
23 | ||||||||||
24 | ||||||||||
25 | ||||||||||
26 | ||||||||||
27 | ||||||||||
28 | ||||||||||
29 | ||||||||||
30 | ||||||||||
31 |
Esempio 3
STRUCT Var1 : BYTE := 16#01; Var2 : LWORD := 16#11; Var3 : BYTE := 16#22; Var4 : BYTE := 16#44; Var5 : DWORD := 16#88776655; Var6 : BYTE := 16#99; Var7 : BYTE := 16#AA; Var8 : WORD := 16#AA; END_TYPE
pack_mode = 8 | pack_mode = 0 | pack_mode = 1 | pack_mode = 2 | pack_mode = 4 | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Variabile | Valore | Variabile | Valore | Variabile | Valore | Variabile | Valore | Variabile | Valore | |
0 |
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
| ||||||
2 | … |
| … |
|
|
| ||||
3 | … |
| … |
| … |
| ||||
4 | … |
| … |
| … |
|
|
| ||
5 | … |
| … |
| … |
| … |
| ||
6 | … |
| … |
| … |
| … |
| ||
7 | … |
| … |
| … |
| … |
| ||
8 |
|
| … |
| … |
| … |
| … |
|
9 | … |
|
|
|
|
| … |
| … |
|
10 | … |
|
|
|
|
|
|
| … |
|
11 | … |
|
|
|
|
|
|
| … |
|
12 | … |
| … |
| … |
|
|
|
|
|
13 | … |
| … |
| … |
| … |
|
|
|
14 | … |
| … |
| … |
| … |
| ||
15 | … |
|
|
|
|
| … |
| ||
16 |
|
|
|
|
|
|
|
|
|
|
17 |
|
|
|
|
|
|
|
| … |
|
18 | … |
| … |
|
|
| … |
| ||
19 | … |
| … |
| ||||||
20 |
|
|
|
| ||||||
21 | … |
|
|
| ||||||
22 | … |
|
|
| ||||||
23 | … |
| … |
| ||||||
24 |
|
| ||||||||
25 |
|
| ||||||||
26 |
|
| ||||||||
27 | … |
| ||||||||
28 | ||||||||||
29 | ||||||||||
30 | ||||||||||
31 |
Comportamento senza 'pack-mode'
Se 'pack-mode'
non viene utilizzato, quindi il compilatore utilizza in genere la modalità pacchetto 4 o 8, a seconda della descrizione del dispositivo. In ogni caso, viene utilizzata una modalità di pacchetto particolarmente vantaggiosa per il processore in modo che possa essere eseguito l'accesso alla memoria. Questo è anche chiamato allineamento naturale o allineamento naturale dei dati
Effetti negativi durante l'utilizzo 'pack-mode'
L'accesso alla memoria non allineato può essere il risultato dell'utilizzo dell'attributo 'pack_mode'
. Ciò significa, ad esempio, che un tipo di dati con una dimensione di 4 byte si trova quindi in un indirizzo che non è divisibile per 4. Normalmente, su un sistema a 32 bit un tipo di dati a 32 bit può essere letto e scritto con un unico accesso alla memoria. Su alcune piattaforme, ad esempio su piattaforme ARM, ciò è possibile solo quando questo valore è allineato in memoria. Su altre piattaforme, può essere che l'accesso sia possibile ma viene eseguito molto più lentamente.
{attribute 'pack_mode':=1} TYPE DUT STRUCT by1 : BYTE; dw1 : DWORD; END_STRUCT END_TYPE
Su una piattaforma ARM, il valore dw1
non può essere letto con un unico accesso. Quando si tenta di accedere direttamente a questo elemento, il processore ARM genererà un'eccezione.
Presupposto: viene eseguito il seguente accesso in lettura: dwTest := dut1.dw1;
Per questo l'accesso al DWORD dw1
, sono necessari quattro accessi alla memoria perché ogni byte viene letto, spostato e disgiunto individualmente. Il flusso è in qualche modo lo stesso dell'esempio seguente in cui a DWORD
viene generato da un array di quattro byte:
dwHelp := bytes[0]; dwResult := dwHelp; dwHelp := bytes[1]; dwHelp := SHL(dwHelp, 8); dwResult := dwResult OR dwHelp; dwHelp := bytes[2]; dwHelp := SHL(dwHelp, 16); dwResult := dwResult OR dwHelp; dwHelp := bytes[3]; dwHelp := SHL(dwHelp, 24); dwResult := dwResult OR dwHelp;
Ovviamente, questo tipo di accesso è molto più lento dell'accesso a a DWORD
, che è allineato in modo appropriato nella memoria.
pdw := ADR(dut1.dw1); dwTest := pdw^;
Tuttavia, il compilatore non genererà l'accesso dell'esempio quando si accede a questo tipo di membro tramite un puntatore. Ciò significa che il codice seguente genera un'eccezione su una piattaforma ARM.
pdw := ADR(dut1.dw1); dwTest := pdw^;
Per motivi di prestazioni, dovresti quindi evitare di lavorare con strutture che non sono naturalmente allineate.
Una struttura imballata non deve contenere una struttura non imballata.