Diferencia entre const y const volátil

Si declaramos una variable como volatile cada vez que se actualiza el valor actualizado
Si declaramos una variable como const , el valor de esa variable no cambiará

Entonces const volatile int temp;
¿Cuál es el uso de declarar la temp variable como arriba?
¿Qué sucede si declaramos como const int temp ?

El código no permitirá que un objeto marcado como const volatile cambie (se generará un error debido al calificador const ), al menos a través de ese nombre / puntero en particular.

La parte volatile del calificador significa que el comstackdor no puede optimizar ni reordenar el acceso al objeto.

En un sistema integrado, esto se usa generalmente para acceder a registros de hardware que el hardware puede leer y actualizar, pero no tiene sentido escribir (o puede ser un error al que escribir).

Un ejemplo podría ser el registro de estado para un puerto serie. Varios bits indicarán si un personaje está esperando a ser leído o si el registro de transmisión está listo para aceptar un nuevo carácter (es decir, – está vacío). Cada lectura de este registro de estado puede generar un valor diferente según lo que haya ocurrido en el hardware del puerto serie.

No tiene sentido escribir en el registro de estado (dependiendo de la especificación de hardware en particular), pero debe asegurarse de que cada lectura del registro resulte en una lectura real del hardware, utilizando un valor en caché de una lectura anterior ganada Te cuento sobre los cambios en el estado del hardware.

Un ejemplo rápido:

 unsigned int const volatile *status_reg; // assume these are assigned to point to the unsigned char const volatile *recv_reg; // correct hardware addresses #define UART_CHAR_READY 0x00000001 int get_next_char() { while ((*status_reg & UART_CHAR_READY) == 0) { // do nothing but spin } return *recv_reg; } 

Si estos punteros no se marcaron como volatile , podrían surgir un par de problemas:

  • la prueba while loop podría leer el registro de estado solo una vez, ya que el comstackdor podría asumir que lo que apunta nunca cambiará (no hay nada en la prueba de bucle while o loop que pueda cambiarlo). Si ingresó la función cuando no había ningún carácter esperando en el hardware UART, podría terminar en un bucle infinito que nunca se detuvo incluso cuando se recibió un carácter.
  • la lectura del registro de recepción podría ser movida por el comstackdor antes del ciclo while – nuevamente porque no hay nada en la función que indique que *recv_reg es cambiado por el ciclo, no hay razón por la cual no pueda leerse antes de ingresar al ciclo.

Los calificadores volatile aseguran que estas optimizaciones no sean realizadas por el comstackdor.

  • volatile le dirá al comstackdor que no optimice el código relacionado con la variable, generalmente cuando sabemos que puede cambiarse desde “afuera”, por ejemplo, por otro hilo.
  • const le dirá al comstackdor que está prohibido que el progtwig modifique el valor de la variable.
  • const volatile es algo muy especial que probablemente veas usado exactamente 0 veces en tu vida ™. Como es de esperar, significa que el progtwig no puede modificar el valor de la variable, pero el valor puede modificarse desde el exterior, por lo que no se realizarán optimizaciones en la variable.

No es porque la variable sea const porque no haya cambiado entre dos puntos de secuencia.

Constness es una promesa que usted hace para no cambiar el valor, no es que el valor no cambie.

He necesitado usar esto en una aplicación incorporada donde algunas variables de configuración se encuentran en un área de memoria flash que puede ser actualizada por un gestor de arranque. Estas variables de configuración son ‘constantes’ durante el tiempo de ejecución, pero sin el calificador volátil el comstackdor optimizaría algo como esto …

 cantx.id = 0x10<<24 | CANID<<12 | 0; 

... precomputando el valor constante y usando una instrucción de ensamblaje inmediata, o cargando la constante desde una ubicación cercana, de modo que cualquier actualización del valor de CANID original en el área de flash de configuración sería ignorada. CANID tiene que ser const volátil.

En C, const y volátil son calificadores de tipo y estos dos son independientes.

Básicamente, const significa que el valor no es modificable por el progtwig.

Y volátil significa que el valor está sujeto a cambios repentinos (posiblemente desde fuera del progtwig).

De hecho, el estándar C menciona un ejemplo de statement válida que es const y volátil. El ejemplo es

“Extern const volátil int real_time_clock;”

donde real_time_clock puede ser modificable por hardware, pero no puede asignarse, incrementarse ni decrementarse.

Entonces ya deberíamos tratar const y volátil por separado. Además, este calificador de tipo también se aplica a struct, union, enum y typedef.

const significa que la variable no puede ser modificada por el código c, no es 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 la temp es una variable declarada por el usuario, no un registro relacionado con el hardware (ya que generalmente se manejan en un archivo .h separado), considere:

Un procesador integrado que tiene memoria de datos de lectura y escritura volátil y memoria de datos no volátil de solo lectura, por ejemplo memoria FLASH en la architecture von-Neumann, donde los datos y el espacio del progtwig comparten un bus de datos y direcciones común.

Si declara que const temp tiene un valor (al menos si es diferente de 0), el comstackdor asignará la variable a una dirección en el espacio FLASH, porque incluso si se le asignó una dirección RAM, aún necesita memoria FLASH para almacenar el valor inicial de la variable, por lo que la dirección de la RAM es una pérdida de espacio ya que todas las operaciones son de solo lectura.

En consecuencia:

int temp; es una variable almacenada en RAM, inicializada en 0 al inicio (cstart), se pueden usar valores en caché.

const int temp; es una variable almacenada en FLASH (de lectura), inicializada a 0 en el momento del comstackdor, se pueden usar valores en caché.

volatile int temp; es una variable almacenada en RAM, inicializada en 0 al inicio (cstart), los valores en caché NO serán utilizados.

const volatile int temp; es una variable almacenada en FLASH (de lectura), inicializada a 0 en el momento del comstackdor, NO se usarán valores en caché

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 por medio de un módulo de función especial, en cuyo caso const int temp puede modificarse en tiempo de ejecución, aunque no de manera directa. Dicho de otra manera, una función puede modificar el valor en la dirección donde se almacena la temp .

Un ejemplo práctico sería usar la temp para el número de serie del dispositivo. La primera vez que se ejecuta el procesador integrado, la 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 es exitosa, solicite que se le asigne un número de serie y modifique el valor de temp por medio de una función especial. Algunos procesadores tienen un rango de direcciones especial con memoria OTP (progtwigble por única vez) solo para eso.

Pero aquí viene la diferencia:

Si const int temp es una ID modificable en lugar de un número de serie progtwigble por única vez y NO se declara volatile , se puede usar un valor en caché hasta el siguiente inicio, lo que significa que la nueva ID podría no ser válida hasta el próximo reinicio, o incluso peor aún, algunas funciones pueden usar el nuevo valor, mientras que otras pueden usar un valor caché anterior hasta que se reinicie. Si const int temp declara voltaile , el cambio de ID tendrá efecto inmediatamente.

Este artículo analiza los escenarios en los que desea combinar const y calificadores volátiles.

http://embeddedgurus.com/barr-code/2012/01/combining-cs-volatile-and-const-keywords/

Puede usar const y volátil juntos. Por ejemplo, si se supone que 0x30 es el valor de un puerto que se modifica solo por condiciones externas, la siguiente statement evitará cualquier posibilidad de efectos secundarios accidentales:

 const volatile char *port = (const volatile char *)0x30; 

Usamos la palabra clave ‘const’ para una variable cuando no queremos que el progtwig la modifique. Mientras que cuando declaramos una variable ‘const volátil’ le estamos diciendo al progtwig que no la cambie y al comstackdor que esta variable puede cambiarse inesperadamente a partir de una entrada proveniente del mundo exterior.

En términos simples, el valor en la variable ‘const volátil’ no puede modificarse mediante progtwigción, pero puede ser modificado por hardware. Aquí lo volátil es evitar cualquier optimización del comstackdor.