Variables compartidas entre interrupciones y tarea principal [cerrado]

-5

Esto se ha convertido en una de las partes más confusas para mí en el desarrollo integrado. Recientemente, he escrito un software para medir el período de tiempo de los pulsos usando la captura de entrada y esa variable, por ejemplo, period_u16, estoy usando en la pantalla principal para cálculos adicionales utilizando factores de multiplicación. Ahora este valor viene correctamente durante unos 10 segundos y de repente, el tipo de caída va a un valor no válido y vuelve. Este ciclo sigue repitiéndose. Sospeché que tanto la interrupción como la tarea principal compartían la variable y moví todos los cálculos a la interrupción. Entonces está bien. ¿Es la forma correcta? Tengo varias otras interrupciones similares a esto. ¿Qué debo hacer? No quiero hacer todos los cálculos en interrupciones.

    
pregunta rajesh

3 respuestas

1

Dos posibilidades:

  1. Como Dave indicó que podría tratarse de un problema de reinversión, su naturaleza regular significa que probablemente sea eso o alguna frecuencia de latido entre la tasa de interrupción y la tasa de bucle del código principal.
  2. El valor está cambiando cuando no esperas que lo haga.

Un problema de reinversión puede estar en el valor principal o en algún cálculo que esté realizando en él.

El segundo problema es si tienes algo como esto:

// if you haven't marked this as volatile then you're lucky it ever worked
volatile uint16_t period_u16;

onInterrupt () {
  period_u16 = new_value;
}

main() {
  while(true) {
    uint16_t my_number = doSomeCalculation(period_u16);
    // Invalid results if interrupt triggers here
    result = my_number - period_u16;
    ... some other code ...
  }
}

es decir, Realiza algunos cálculos basados en period_u16 y luego hace referencia a period_u16 por segunda vez, asumiendo que no ha cambiado entre ellos. Si la interrupción se dispara en el lugar equivocado, entonces period_u16 habrá cambiado entre esas líneas y los resultados serán incorrectos.

Para evitar esto, deshabilite las interrupciones durante la parte sensible o haga una copia local. Si la interrupción está configurando dos valores diferentes (o una sola variable que es más grande que el ancho del procesador), entonces tiene que hacer ambos, deshabilitar interrupciones, hacer una copia y luego volver a habilitarlos. Si no te arriesgas a obtener resultados inconsistentes.
Si el valor calculado es necesario dentro de la interrupción la próxima vez que se dispare, deberá mantener las interrupciones desactivadas hasta que se realicen los cálculos.

    
respondido por el Andrew
1

Sí, si su tarea principal es leer-modificar-escribir alguna variable, y un controlador de interrupciones también podría modificar esa variable, tiene un problema potencial. Si es una variable de 16 bits y un procesador de 8 bits (por ejemplo), incluso podría terminar con un byte de la variable escrita por la interrupción y el otro byte por la tarea principal.

Una solución es que la tarea principal bloquee las interrupciones mientras se realiza la lectura-modificación-escritura.

Otra solución es que la interrupción no modifique la variable, sino que deje un mensaje que indique a la tarea principal que la modifique cuando sea seguro hacerlo.

    
respondido por el The Photon
0

no trabaje (modifique) con la misma variable utilizada en ISR, en lugar de eso, use una copia de la misma en la rutina principal, y use indicadores para indicar que hay un nuevo valor disponible

ISR modifica la variable y establece el indicador, el enrutamiento principal que comprueba el indicador copia la variable en la variable local y restablece el indicador, la rutina principal funciona con la copia local.

También verifique el tipo de variable utilizada, como mantener valores de 16 bits en la variable de 8 bits, que truncan los datos

    
respondido por el Raj

Lea otras preguntas en las etiquetas