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.
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).
AlfaGoku
Spehro Pefhany
AlfaGoku
sam buca
Spehro Pefhany
Super gato