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_TYPEL'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_TYPESu 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.