Allocazione in memoria delle variabili strutturate
Home › Forum › Programmazione IEC 61131 (LogicLab) › Allocazione in memoria delle variabili strutturate
- Questo topic ha 11 risposte, 4 partecipanti ed è stato aggiornato l'ultima volta 4 anni, 2 mesi fa da
Sergio Bertana.
-
AutorePost
-
Gennaio 24, 2014 alle 9:26 am #35498
Maurizio Conti
PartecipanteE’ possibile conoscere come viene mappata in memoria un’array di elementi strutturati in modo da poterli recuperare e visualizzare all’interno di una pagina Web ? Di seguito riporto un possibile caso.
ChannelSettingType : STRUCT
Settings : USINT;
ExtraSettings : UINT;
Descrizione : STRING[ 24 ];
END_STRUCT;(* Allocazione di una array di ChannelSettingType *)
ChannelSettings AT %MB100.2056 : ARRAY[ 0..15 ] OF ChannelSettingType;
Gennaio 24, 2014 alle 1:46 pm #38028Sergio Bertana
Amministratore del forumPer rispondere alla tua domanda occorre fare riferimento alla architettura del sistema, in un sistema ARM come lo SlimLine le variabili a 2 bytes sono allineate ad indirizzi divisibili per 2, mentre le variabili a 4 bytes sono allineate ad indirizzi divisibili per 4. Ora la tua struttura si compone di un USINT, un UINT ed una stringa, ed è allocata all’indirizzo 2056 quindi avremo:
ADR(ChannelSettings[0].Settings) (* 2056 *)
ADR(ChannelSettings[0].ExtraSettings) (* 2058 *)
ADR(ChannelSettings[0].Descrizione) (* 2060, il campo descrizione occupa 24 bytes più 1 di terminazione *)ADR(ChannelSettings[1].Settings) (* 2085 *)
ADR(ChannelSettings[1].ExtraSettings) (* 2086 *)
ADR(ChannelSettings[1].Descrizione) (* 2088 *)… Ecc…
Il mio consiglio è di tenere sempre le strutture con il giusto allineamento quindi se puoi ridurre di un byte la descrizione trasformerei la tua nel modo:
ChannelSettingType : STRUCT
Settings : USINT;
Dummy: USINT;
ExtraSettings : UINT;
Descrizione : STRING[ 23 ];
END_STRUCT;Gennaio 29, 2014 alle 12:45 pm #38038Maurizio Conti
PartecipanteHo capito il problema dell’allineamento però c’è però una cosa che non mi torna: Definendo una struttura come segue ed allocandone un array:
ChannelSettingType : STRUCT Settings : USINT; Descrizione : USINT[ 24 ]; END_STRUCT;
ChannelSettings AT %MB100.2056 : ARRAY[ 0..15 ] OF ChannelSettingType;Gli indirizzi di allocazione che ritornano (ottenuti con la funzione ADR) sono:
1073766964 //ChannelSettings[0].Settings
1073766965 //ChannelSettings[0].Descrizione[0]
1073766992 //ChannelSettings[1].Settings
1073766993 //ChannelSettings[1].Descrizione[0]
1073767020 //ChannelSettings[2].Settings
1073767021 //ChannelSettings[2].Descrizione[0]Quindi la struttura di 25 bytes sembra essere allocata con passo 28 bytes che non mi sembra congruente. Stessa situazione con una struttura di 25 bytes o di 26 bytes come nei due casi seguenti.
ChannelSettingType : STRUCT Settings : UINT; Descrizione : STRING[ 23 ]; END_STRUCT;
ChannelSettingType : STRUCT Settings : UINT; Descrizione : USINT[ 24 ]; END_STRUCT;Gennaio 29, 2014 alle 1:44 pm #38039Sergio Bertana
Amministratore del forumLa spiegazione segue quanto già detto nel post precedente riguardo all’allineamento ad indirizzi divisibili per 4 delle variabili a 4 bytes. Il compilatore considera il tipo struttura come un tipo di dati da allineare ad indirizzo divisibile per 4, essendo la lunghezza della struttura 25 bytes, l’indirizzo di allocazione della seconda struttura nell’array divisibile per 4 lo si ottiene lasciando 3 bytes liberi.
Proprio per evitare al compilatore l’onere di lasciare spazi vuoti nell’allineamento (Caratteristica che compilando per altri targets diversi da ARM potrebbe modificarsi) consiglio sempre di prestare attenzione all’allineamento dei dati nella definizioni delle strutture inserendo dei bytes dummy. La tua struttura potrebbe diventare:
ChannelSettingType : STRUCT Settings : USINT; Descrizione : USINT[ 24 ]; Dummy : USINT[ 3 ]; END_STRUCT;
Gennaio 29, 2014 alle 5:25 pm #38040Maurizio Conti
PartecipanteMille grazie! Non mi era noto che il compilatore considera il tipo struttura come un tipo di dati da allineare ad indirizzo divisibile per 4.
Agosto 6, 2019 alle 6:32 am #48960Roberto
PartecipanteMi accodo a questo vecchio articolo per porre la seguente questione:
Nel caso in cui dichiaro una variabile di tipo struttura personalizzata, come scegliere la selezione del size nella colonna address? Ho provato a selezionare tutte le possibilità, notando che l’allocazione della memoria dipende esclusivamente dal tipo dichiarato per ogni singolo elemento all’interno della struttura.
Agosto 6, 2019 alle 6:49 am #48965Sergio Bertana
Amministratore del forumLa selezione del size non è importante il compilatore assegnerà alla variabile la dimensione corretta indipendentemente dal size definito.
Il campo size serve unicamente rappresentare l’associazione della variabile con posizioni fisiche nella memoria. La rappresentazione è fornita dalla concatenazione del segno di percentuale “%”, di un prefisso di allocazione, di un prefisso di dimensione e uno o due numeri interi senza segno, separati da punti (.). Esempio
% location.size.index.index
location può essere: I Input, Q Output, M Memory
size può essere: X Single bit, B Byte (8 bits), W Word (16 bits), D Double word (32 bits)Quindi per un ingresso digitale: %IX0.0, %IX5.6, %IX0.8
Quindi per una uscita digitale: %QX0.0, %QX5.6, %QX0.8
Per variabili in memoria: %MX100.0, %MB100.10, %MW100.32, %MD100.64Gennaio 20, 2021 alle 1:53 pm #58819Rubox
PartecipanteRiprendo questo argomento perché probabilmente mi sfugge qualcosa: quando dichiaro in una struttura un membro di tipo STRING LogicLab non mi permette di definirne la dimensione ma imposta automaticamente la dimensione a 32 caratteri.
Se apro progetti scritti con la versione precedente di LogicLab ho delle strutture con stringhe da 15, 31 o 63 caratteri, ma non mi permettere di modificarne la dimensione.Cosa sto sbagliando?
Gennaio 20, 2021 alle 1:57 pm #58824Sergio Bertana
Amministratore del forumC’è stata una versione di LogicLab che aveva questo problema ma sull’ultima versione scaricabile dal nostro sito il problema dovrebbe essere risolto. Io ho provato con questa versione e non ho riscontrato il problema, la mia versione è:
Version: 3.1.1.0
Build Jul 10 2020 17:0007 – 5.12.0.36Puoi verficare la versione che stai utilizzando?
Gennaio 20, 2021 alle 3:33 pm #58829Rubox
PartecipanteIl problema è che aggiornando LogicLab a quella versione da quella che utilizzo mi ritrovo errori in fase di compilazione dal blocco FTPClient_v1. Se lo sostituisco con FTPClient_v2 della libreria fornita con LogicLab 3.1.1.0 scompare l’errore di indice non trovato, ma saltano fuori warnings (21) del tipo
FTPClient_v2(629) - warning G0128: 0 => Comparison between pointer and non-pointer
Infatti avevo installato l’ultima versione, ma poi ero ritornato sui miei passi perchè mi dava problemi.Gennaio 22, 2021 alle 5:17 pm #58851Rubox
PartecipanteRiprendo il discorso. Mi son collegato da remoto ad una CPU per provare. I passi precedenti sono stati:
- Ho installato la versione di LogicLab 3.1.1.0 Build 5.12.0.36
- Ho scaricato le ultime versioni delle librerie
- Ho aggiunto la libreria eLLabXTargetAdjLib al progetto esistente
Ho creato un nuovo progetto per la CPU e caricato il blocco FTPClient_v2 (da libreria SFR079C220). Mi collego alla CPU caricando la sua immagine (SlimLine Cortet M7 MPS054A110, XTarget_12, con FW SFW198C330). Creo un semplicissimo programma copiando l’esempio di utilizzo ST_FTPClient_v2 sulla Knowledge, e mi compaiono le warning:
FTPClient_v2(63) - warning G0128: 0 => Comparison between pointer and non-pointer FTPClient_v2(100) - warning G0128: 0 => Comparison between pointer and non-pointer FTPClient_v2(117) - warning G0128: 0 => Comparison between pointer and non-pointer
Ho provato a cancellare tutto il contenuto della cartella del progetto lasciando solo il codice, ricaricando l’immagine ecc… ma saltano sempre fuori quei warning.
Non riesco a capire dove sbaglio, se devo caricare qualche altra libreria, se non gli piace il firmware XTarget. Va bene che i warning non sono “bloccanti”, ma non mi piace spedire in giro programmi potenzialmente “problematici” e mi piacerebbe venirne a capo.
Gennaio 22, 2021 alle 5:19 pm #58864Sergio Bertana
Amministratore del forumIl problema è dovuto ad un errore nella libreria eLLabXTargetAdjLib, è errata la definizione di eNULL, ho provveduto a creare la nuova versione di libreria si può scaricare dal sito.
-
AutorePost
- Devi essere connesso per rispondere a questo topic.