Vai al contenuto

Allocazione in memoria delle variabili strutturate

Home Forum Programmazione IEC 61131 (LogicLab) Allocazione in memoria delle variabili strutturate

Stai visualizzando 12 post - dal 1 a 12 (di 12 totali)
  • Autore
    Post
  • #35498
    Maurizio Conti
    Partecipante

    E’ 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;

    #38028
    Sergio Bertana
    Amministratore del forum

    Per 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;

    #38038
    Maurizio Conti
    Partecipante

    Ho 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;

    #38039
    Sergio Bertana
    Amministratore del forum

    La 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;

    #38040
    Maurizio Conti
    Partecipante

    Mille grazie! Non mi era noto che il compilatore considera il tipo struttura come un tipo di dati da allineare ad indirizzo divisibile per 4.

    #48960
    Roberto
    Partecipante

    Mi 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.

    #48965
    Sergio Bertana
    Amministratore del forum

    La 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.64

    #58819
    Rubox
    Partecipante

    Riprendo 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?

    #58824
    Sergio Bertana
    Amministratore del forum

    C’è 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.36

    Puoi verficare la versione che stai utilizzando?

    #58829
    Rubox
    Partecipante

    Il 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.

    #58851
    Rubox
    Partecipante

    Riprendo 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.

    #58864
    Sergio Bertana
    Amministratore del forum

    Il 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.

Stai visualizzando 12 post - dal 1 a 12 (di 12 totali)
  • Devi essere connesso per rispondere a questo topic.