Volátil: ¿qué veré en el depurador?

programación


Hola !

He estado aprendiendo cómo funciona volátil porque uso microcontroladores. En parte necesito saber cómo funciona. Aprendí cómo funcionan los sitios web cuando se trata de código pseudoensamblador. Agregaré esta información para mostrar lo que sé y lo que quería mordisquear.

Por lo tanto, volátil detiene al compilador para optimizar una variable que cree que no se actualizará en un gran resumen ni que el compilador optimice otros procesos.

Algo como esto :

No volátil :

move the value of variable m into internal register A
label:
if A != 1 goto done
goto label
done:
carry on

Entonces la variable m se lee una vez y nunca leerá el valor m de nuevo a pesar de que m puede cambiar su valor. Piensa que nunca será cambiado.

Volátil :

label:<br />
move the value of variable 'm' to internal register A<br />
if A != 1 then go to done<br />
go to label<br />
done:

Aquí con volátil leerá cada vez qué variable m tiene dentro.

¿Cómo se ve con ISR (ruta de interrupción)?
Este es un ejemplo que también leí en sitios web que me dicen mucho cómo funciona.

Cita:

* en el bucle principal – justo antes de que se ejecute ISR – tiene el valor “X” en el registro1
* Se inicia ISR, ISR guarda el valor del registro1 (X) en SRAM (¿pila?)
* ISR usa el registro 1 con sus propios valores, carga con abc, cambia a def… cualquier cosa, realiza operaciones
* antes de volver a main() restaura el valor “X” en el registro1.

El valor de las variables se guarda en la memoria/RAM, etc. en la que las operaciones se almacenan en registros. Esto me dejó muy claro que ISR solo actualiza el valor de la variable en la memoria, no en el registro, porque los registros vuelven a su estado anterior antes de la modificación.

Fresco

Ahora lo que quería saber es cómo funciona volátil, etc. porque en parte sé cómo funciona. Quiero saber cómo lo veré en el depurador.

Usemos este ejemplo:

int A = 0;

int main()
{
	while(A != 1)
	{
	//Do something
	}
}

void ISR()

{
	A++;
}

Aquí hay un código simple sin volátil. Quería saber cómo se comportará el depurador.

int A = 0;

int main()
{
	while(A != 1)
	{
	//Do something
	}
}

void ISR()

{
	A++; <----- breakpoint
}

Establecí un punto de interrupción aquí.
La variable A se actualiza de 0 a 1. Pero el bucle while no leerá la variable A, sino que está optimizado y leerá el valor 0 de su registro como dije al principio.

Bien, entonces la variable A se actualizó de 0 a 1 y el depurador mostrará que el valor de A es 1 y no 0.

int A = 0;

int main()
{
	while(A != 1) <----- breakpoint
	{
	//Do something
	}
}

void ISR()

{
	A++;
}

Entonces, después de ISR, el depurador ahora salta al principal y se detiene en un momento porque este es mi próximo punto de interrupción.

¿Qué valor de A será? ¿Seguirá siendo “1”, como dije al principio, cómo funciona todo? A debería seguir siendo 1 y el while debería dejarme pasar porque aunque A = 1 y el bucle while dice A! = 1, aún debería pasar porque while lee los datos del registro y no de la variable A porque no es volátil.

¿Por qué necesito este conocimiento? En el futuro, si lo olvido y sucede algo extraño, esto me ayudará a saber si olvidé algo así. Por qué comenzó el ciclo while aunque la condición no coincidía.

Creo que entiendes lo que estoy tratando de decir aquí.

Lo que he probado:

No sabía cómo se vería porque mi microcontrolador no optimizó las variables no volátiles como si fueran volátiles así que busco conocimiento sin verlo normalmente ;D

Solución 1

Me imagino que la optimización depende del compilador. Estoy muy familiarizado con el compilador gcc y el código que se proporciona aquí;

C++
int A = 0;

int main()
{
	while(A != 1) <----- breakpoint1
	{
	//Do something
	}
}

void ISR()

{
	A++; <----- breakpoint2
}

El valor en el punto de interrupción2 será 0->1 y el valor en el punto de interrupción1 obtendrá “el valor se optimizó” porque el valor estaba en un registro y el valor desaparece una vez que la PC abandona el ISR.

C++
volatile int A = 0;

int main()
{
	while(A != 1) <----- breakpoint1
	{
	//Do something
	}
}

void ISR()

{
	A++; <----- breakpoint2
}

Cuando se utiliza la palabra clave volátil, el valor en el punto de interrupción2 será n->n+1 y el valor en el punto de interrupción1 será n y el valor aparecerá en el depurador.

コメント

タイトルとURLをコピーしました