MSP430: ¿cómo permitir que el ISR del temporizador interrumpa el ISR de RX en serie?

4

Estoy trabajando en un MSP430 conectado a la PC a través de una serie. El MSP430 también se comunica con algunas otras placas mediante una interfaz en serie modificada. Estoy usando el periférico del temporizador para golpear el bit de la serie, y estoy usando el UART para hablar con la PC.

Cuando los comandos llegan desde la PC, la interrupción USCIAB0RX_VECTOR se ejecuta, y mientras se ejecuta, bloquea otras interrupciones. Sin embargo, algunas veces mi rutina de RX en serie tarda un poco, lo que retrasa la interrupción del temporizador y desactiva la interfaz bit-bang.

En el ISR de RX en serie, me gustaría permitir que la interrupción del temporizador continúe siendo reparada, pero me gustaría evitar que la RX en serie se interrumpa a sí misma (lo que no debería ser posible para mi aplicación específica, pero quisiera proteger contra esto por si acaso)

  • ¿Debería simplemente enmascarar manualmente la interrupción de RX en serie en la parte superior de la ISR en serie y luego habilitar interrupciones globales?
  • ¿También necesito desenmascarar la interrupción de RX en serie al final?
  • ¿Debo borrar manualmente los indicadores de solicitud de interrupción?
  • Después de que regrese el ISR del temporizador, ¿continuará ISR en serie y luego regresará al bucle principal?

  • ¿Debo considerar alguna condición de raza potencial?

  • ¿Hay una solución mejor?
  • ¿Hay un artículo sobre la interrupción y la interrupción? (Ya he leído sobre interrupciones anidadas en la guía del usuario)
pregunta Marcus10110

3 respuestas

3

No conozco este MCU específico, pero la pregunta es bastante genérica.

La respuesta obvia a todos los problemas como estos es mantener los ISR lo más delgado posible. A lo sumo, deberían rellenar los datos en un búfer de anillo, que luego es procesado por el programa principal. (Una MCU con DMA hubiera sido aún mejor, pero ¿no creo que tenga DMA en MSP430?)

Si el ISR sigue siendo demasiado lento después de tales optimizaciones, no tiene otra opción más que hacer lo que sugiere: habilite la máscara de interrupción global en la parte superior del ISR de UART y deje que la interrupción de prioridad más alta tenga prioridad. Sin embargo, tenga en cuenta que cuando permite que más interrupciones se sumen a un ISR que ya se está ejecutando, se permite una mayor profundidad de pila.

  

¿También necesito desenmascarar la interrupción de RX en serie al final?

¿Supongo que debe hacer eso desde el ISR sin importar la naturaleza de la aplicación? Así es como funciona la mayoría de las MCU. Y sí, si toca la máscara de interrupción global, tendrá que eliminar la interrupción específica una vez que haya terminado de servirla, es decir, después de haber copiado los datos recibidos en las variables locales.

  

Después de que el temporizador ISR regrese, ¿continuará ISR en serie y luego volverá al bucle principal?

Si ha cambiado la máscara de interrupción global, entonces sí.

  

¿Hay alguna condición de carrera que deba considerar?

Siempre se debe tener en cuenta esto cuando se compartan datos entre un ISR y otra cosa. No importa si el ISR solo escribe y el programa principal solo lee, etc., a menos que pueda garantizar que cada acceso sea atómico, lo que generalmente no puede hacer a menos que escriba el código en el ensamblador.

En un lenguaje de alto nivel, puede que tenga que usar alguna variable de semáforo. Cómo se implementa esto depende de la aplicación. Depende particularmente de si puede permitirse perder algunos datos del ISR o si tiene que capturar todos los datos.

  

¿Hay una mejor solución?

DMA o una MCU multinúcleo.

    
respondido por el Lundin
2

Mueva sus rutinas de manejo de paquetes RX desde el vector de interrupción. La función de interrupción debe ser lo más corta posible (en su caso, coloque un byte en un búfer para su procesamiento posterior y señale al programa principal que hay un byte pendiente). Decidir sobre las prioridades, ¿qué interfaz es más importante? Periférico o PC? ¿Puede uno de ellos esperar?

    
respondido por el Lior Bilia
0

Una posible solución es servir el UART desde la interrupción del temporizador, sin dejar que se interrumpa por sí sola. Verificando si un personaje ha llegado a la UART y almacenarlo en un búfer se puede hacer con algunas instrucciones. A continuación se le da servicio al bit banging. Salir de la interrupción del temporizador permite que el código de modo de usuario se ejecute hasta la próxima interrupción del temporizador. Cuando no esté en bit bit, puede optar por habilitar la interrupción de UART y aumentar el tiempo entre las interrupciones del temporizador para ganar más tiempo en el modo de usuario.

    
respondido por el ghellquist

Lea otras preguntas en las etiquetas