ISR - Alcance vs. Contador

3

Básicamente, tengo un programa que incrementa el contador cada vez que recibo una interrupción. El código es algo como esto:

void ISR(void)
{
  static int counter=0;
  counter++;
  GPIO_SET(PIN1); // set the gpio pin
  DELAY(10); // some short delay so that we can see it in scope nicely
  GPIO_RESET(PIN1);//reset the pin
  clearFlag();

}

El evento (en realidad es un temporizador) que dispara este ISR también desencadena algunas otras cosas (DMA, básicamente cada 8 eventos debería recibir una interrupción DMA, esto es por diseño del código)

En el código ISR de DMA, tengo otra configuración / restablecimiento de pin GPIO. Ahora:

  • Cuando miro los eventos (salida del temporizador en un pin y conmutador DMA), en el alcance veo que 8 eventos corresponden a cada ciclo DMA. Hasta ahora tan bueno.

  • Cuando veo el PIN1 en el alcance, solo veo 6 eventos, dos de ellos se pierden y esto es muy consistente, siempre es el mismo 2.

No tengo nada que lleve mucho tiempo en el ISR y estoy sorprendido por el hecho de que la rutina ISR no se recibe cada vez que recibo el evento.

Espero que este sea un problema de configuración por mi parte, cualquier idea sobre dónde buscar. Esto es algo tan básico que debería funcionar. Este es un nuevo procesador de ST, por lo tanto, existe la posibilidad de que sea un error, pero me niego a creer que algo de lo básico no funciona.

La parte es nueva STM32F2 ... El compilador es Crossworks ... Sin optimizaciones, código de depuración ... ejecutar la configuración de la fábrica, nada de lujos.

Realmente estoy buscando un indicador de dónde buscar ... No espero que ustedes se depuren por mí ... ¿Qué causaría esto? Bajo diferentes circunstancias, asumiría que el tiempo de ISR es el problema, pero deshabilito el código ISR con #if 0 para evitar estos problemas de tiempo. Por lo tanto, no es tiempo. ¿Qué más podría ser?

    
pregunta Frank

5 respuestas

0

Alguien, un muy hombre sabio en este foro una vez id , "Esté siempre preparado para probar sus suposiciones. El error generalmente está en lo que está asumiendo trabajos". Este fue mi caso también. Resulta que se estaba ejecutando una interrupción de mayor prioridad en ese momento y evitando que se llame a mi ISR.

Mi error fue el exceso de confianza de que no se trataba de un problema de tiempo y no se verificaban a fondo las prioridades de interrupción. Aprecio a todos los chicos de apoyo.

    
respondido por el Frank
3

Poner una demora real en una rutina de servicio de interrupción es altamente inusual. Puede que no sea su problema, ya que parece tener motivos para creer que su ISR se está completando a tiempo, pero la práctica habitual con los ISR es entrar y salir lo más rápido posible.

Solo para risas, ¿qué sucede si, en lugar de establecer un retraso de ajuste, simplemente alterna su pin de salida, sin retraso?

    
respondido por el JustJeff
2

Sin más detalles, es imposible determinar qué puede estar yendo mal. Aquí hay algunas cosas que probaría:

  1. Usa tu depurador. Aunque no estoy familiarizado con la micro que está utilizando, muchas arquitecturas le permitirán realizar ciclos de pasos únicos precisos. Es muy tedioso realizar todas las instrucciones de montaje en un solo paso, pero es posible que solo tenga que hacerlo una vez.
  2. Cambia los niveles de optimización en tu compilador. Si el sistema se comporta de manera diferente, el problema puede estar relacionado con el tiempo.
  3. Eliminar la dependencia entre las partes asíncronas del código. Por ejemplo, ¿la función / macro GPIO_SET también se usa en el ISR de DMA y están los gpios en el mismo puerto? Es probable que establecer un GPIO implique un ciclo de lectura / modificación / escritura y si el ISR de DMA también realiza esta operación y puede interrumpir el ISR del temporizador, es posible que tenga una condición de carrera.

Para probar su teoría de que el ISR del temporizador no se llama con la frecuencia esperada, elimine todas las referencias a las rutinas de GPIO y habilite los contadores de interrupción en los ISR de DMA y del temporizador. Deje el sistema en funcionamiento durante algún tiempo y luego verifique si la relación entre los contadores es de 1: 6 o de 1: 8, como espera.

Si le faltan interrupciones de temporizador, es probable que su tiempo de respuesta para manejar la interrupción sea demasiado grande en algunas circunstancias, con el temporizador desbordado mientras la interrupción anterior aún está pendiente.

    
respondido por el Austin Phillips
1

Sería útil si supiéramos más sobre el temporizador. A menudo, los temporizadores funcionan libremente y usted usa un registro de comparación para generar la interrupción. Si el temporizador se desplaza o se reinicia, es posible que la comparación no coincida con ese ciclo y que no se llame a su ISR.

Intente leer el valor del temporizador en ambos ISR (supongo que se llama a un ISR en la interrupción DMA) y asegúrese de que el temporizador tenga sentido en cada caso. Dado que es posible que el temporizador no se detenga mientras usa un depurador, es posible que deba simplemente almacenar los valores en una matriz y registrarlos cuando la matriz se llene para no alterar la prueba agregando grandes retrasos en la impresión.

    
respondido por el Klox
1

Me preocuparía que te estuvieras perdiendo esos dos eventos porque algo sigue sucediendo con las interrupciones deshabilitadas. ¿Puede hacer algo como alternar un GPIO diferente a la velocidad máxima en el proceso de primer plano (o cambiarlo cada vez que habilite / deshabilite las interrupciones para que coincidan con esa configuración), para saber cuándo no está en un ISR utilizando un canal diferente del alcance? ? O algo similar con DMA que todavía mantiene las cosas ocupadas.

Si hay otro registro de temporizador o contador de ciclos de CPU, puede leerlo en el ISR y registrarlo de alguna manera (quizás incluso como un mínimo / máximo usando solo dos ubicaciones) y ver si está obteniendo una latencia de interrupción extrema.

    
respondido por el Chris Stratton

Lea otras preguntas en las etiquetas