¿La interrupción de la recepción de datos de un microcontrolador con una interrupción de mayor prioridad provoca la pérdida de datos?

Me gustaría saber qué sucedería si una terminal en serie enviara una gran cantidad de datos a un PIC/AVR, por ejemplo, a través de una interrupción USART, que luego fue interrumpida por una interrupción de mayor prioridad como un temporizador, que pospondría los datos. transferir. ¿Se perderían los datos? ¿O el terminal serial tiene un búfer antes de enviar y retiene los datos hasta que volvemos a la interrupción de recepción?

Por ejemplo, estoy usando un atxmega128a1 y estoy usando esta interrupción para recibir bytes:

//interrupt to receive a byte 
ISR(USARTC0_RXC_vect){                      //ISR for when receive flag is set
if(FIFO_Put(&RxFIFO, USARTC0_DATA)){        //put data into receive FIFO
    USARTC0_STATUS |= USART_RXCIF_bm;       //write 1 to clear bit
}
}

Si envío una gran cantidad de bytes a través de un terminal serie al mismo tiempo, esta interrupción se activará muchas veces para recibir cada byte.

También tengo una interrupción de temporizador de mayor prioridad que puede tardar mucho tiempo en completarse:

ISR(TCC0_OVF_vect){
    AXISid n = X;
    static BOOL cycle;
    TimerAxisInterrupt(n, &cycle);
} 

Para reiterar, mi pregunta es, si la interrupción de mayor prioridad ocurre durante una transferencia de recepción de datos grande, ¿se perderá algún dato?

Si es relevante: estoy enviando los datos USART a través de rs232 usando un convertidor lógico max3232. Tengo las líneas de protocolo de enlace y las líneas RTS CTS en bucle de modo que solo estoy usando las líneas Rx y Tx.

Respuestas (1)

Suponiendo que no haya protocolo de enlace, no perderá ningún dato si la interrupción de UART se atiende con la frecuencia suficiente para evitar que se desborde cualquier búfer de hardware que tenga. Por lo general, es al menos un carácter, pero pueden ser muchos caracteres según el chip (los chips más potentes tienden a tener más bytes de búfer).

En mi experiencia, no puede depender del protocolo de enlace XON/XOFF cuando el tamaño del búfer es pequeño y el remitente es una PC; puede enviar bastantes caracteres antes de que se ahogue el flujo.

Entonces, si la profundidad del búfer es de un carácter, y la velocidad en baudios es tal que un carácter toma 1 ms, entonces no debe quitar más de 1 ms en su interrupción de mayor prioridad o podría perder datos (un poco menos porque tiene que tener en cuenta el tiempo en el UART ISR para responder y extraer el carácter entrante del búfer, y también debe tener en cuenta la situación en la que la interrupción UART está en curso cuando se interrumpe (observe que ocurre justo antes y justo después de leer el carácter entrante)

Hay varias formas de lidiar con la situación en la que debe tener dos interrupciones con una respuesta rápida. Una forma (generalmente la mejor) sería no hacer demasiado en su temporizador de interrupción; las rutinas de servicio de interrupción se utilizan mejor para entrar y salir rápidamente). Otra sería implementar un búfer en la memoria y establecer su interrupción UART en la prioridad más alta (simplemente rellene el carácter recibido en una cola circular, incremente el tamaño del búfer del módulo del puntero de escritura y regrese; puede verificar la igualdad si lee y escribe punteros a ver si la cola está vacía). Todavía hay otros enfoques según los requisitos y el procesador: tal vez no necesite tener la rutina del temporizador con una prioridad tan alta, o tal vez cambie dinámicamente la prioridad una vez que haya terminado las cosas críticas y luego vuelva a cambiarla a alta prioridad. ,

Los procesadores más potentes tendrán búferes más grandes o DMA que permitirán que el procesador recorra muchos caracteres antes de que se produzca la pérdida de datos.

TL; DR Puede predecir esto perfilando su interrupción del temporizador y el código de interrupción ISR para encontrar el tiempo máximo de ejecución y compararlo con el tiempo mínimo para llenar el búfer (a la velocidad máxima en baudios).

Si la interrupción del temporizador se utiliza para funciones de temporización como la generación de pulsos, tiempos de espera, etc., ¿no debería darse la máxima prioridad a la interrupción del temporizador?
@AkshayImmanuelD Depende totalmente de la aplicación. Si puede soportar un poco de nerviosismo por la interrupción de UART, tal vez no. A veces no es intuitivo. Por ejemplo, tengo un controlador muy complejo con muchas operaciones críticas, pero la interrupción de mayor prioridad es cambiar un transductor de sonido. Las otras operaciones son mucho más importantes pero no tan urgentes y una fluctuación de unos pocos microsegundos no tiene ningún efecto práctico sobre ellas (pero lo escucharía en el sonido).
Estoy de acuerdo. Si puede permitir una tolerancia de tiempo de espera, no veo ninguna razón por la que la interrupción del temporizador deba tener la máxima prioridad. Pero, de nuevo, totalmente específico de la aplicación
@SpehroPefhany gracias por su respuesta. Entonces, para asegurarme de que entiendo, tengo una velocidad de transmisión de 19200 con 10 bits por carácter (1 inicio, 1 parada, 8 bits de datos). Así que eso es aproximadamente 521us por personaje. Por lo tanto, para evitar la pérdida de datos, mi(s) interrupción(es) de mayor prioridad no deberían tomar más de 521us, o con un reloj de 32MHz, no deberían tener más de 16667 instrucciones. ¿Correcto?
@SamBucca Más como la suma de los dos tiempos de ejecución de ISR, incluida la latencia y el guardado de contexto, si solo tiene un byte de búfer. Además, algunas instrucciones pueden tardar más de un ciclo.
@SpehroPefhany: En algunos casos en los que se debe poder generar un valor precalculado al instante en respuesta a algún evento no muy frecuente, pero donde el cálculo del siguiente valor llevaría un tiempo, puede ser útil tener un alto -la interrupción de prioridad responde al evento, emite el valor, publica una interrupción de baja prioridad y regresa; la interrupción de baja prioridad podría entonces calcular el siguiente evento sin bloquear otras interrupciones de prioridad media.