const
significa que la variable no puede ser modificada por el código c, no que no pueda cambiar. Significa que ninguna instrucción puede escribir en la variable, pero su valor aún puede cambiar.
volatile
significa que la variable puede cambiar en cualquier momento y, por lo tanto, no se pueden usar valores en caché; cada acceso a la variable debe ejecutarse en su dirección de memoria.
Dado que la pregunta está etiquetada como "incrustada" y suponiendo que temp
es una variable declarada por el usuario, no un registro relacionado con el hardware (ya que estos generalmente se manejan en un archivo .h separado), considere:
Un procesador integrado que tiene memoria de datos de lectura y escritura (RAM) volátil y memoria de datos de solo lectura no volátil, por ejemplo, memoria FLASH en la arquitectura von-Neumann, donde los datos y el espacio del programa comparten un bus común de datos y direcciones.
Si declara const temp
tener un valor (al menos si es diferente de 0), el compilador asignará la variable a una dirección en el espacio FLASH, porque incluso si se le asignó una dirección RAM, todavía necesita memoria FLASH para almacenar el valor inicial de la variable, lo que hace que la dirección RAM sea una pérdida de espacio ya que todas las operaciones son de solo lectura.
En consecuencia:
int temp;
es una variable almacenada en la RAM, inicializada a 0 al inicio (cstart), se pueden usar valores en caché.
const int temp;
es una variable almacenada en (lectura) FLASH, inicializada a 0 en el momento del compilador, se pueden usar valores en caché.
volatile int temp;
es una variable almacenada en la RAM, inicializada a 0 al inicio (cstart), los valores en caché NO se utilizarán.
const volatile int temp;
es una variable almacenada en (de lectura) FLASH, inicializada a 0 en el momento del compilador, los valores almacenados en caché NO se utilizarán
Aquí viene la parte útil:
Hoy en día, la mayoría de los procesadores integrados tienen la capacidad de realizar cambios en su memoria no volátil de solo lectura mediante un módulo de función especial, en cuyo caso const int temp
se puede cambiar en tiempo de ejecución, aunque no directamente. Dicho de otra forma, una función puede modificar el valor en la dirección donde temp
se almacena.
Un ejemplo práctico sería utilizarlo temp
para el número de serie del dispositivo. La primera vez que se ejecuta el procesador integrado, temp
será igual a 0 (o el valor declarado) y una función puede usar este hecho para ejecutar una prueba durante la producción y, si tiene éxito, solicitar que se le asigne un número de serie y modificar el valor de temp
por medio de una función especial. Algunos procesadores tienen un rango de direcciones especial con memoria OTP (programable una vez) solo para eso.
Pero aquí viene la diferencia:
Si const int temp
es un ID modificable en lugar de un número de serie programable por única vez y NO se declara volatile
, se puede usar un valor en caché hasta el próximo inicio, lo que significa que el nuevo ID podría no ser válido hasta el próximo reinicio, o peor aún, algunas funciones podría usar el nuevo valor mientras que otros podrían usar un valor almacenado en caché más antiguo hasta reiniciar. Si se const int temp
declara voltaile
, el cambio de ID entrará en vigor de inmediato.
const volatile int temp;
en el alcance del bloque (es decir, dentro{ }
), no tiene uso allí.