const
significa che la variabile non può essere modificata dal codice c, non che non può cambiare. Significa che nessuna istruzione può scrivere sulla variabile, ma il suo valore potrebbe comunque cambiare.
volatile
significa che la variabile può cambiare in qualsiasi momento e quindi non è possibile utilizzare valori memorizzati nella cache; ogni accesso alla variabile deve essere eseguito al suo indirizzo di memoria.
Poiché la domanda è contrassegnata come "incorporata" e supponendo che temp
sia una variabile dichiarata dall'utente, non un registro relativo all'hardware (poiché questi sono solitamente gestiti in un file .h separato), si consideri:
Un processore integrato che ha sia una memoria dati (RAM) volatile di lettura-scrittura che una memoria dati non volatile di sola lettura, ad esempio una memoria FLASH nell'architettura von-Neumann, dove i dati e lo spazio del programma condividono un bus di dati e indirizzi comune.
Se si dichiara const temp
di avere un valore (almeno se diverso da 0), il compilatore assegnerà la variabile ad un indirizzo nello spazio FLASH, perché anche se fosse assegnata ad un indirizzo RAM ha comunque bisogno di memoria FLASH per memorizzare il valore iniziale della variabile, rendendo l'indirizzo RAM uno spreco di spazio poiché tutte le operazioni sono di sola lettura.
Conseguentemente:
int temp;
è una variabile memorizzata nella RAM, inizializzata a 0 all'avvio (cstart), possono essere utilizzati valori memorizzati nella cache.
const int temp;
è una variabile memorizzata in FLASH (read-ony), inizializzata a 0 al momento del compilatore, possono essere usati valori memorizzati nella cache.
volatile int temp;
è una variabile memorizzata nella RAM, inizializzata a 0 all'avvio (cstart), i valori memorizzati nella cache NON verranno utilizzati.
const volatile int temp;
è una variabile memorizzata in FLASH (read-ony), inizializzata a 0 al momento del compilatore, i valori memorizzati nella cache NON verranno utilizzati
Ecco la parte utile:
Oggigiorno la maggior parte dei processori Embedded ha la capacità di apportare modifiche alla propria memoria non volatile di sola lettura per mezzo di uno speciale modulo funzione, nel qual caso const int temp
può essere modificato in fase di esecuzione, anche se non direttamente. Detto in altro modo, una funzione può modificare il valore all'indirizzo in cui temp
è memorizzato.
Un esempio pratico potrebbe essere quello di utilizzare temp
per il numero di serie del dispositivo. La prima volta che il processore integrato viene eseguito, temp
sarà uguale a 0 (o il valore dichiarato) e una funzione può utilizzare questo fatto per eseguire un test durante la produzione e, in caso di successo, chiedere di essere assegnato un numero di serie e modificare il valore di temp
mediante di una funzione speciale. Alcuni processori hanno un intervallo di indirizzi speciale con memoria OTP (programmabile una tantum) solo per questo.
Ma ecco la differenza:
Se const int temp
è un ID modificabile invece di un numero di serie programmabile una tantum e NON è dichiarato volatile
, un valore memorizzato nella cache potrebbe essere utilizzato fino al successivo avvio, il che significa che il nuovo ID potrebbe non essere valido fino al prossimo riavvio, o peggio ancora, alcune funzioni potrebbe utilizzare il nuovo valore mentre altri potrebbero utilizzare un vecchio valore memorizzato nella cache fino al riavvio. Se viene const int temp
dichiarato IS voltaile
, la modifica dell'ID avrà effetto immediato.
const volatile int temp;
useresti nell'ambito del blocco (cioè all'interno{ }
), non ha alcuna utilità lì.