Skip to main content

Dichiarazione del modulo

Moduli in CODESYS Application Composer sono definiti in una dichiarazione di modulo. La dichiarazione del modulo è un oggetto separato nel pool POU e costituisce la base per l'utilizzo di un modulo nel albero dei moduli.

Oggetti nel POU:

27-04-2026_15-13-36.png

I moduli vengono dichiarati con un proprio linguaggio di descrizione che è simile alla dichiarazione delle variabili nel codice ST (Structured Text).

. Principio di base
  • Ogni dichiarazione di modulo è basata su un blocco funzione (modulo FB).

  • Il modulo FB contiene la logica funzionale.

  • La dichiarazione del modulo aggiunge informazioni di configurazione e strutturali al modulo FB.

. Elementi definibili della dichiarazione del modulo
  • Parametri

    Le variabili di input del modulo FB possono essere contrassegnate come parametri per abilitare la parametrizzazione strutturata del modulo.

  • Ingressi e uscite del modulo

    Le variabili di ingresso e uscita del modulo FB possono essere definite come I/O del modulo e collegate a variabili, altri moduli o I/O del dispositivo.

  • Slot

    Gli slot consentono l'integrazione di altri moduli come sottomoduli, definendo così una struttura gerarchica dei moduli.

  • Sottomoduli predefiniti

    Assegnazioni predefinite per gli slot dei moduli che vengono applicate automaticamente all'inserimento di un modulo.

  • Visualizzazioni

    I moduli possono fornire visualizzazioni di pagina e visualizzazioni incorporate che vengono generate e collegate automaticamente.

  • Modulo proxy FbS

    I blocchi funzione proxy possono essere definiti per implementare riferimenti oltre i limiti dell'applicazione o del controller.

  • Riferimenti alle istanze

    Riferimenti a istanze FB che l'utente associa a istanze specifiche solo in fase di configurazione.

  • Allarmi

    I moduli possono utilizzare la gestione degli allarmi CODESYS per definire e valutare gli allarmi per le variabili del modulo FB.

  • Bandiere di processo

    Contrassegni per l'utilizzo dei moduli in processi sequenziali (ad esempio catene di passaggi).

Formato della dichiarazione del modulo

A header of the form MODULE<name> begins the declaration. This is followed by a list of sections.

Ogni sezione è introdotta dalla parola chiave SEC (per «sezione») e un nome univoco. La parola chiave END_SEC chiude la sezione. Il contenuto di una sezione contiene un elenco di voci composto da più sezioni o definizioni

Una definizione è costituita da un nome e un valore opzionale e termina con un punto e virgola.

I commenti possono essere usati come nel codice ST: «//"» per un commento a riga singola e «(*» e «*)» per commenti su più righe. Gli spazi bianchi (tabulazioni e spazi) e newline/linefeed possono essere usati per separare le parti di una dichiarazione. Altrimenti vengono ignorati durante l'elaborazione.

Come per il codice ST, maiuscole e minuscole non fanno differenza.

Esempio 9. L'esempio seguente spiega gli elementi di una dichiarazione di modulo:
01    MODULE Persistence IMPLEMENTED_BY PersistenceFB
02    SEC MetaData
03        NAME       := TL.ChannelName ;
04        DESC       := TL.ChannelDesc ;
05        COLLECTION CATEGORY := ’Persistence’TL.Collection  ;
06        ICON_16    := IP.Channel16 ;
07        ICON_32    := IP.Channel32 ;
08    END_SEC
09    SEC Toplevel
10              SEC STANDARD_TASK : LOW
11                      NAME  := LOW ;
12                      DESC  := TL.TaskLow ;
13                      FLAGS := CREATE_IF_MISSING | READONLY ;
14              END_SEC
15              GVL_NAME := 'GVL_%InstanceName%' ;
16     END_SEC

Il nome del modulo è definito nella riga 01. IMPLEMENTED_BY definisce il blocco funzione «PersistenceFB» che contiene la logica del modulo. Questo blocco funzionale deve derivare IModule. MetaData la sezione inizia nella riga 02 e termina nella riga 08. Questa sezione contiene cinque definizioni. La possibilità di sezioni annidate è mostrata nella Toplevel sezione (Righe 09—16) che contiene STANDARD_TASK sottosezione (riga 10).



Sintassi della dichiarazione del modulo

In questa sezione vengono spiegate la sintassi e la struttura sintattica consentita di una dichiarazione di modulo.

Nel seguente scanner i token sono scritti in maiuscolo (esempio: ID). Le parti non terminali della grammatica sono scritte tra parentesi graffe {Entry}).

Analisi lessicale (scanner)

Nella prima fase, i token (o lessemi) vengono creati dai caratteri della dichiarazione del modulo (esempio: parole chiave, costanti, identificatori).

Gli spazi bianchi e i caratteri newline e linefeed separano i token, ma altrimenti vengono ignorati. Anche i commenti vengono ignorati durante l'elaborazione della dichiarazione. (I commenti possono essere scritti in una sola riga//«) o commenti su più righe ((* e *)) come nel linguaggio ST. I commenti su più righe possono essere annidati

Fondamentalmente un token ha sempre una lunghezza massima. Ad esempio a123 viene interpretato come un identificatore e non come un identificatore a seguito da un letterale 123.

L'ordine dei token nell'elenco seguente mostra la loro priorità, come descritto di seguito. Ad esempio, MODULE l'input è inteso come parola chiave e non come identificatore.

. Elenco di tutti i token disponibili:
  • Parole chiave: MODULE, SEC, END_SEC, IMPORTS, e IMPLEMENTED_BY

  • OP: Una sequenza non vuota dei seguenti caratteri: .:,%()[]{}<>|+-*/@!?^°=\~

    Nota: i marcatori dei commenti //, (*, e *) hanno una priorità più alta rispetto agli operatori. D'altra parte, un commento non può iniziare all'interno di un operatore. Ad esempio, secondo la regola della lunghezza massima, +//+ viene interpretato come un operatore e non come + seguito da un commento.

  • LIT: un valore letterale IEC, come viene utilizzato in ST, esempio: 1.4, tod#12:13:14. Ciò include i valori letterali booleani TRUE e FALSE (lettere maiuscole o minuscole non sono rilevanti).

    Nota: valori letterali non tipizzati con segno negativo (-1, -3.2) vengono letti come due token, cioè come operatore - seguito da un letterale non digitato. Di conseguenza, i valori letterali numerici non digitati non possono mai essere negativi.INT#-34) verrà sempre interpretato come un token.

  • ID: un identificatore IEC valido ([a-zA-Z_][a-zA-Z0-9_]*sottolineatura consecutivi. A differenza di ST, questo include anche le parole chiave di ST FUNCTION, INTe EXTENDS).

  • PUNTO E VIRGOLA: Il personaggio ;

Sintassi (parser)

La sintassi della dichiarazione del modulo è definita dalla seguente grammatica.µ è una sequenza vuota.

{MDecl}        ::= MODULE {QID} {ImplSpec} {ImportsSpec} {MBody}
{ImplSpec}     ::= IMPLEMENTED_BY {QID} | µ
{ImportsSpec}  ::= IMPORTS {QID} | µ
{MBody}        ::= {SecList}
{SecList}      ::= {Modifiers} {Sec} {SecList} | µ
{Sec}          ::= SEC {QID} {SecTarget} {EntryList} END_SEC
{SecTarget}    ::= OP(":") {QID} | µ
{Modifiers}    ::= OP("[") {ModifierList} OP("]") | µ
{ModifierList} ::= {QID} OP(",") {ModifierList} | {QID}
{EntryList}    ::= {Modifiers} {Entry} {EntryList}
{Entry}        ::= {Sec} | {Def}
{Def}          ::= {QID} OP(":=") {ValList} SEMICOLON |
                   {QID} SEMICOLON
{ValList}      ::= {Val} {ValList} | {Val}
{Val}          ::= ID | LIT | OP
{QID}          ::= ID | ID OP(".") {QID}

L'elenco dei valori di definizione ({ValList}) deve terminare con un punto e virgola. Questo semplifica la grammatica ed evita ambiguità perché il punto e virgola non può far parte{VAL}), tranne all'interno di una stringa letterale.

L'operatore di assegnazione (:=) delle definizioni ({Def}) serve anche a evitare ambiguità ({QID}) dei nomi e dei valori delle definizioni.

Tipi definiti per le definizioni

  • Testo: ID.ID (nome dell'elenco di testo e identificatore dell'elenco di testo) - vedere Localizzazione delle stringhe di elenchi di testo

  • Immagine: ID.ID (nome del pool di immagini e identificatore del pool di immagini)

  • ID (identificativo IEC)

  • QID (identificatore qualificato): {QID} ::= ID | ID.ID

  • CategoryPath ::= {StringLiteral} | {CategoryPath}

  • Cardinalità: [{MIN} .. {MAX}] | [ {MIN} .. INF [ {MIN}, e {MAX} sono valori letterali interi e non negativi. Se {MAX} != INF, quindi {MIN} <= {MAX} deve candidarsi.

  • StringLiteral: una stringa letterale IEC può contenere interruzioni di riga.

  • stdTaskFlags: := {stdTaskFlag} | {stdTaskFlags} stdTaskFlag: := NONE | CREATE_IF_MISSING | READONLY

  • Letterale: qualsiasi valore letterale IEC o QID (per costanti Enum)

  • Bandiera DTBOOL: µ (sequenza vuota) | TRUE | FALSE

  • Tipo di slot: SUBMODULE | REFERENCE

  • Pragma: [ {PragmaList} ] {PragmaList} ::= {Pragma} | {Pragma} , {PragmaList} {Pragma} ::= { ( ID | {StringLiteral} | {OP2} )+ } {OP2} : tutti gli operatori tranne {, }, [, ] e ,.

  • Percorso dell'istanza:

    InstancePath ::= {IComp} | {IComp} . {IComp} con {IComp} ::= ID {ArrayAccess}* e {ArrayAccess} ::= [ {IntList} ] e {IntList} ::= Int | Int , {IntList}

  • Rif. attività: Standard_Task. ( Low | Medium | High) | Custom_Task.ID

Percorsi delle istanze

In alcune posizioni della dichiarazione del modulo, è possibile definire percorsi di istanza per indirizzare una variabile di un blocco funzione: per parametri, slot, I/O, array con dimensioni variabili e riferimenti di istanza.

Un percorso di istanza è definito come una sequenza di componenti non vuota, separati da punti: C1.C2…CN. Un componente deve essere un identificatore IEC o un componente seguito da un' [i1, …, iN], dove i1 a iN sono valori interi.

I percorsi delle istanze sono sempre relativi al blocco funzione che implementa la logica del modulo. Il primo componente del percorso dell'istanza è un membroVAR_INPUT o VAR_OUTPUT, a seconda del caso d'uso) del blocco funzionale. Se il percorso dell'istanza contiene componenti aggiuntivi, questi componenti indirizzano la variabile all'interno del membro. Altrimenti viene indirizzato il membro stesso. I percorsi delle istanze possono essere limitati alle variabili di input o output (esempio: per gli I/O). Queste restrizioni non sono valide per le strutture. Questi tipi di percorsi di istanza sono denominati percorsi di istanza di input e percorsi di istanza di output.

Localizzazione di stringhe di elenchi di testo

I testi nei moduli (esempio: descrizione del modulo, nome, descrizione del parametro) possono essere visualizzati in diverse lingue. Questi testi sono gestiti in elenchi di testo.

. Specifica del nome della lingua:
  • Il nome del linguaggio ha il formato <LanguageCode>[-<Country/Region>] (ad esempio: en-US, de-DE).

  • <LanguageCode> è il nome della lingua secondo la norma (example: de o en).

  • <Country/Region> è un codice del paese secondo la norma ISO 3166.

  • Quando si recupera una voce di un elenco di testi, il sistema cerca innanzitutto il nome completo della lingua. Se non viene trovato nulla, cerca il <LanguageCode>. Se anche questa ricerca fallisce, viene utilizzato il testo predefinito.

Tabella 1. Esempi di nomi di lingue negli elenchi di testo

Lingua

Nome della lingua

Cinese

zh-CHS

inglese

en-US

Francese

fr-FR

tedesco

de-DE

italiano

IT-IT

Giapponese

Ja-jp

Portoghese

Pt-PT

russo

ru-RU

spagnolo

es-ES



Derivazione delle dichiarazioni dei moduli

Analogamente all'ereditarietà orientata agli oggetti di un blocco funzione A da un blocco funzione B («EXTENSS»), è possibile derivare le dichiarazioni dei moduli utilizzando IMPORTS parola chiave. UPDATE e HIDE i modificatori sono trattati in modo speciale.

. Vengono utilizzate le seguenti regole:
  • Il nome del modulo importato deve essere specificato con namespace se questo modulo è definito in una libreria diversa.

  • Le importazioni cicliche non sono consentite, in particolare un modulo non deve importarsi da solo. (Esempio di importazione ciclica: il modulo M_1 importa il modulo M_2, M_2 importa M_3,..., M_N importa nuovamente M_1

  • Un modulo derivato può essere definito senza IMPLEMENTED_BY direttiva. In questo caso, verrà utilizzato il blocco funzione del modulo base.

  • Se un modulo derivato tramite IMPLEMENTED_BY specifica un blocco funzione, quindi questo blocco funzione deve derivare dal blocco funzione del modulo base o deve essere identico ad esso.

  • Un modulo derivato eredita tutte le sezioni del modulo base. Può aggiungere nuove sezioni o modificare sezioni esistenti

  • Una sezione può essere modificata nel modulo derivato utilizzando lo stesso nome e la stessa destinazione estesa con UPDATE modificatore. In questo caso, le sue voci vengono modificate. Tutte le definizioni mancanti della sezione nel modulo derivato vengono applicate dal modulo base.

  • Le UPDATE e HIDE i modificatori possono essere utilizzati solo se la rispettiva sezione (nome e destinazione) è definita nel modulo base. Viceversa, una sezione definita nel modulo base può essere utilizzata nel modulo derivato solo se è fornita HIDE o UPDATE modificatori. Se c'è solo il HIDE modificatore nella sezione e non UPDATE, quindi non sono ammesse definizioni.

  • Alcune voci devono essere modificate nel modulo derivato (esempio: la descrizione).

Esempio 10. Esempio:
MODULE MBase IMPLEMENTED_BY FBBase
SEC MetaData
        DESC := TL.Desc_Base ;
END_SEC
SEC Parameters
        SEC Param : paramxIn
                Variable := xIn ;
                Name     := TL.Param1_Name ;
                Desc     := TL.Param1_Desc ;
        END_SEC
END_SEC

MODULE MDerived IMPORTS MBase
[UPDATE] SEC MetaData
        DESC := TL.Desc_Derived ;
END_SEC
[UPDATE] SEC Parameters
        [UPDATE,HIDE] SEC Param : paramIn
                Variable := xIn ;
                DEFAULT := TRUE ;
        END_SEC
END_SEC


Nell'esempio sopra riportato, paramIn parametro del MBase il modulo è nascosto nel modulo derivato MDerived (utilizzando il HIDE modificatore) e allo stesso tempo un nuovo valore predefinito (TRUE) è impostato.

Note sull'ordine delle sezioni e delle definizioni

L'ordine delle sezioni subito dopo l'intestazione del modulo è irrilevante. All'interno delle sezioni, l'ordine può essere molto importante. Ad esempio, l'ordine delle dichiarazioni degli slot definisce l'ordine dei moduli nell'albero dei moduli

L'ordine delle definizioni è sempre irrilevante.

. Regole per i moduli derivati relative all'ordine:
  • Le sezioni dei moduli base sono sempre definite prima delle sezioni del modulo stesso.

  • Se una sezione del modulo base viene modificata utilizzando UPDATE o HIDE, il suo ordine non viene alterato.

  • Non è possibile per un modulo derivato modificare l'ordine come definito nel modulo base.

Completamento automatico e «Elenca componenti»

Quando si inizia a digitare nell'editor del modulo, tutte le definizioni di sezione disponibili/possibili vengono visualizzate in un menu «Elenco componenti». Vengono mostrate solo le sezioni e le definizioni significative per la posizione corrente. Anche se alcune voci di sottosezione hanno lo stesso nome delle voci di sottosezione di altre sezioni, cercherà di visualizzare solo le definizioni di sezione corrispondenti

Se il Ritorno viene premuto il tasto dopo aver completato la prima riga di una sezione, quindi la sezione verrà completata con tutte le definizioni/sezioni necessarie e END_SEC .

Dopo le definizioni delle variabili, alle variabili di input/output viene fornito un menu «Elenco componenti». Le bandiere o i valori predefiniti sono inoltre dotati di una selezione «Elenca componenti», che

Dopo le definizioni che utilizzano voci di elenco di testo o voci di pool di immagini (esempio: la maggior parte delle volte Desc :=), viene presentato un menu «Elenca componenti» che include tutti gli elenchi di testo o i pool di immagini disponibili e visibili e le relative voci.

Premendo il pulsante F2 tasto, è possibile aprire il supporto di input corrispondente.

Sezioni della dichiarazione del modulo

Sezione: MetaData

Sezione: Toplevel

Sezione: IO

Sezione: Parametri

Sezione: Slot

Sezione: Visu

Sezione: Proxies

Sezione: VarArrays

Sezione: Vincoli

Sezione: InstRefs

Sezione: MSE.Sequence

Generatore di dispositivi

Sezione: Alg.Alarm