Home › Forum › Programmazione IEC 61131 (LogicLab) › Utilizzo variabili globali tra tasks diverse
- Questo topic ha 1 risposta, 1 partecipante ed è stato aggiornato l'ultima volta 6 anni fa da
Sergio Bertana.
-
AutorePost
-
Settembre 24, 2020 alle 11:28 am #57629
sacost
PartecipanteHo notato un comportamento un pò bizzarro nell’utilizzo di una variabile globale. Ho un programma che legge su di una coda MQTT (per realizzarlo ho usato l’esempio MQTTClient adattato allo scopo) e mi scrive (in funzione di ciò che legge sulla coda) su di una variabile globale di tipo INT di nome “Status” (i valori che può assumere sono 0, 1 o 2), il programma è definito nel task Back.
Questa variabile viene messa in input ad un programma (scritto in FBD) definito nel task Slow. All’interno di questo programma la variabile viene utilizzata da un FB (il nome della variabile di ingresso del FB è DOMO_IN).
La cosa strana è che andando a monitorare con lo strumento oscilloscopio fornito da Logiclab (vedi figura) a fronte di un comportamento normale della variabile status (quella in giallo che assume il valore intero 0) sulla variabile di input del FB (DOMO_IN) ho un andamento altalenante (nella figura rappresentato in celeste).
A cosa può essere dovuto questo comportamento?
Settembre 24, 2020 alle 11:41 am #57654Sergio Bertana
Amministratore del forumFaccio una premessa su come interagiscono tra di loro le varie tasks, normalmente è eseguita la task Back che viene interrotta ogni tempo definito (Default 10mS) dalla escuzione della task Slow, entrambe le tasks sono interrotte ogni tempo definito (Default 1mS) dalla esecuzione della task Fast.
Detto questo è importante che tutte le variabili condivise tra le varie tasks siano gestite in modo atomico, se per esempio una variabile INT che usa 2 bytes viene settata dalla task Back accedendo sui suoi singoli bytes può essere che arrivi l’esecuzione della task Slow proprio mentre si è modificato solo uno dei due bytes del valore e quindi il valore che “vede” la task è un valore diverso da quello settato dalla task Back.
Per capire perchè questo acccade nel tuo programma occorrebbe eseguire tests sul programma, ma in generale statements di assegnazione su variabili da 1 a 4 bytes (Quindi sono escluse quelle a 8 bytes e le stringhe) operano in modo atomico. Se in un programma ST in Back utilizzo una variabile globale di tipo UDINT per una somma Var:=Var+1, sono sicuro che questa variabile nella task Slow ha sempre valori coerenti.
Quindi quando non si è certi della atomicità di una variabile in una task per utilizzarrla in un’altra task è consigliabile trasferirne il valore su un’altra variabile. Per le variabili fino a 4 bytes basta fare una assegnazione VarSlow:=VarBack, mentre per le variabili di dimensioni maggiori e per le stringhe consiglio di utilizzare la funzione Sysmemmove.
-
AutorePost
- Devi essere connesso per rispondere a questo topic.