Allocare variabile anche se non utilizzata...

Ciao a tutti, avrei la necessità di allocare una variabile non utilizzata ad un indirizzo di memoria predefinito.
Per l'allocazione ad un indirizzo predefinito non ci sono problemi, con la direttiva "#pragma location = 0xnnnnnn" ho risolto.
Il problema è che questa variabile è inizializzata ma non utilizzata direttamente dallo sketch e quindi il compilatore, vedendo che non è utilizzata non gli assegna nessuna cella di memoria.
Sono quindi costretto a scrivere del codice fake per far credere al compilatore che la variabile sia utilizzata.
La soluzione del codice fake funziona, ma non mi piace.
Esiste una direttiva tipo "#pragma qualcosa" che obblighi il compilatore a riservare memoria in ogni caso per questa variabile?
Grazie.

Stefano

... purtroppo, salvo fare un finto utilizzo, non trovo alcun modo che faccia mantere una variabile non "referenziata".

Ho provato con i #pragma per disabilitare l'ottimizzazione, ho provato a metterla volatile, ho provato a dichiarala statica ed a dargli l'attributo "used" ... nulla, se non viene referenziata da qualche parte viene eliminata.

Se ti viene in mente qualche altra idea fammela sapere che mi interessa :slight_smile:

Guglielmo

Non basta dichiararla volatile?

SukkoPera:
Non basta dichiararla volatile?

Sukko, ma l'hai letto bene il mio post ? ? ? :smiley: :smiley: :smiley:

Guglielmo

No, sto suonando :D.

OK, qua c'è una soluzione ma fa uso esplicito del linker. Al momento non ho trovato di meglio.

SukkoPera:
OK, qua c'è una soluzione ma fa uso esplicito del linker. Al momento non ho trovato di meglio.

Si, la KEEP l'avevo trovata anche io, ma applicarla con l'IDE di Arduino è praticamente impossibile senza ogni volta mettere le mani nei suoi files di configurazione ... e poi non so se è applicabile al caso di una variabile che è definita in una ben precisa posizione di memoria (come nel suo caso) ... ::slight_smile:

Guglielmo

SukkoPera:
Non basta dichiararla volatile?

Anche io pensavo bastasse questo.
perchè dite che non funziona? Se non funziona che altro senso ha dichiarare una variabile "volatile"?
Ho appena fatto delle prove e secondo me funziona.
Ovvio che se dichiari una variabile byte può essere che non te ne accorgi se alloca o meno perchè la memoria viene allocata a blocchi non a singoli byte e quindi magari sull'IDE la dimensione totale non cambia.

NO, mi spiace, non funziona, ho fatto tutte le prove, vai a vederti il disassemblato e vedrai che non ce ne è traccia.

Non solo, basta che dichiari una variabile GLOBALE "volatile" unsigned long, che è da 4 bytes e guardi il risultato della copilazione di un programma vuoto ...

Con l'IDE 1.8.9 un programma vuoto occupa comunque 9 bytes si globali, sia che ci sia la tua "volatile" che non ci sia, ma, basta che la usi (es variabiel=+1) ed immediatamente la variabile appare e l'occupazione sale a 13.

In realtà il problema NON è nel compilatore ... è il linker che non vedendola referenziata da nessuna parte comunque la elimina. Per risolvere bisognerebbe provare a giocare con lo script del linker, creare una sezione "KEEP" e metterci dentro la variabile ... dovrebbe andare, ma ... fare queste cose con l'IDE è da diventare matti ... meglio lasciar perdere ed usare appunto una finta istruzione inutile che la tocca così non viene più eliminata.

Guglielmo

Cioè dici che basta fare un test a vuoto e si risolve? Oppure una semplice assegnazione? Questo comportamento lo fa solo con le variabili normali o anche con i vettori?
Perchè per avere un po' più di spazio ho fatto test con vettori e a me risulta corretto il comportamento.
Però se dici che hai guardato il compilato non c'è tanto da discutere a meno di grappini in quantità pre test :wink:

Io non capisco il problema
Se lo OP necessita di questo è perché ha una parte del programma già in oggetto, che usa un indirizzo non modificabile
E quindi "comunque" deve poi lavorare di linker
Tanto vale metterci mano subito

O sbaglio?

Standardoil:
E quindi "comunque" deve poi lavorare di linker

Non lo dice, dice che assegna l'indirizzo con un #pragma del compilatore.

Non ricodo né se ci sia, né quale sia ... ::slight_smile:

Comunque la cosa si può sempre fare senza scomodare il linker ...

int *var = (int*)0x40001000;
*var = 4;

... e piazzi il valore 4 nell'indirizzo di memoria 0x40001000 :wink:

Guglielmo

Io ho fatto questo test:

long x = 0;
long y = 0;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  x = random(0, 9);
  y = random(0, 9);
  if (x == 0) {
    Serial.print("X = 0");
  }
  if (y == 0) {
    Serial.print("Y = 0");
  }
}

Sketch 2020 byte e Variabili globali 208 byte
Poi ho sostituito y con x per avere lo stesso codice ma non usare mai y.

...
void loop() {
  // put your main code here, to run repeatedly:
  x = random(0, 9);
  x = random(0, 9);
  if (x == 0) {
    Serial.print("X = 0");
  }
  if (x == 0) {
    Serial.print("Y = 0");
  }
}

Sketch 2004 byte e Variabili globali 204 byte
L'ottimizzatore ha fatto il suo lavoro, probabilmente ha pure evitato il doppio test visto che cala anche la dimensione del codice, oltra a ridurre di 4 byte le variabili globali perchè non ha ritenuto di dover allocare y
Tutto secondo i piani.
Ora dichiaro semplicemente y come volatile

long x = 0;
volatile long y = 0;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  x = random(0, 9);
  x = random(0, 9);
  if (x == 0) {
    Serial.print("X = 0");
  }
  if (x == 0) {
    Serial.print("Y = 0");
  }
}

Sketch 2004 byte e Variabili globali 208 byte
L'ottimizzazione sul codice permane ma ha riallocato y anche se non è usata.

Scusate se insisto ma vorrei capire bene perchè queste cose tendono ad inquietarmi assai.

>maubarzi: allora capiamoci ...

uint8_t pippo[100];

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

... produce come risultato della copilazione:

Global variables use 9 bytes (0%) of dynamic memory, leaving 16375 bytes for local variables. Maximum is 16384 bytes.

(... vedi 16KB disponibili perché, al momento, ho l'IDE per una 1284P, ma non cambia nulla con il 328P)

Aggiungiamo l'attributo "volatile":

volatile uint8_t pippo[100];

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

... e la compilazione da sempre:

Global variables use 9 bytes (0%) of dynamic memory, leaving 16375 bytes for local variables. Maximum is 16384 bytes.

... ovvero, se ne frega altamente.

Ma se tocchiamo anche solo un elemento in modo del tutto innocuo ...

volatile uint8_t pippo[100];

void setup() {
  // put your setup code here, to run once:
  pippo[0]+=0;
}

void loop() {
  // put your main code here, to run repeatedly:

}

allora la compilazione da:

Global variables use 109 bytes (0%) of dynamic memory, leaving 16275 bytes for local variables. Maximum is 16384 bytes.

... come vedi ha conservato i 100 bytes in più.

Guglielmo

Quindi basta inizializzarla alla dichiarazione visto che il mio test, invece, da risultato differente ma differisce perchè io inizializzo a zero alla dichiarazione.

Scusate se sporco il thread, ma aggiungo la domanda: a che serve questa variabile che non viene utilizzata ?
MI sfugge lo scopo.

Aspetta, aspetta, ho scoperto una cosa molto interessante ...
... dipende dalla toolchain utilizzata !!!!!!!!!!!!!!!

Io stavo facendo le prove con schede differenti dalla UNO ed il risultato era che non c'era verso di evitare l'ottimizzazione.

Se scelgo come scheda la UNO (e quindi un'altra toolchain) il comportamento è del tutto diverso !!!!!!!!!!!!

Risultato ... il comportamneto è funzione della toolchain utilizzata e anche della sua versione.

Mi aspetto quindi comportamenti diversi con versioni dell'IDE diverse che utilizzano versioni diverse della toolchain ... ::slight_smile:

Guglielmo

nid69ita:
Scusate se sporco il thread, ma aggiungo la domanda: a che serve questa variabile che non viene utilizzata ?

… su Arduino non o so … altrove può servire in fase di “debug” per esaminare facilmente con il debugger particolari aree di memoria che magari sono mappate con registri o porte di I/O.

Guglielmo

Quindi il comportamento del piccione (leggi volatile) dipende dal grado di umidità, dal fatto che il giorno sia pari o dispari, dall'ora e dalla temperatura dell'aria e da dove hai parcheggiato l'auto?

P.S.
Ho provato ad eliminare l'inizializzazione ed in effetti non cambia nulla, quindi non dipende da quello.

Allora ... semplice programma:

volatile uint32_t pippo = 0;
volatile uint32_t pluto = 0;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

IDE 1.5.6r2:

Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.

e, se tocco con il solito +=0 una variabile, allora la salva (solo quella).

IDE 1.6.5r5

Stesso comportamento

IDE 1.6.13

Cambia il comportamento e basta dichiarale volatili per averle conservate.

Tutte prove fatte con Arduno UNO ... ci sarebbe da provare con altre schede che usano toolchain differenti ...

Guglielmo