10 de abril de 2011

Temporizadores y condiciones de carrera

Un alumno me ha preguntado sobre las condiciones de carrera en los temporizadores. Por ejemplo cuando un temporizador está en modo "contador" para contar piezas, va almacenando el valor en dos registros, que como ya sabéis, son "TH0" y "TL0" para el temporizador "T0".

Para conocer el valor de la cuenta en un momento dado, el micro mira primero la parte baja del temporizador "TL0" (para ello consume un poco de tiempo). Instantes después mira la para alta del temporizador "TH0" y entonces es cuando ya se tiene el valor real de la cuenta que se almacena en una variable de tu programa.

Pero, ¿qué ocurre si entre las dos instrucciones de lectura, se produce una interrupción y el programa debe saltar a otra zona de código? Para cuando la ejecución prosiga y si el temporizador no se ha detenido, el valor del temporizador puede haber cambiado, habrá seguido incrementándose y la cuenta podría ser incoherente.

Un caso típico sería cuando tenemos: "TH0=11111111" y "TL0=11111111". Si se lee primero "TL0" tendremos "11111111". Imagina que en ese momento el programa salta a otra zona de código. El temporizador no se detiene y se producirá un desbordamiento (la cuenta empezará de cero).

Cuando a la vuelta de la interrupción (pasado un tiempo desconocido) se lea "TH0", se podría tener "00000000" y el valor de "TL0" que habíamos guardado tampoco seria el real (que ha vuelto a empezar de cero incrementándose).

Para evitar estas "condiciones de carrera", antes de realizar una lectura del valor del temporizador, siempre se detendrá con la instrucción "TR0=0" y se leerá entonces los registros. De este modo se evitarán las condiciones de carrera (resultados incoherentes), poniéndose en marcha inmediatamente con "TR0=1". En la figura puedes ver como se aplica en este ejemplo de contador de vehículos:



Condiciones de carrera por Wikipedia

No hay comentarios: