Supongo que estás usando el mismo proceso de depuración que haría en este caso:
una de las primeras instrucciones en la rutina de interrupción enciende un LED,
y una de las últimas instrucciones en la rutina de interrupción apaga ese LED.
Luego usaste un osciloscopio de doble trazo con una sonda sujeta al pin apropiado para ver los bytes que ingresan al UART, y la otra sonda sujeta al pin que controla el LED.
Supongo que la rutina de interrupción del controlador UART termina con la instrucción de retorno de la interrupción (en lugar de usar la instrucción de retorno de la subrutina utilizada por las instrucciones normales).
Hay 4 cosas que pueden causar una larga latencia entre el final del último byte de un mensaje y el inicio del controlador UART:
-
Algún byte anterior en el mensaje que activa el controlador UART, y de alguna manera toma mucho tiempo antes de que se vuelvan a habilitar las interrupciones. Algunas personas estructuran sus rutinas de interrupción para que después de que el controlador UART termine de almacenar un byte en el búfer apropiado, verifique un montón de otras cosas antes de ejecutar la instrucción de retorno desde la interrupción: aumenta la fluctuación y la latencia, pero a veces esas personas sí De todos modos, porque mejora el rendimiento.
-
Algunas otras interrupciones tardan mucho tiempo en ejecutarse antes de volver a habilitar las interrupciones mediante la ejecución de la instrucción de retorno de interrupción. (Si puede hacer que todas y cada una de las interrupciones enciendan y apaguen algún otro LED, es bastante fácil ver en el visor si este es el problema o descartarlo).
-
Algunos códigos de no interrupción "temporalmente" apagando interrupciones. (Esto aumenta la inestabilidad y la latencia, pero la gente lo hace de todos modos, porque a menudo es la forma más fácil de evitar la corrupción de datos cuando tanto la interrupción como la tarea de fondo del bucle principal funcionan con la misma pieza de datos). (Si puede hacer que cada bit del código que hace esto encienda y apague algún otro LED, es bastante fácil ver en el o'scope si este es el problema o descartarlo).
-
Instrucciones que tardan mucho tiempo en ejecutarse.
La forma tradicional de averiguar exactamente qué está causando el problema
es guardar la versión actual de su código (está usando TortoiseHg o algún otro sistema de control de versiones, ¿verdad?)
y luego hackear y recortar deliberadamente una copia temporal de su código,
apagando y eliminando completamente el código unas pocas subrutinas a la vez,
volver a probar después de cada ronda de eliminaciones,
hasta que tengas un pequeño, pero técnicamente "completo" y ejecutable -
Programa que presenta el mismo problema.
Con demasiada frecuencia, las personas nos muestran fragmentos de un programa completo:
las partes que esas personas piensan son relevantes -
y no podemos ayudarlos porque una de las piezas que omitieron está causando el problema.
El proceso de reducir un programa a un caso de prueba pequeño es una habilidad muy útil,
porque a menudo mientras se pasa por ese proceso,
descubres rápidamente cuál es el problema real.
Una vez que tengas un programa tan pequeño, pero ejecutable,
por favor publícalo aquí.
Si descubres cuál es el problema durante ese proceso,
Díganos eso también, para que el resto de nosotros podamos evitar ese problema.