Gestión de interrupciones - Proyectos AVR grandes

3

Esto es para los más experimentados que están por ahí.

Actualmente estoy involucrado con un proyecto AVR grande (usando ATMega328) y se está confundiendo con respecto a las interrupciones.

El proyecto involucra interrupciones de las siguientes fuentes

  • USART
  • TWI
  • SPI
  • Interrupción externa (INT0 e INT1)

Con tantas fuentes de interrupciones y el hecho de que las interrupciones globales se deshabilitan cuando se ejecuta un ISR, temo perder las interrupciones que pueden activarse cuando mi código está dando servicio a otra interrupción.

Entonces, ¿hay algún método más estructurado para gestionar interrupciones en un proyecto grande?

    
pregunta Ankit

2 respuestas

7

La primera regla de usar interrupciones: mantenerlas muy cortas.

Cuando se produce una interrupción, ya sea que esté habilitada o no, y si actualmente está dando servicio a una interrupción o no, se establece un indicador de Interrupción activada. Cada interrupción tiene uno de estos indicadores asociados (como SPSR.SPIF). Eso siempre se establece tan pronto como se dispara la interrupción.

El sistema de interrupciones luego realiza un ciclo a través de las interrupciones en busca de cualquier indicador de interrupción que se haya establecido, y si la interrupción está habilitada, salta al ISR.

Lo hará sin importar cuánto tiempo hace que ocurrió la interrupción.

Entonces, la pregunta no es "¿Me perderé una interrupción porque estoy en un ISR", pero "¿Me perderé interrupciones sucesivas porque estoy en un ISR".

Entonces, primero debe calcular la velocidad máxima a la que puede ocurrir una interrupción desde una fuente.

Luego, verifica sus rutinas ISR y se asegura de que nunca excedan ese período mínimo de interrupción. Considere mover el código de un ISR y, en su lugar, establecer indicadores para que su ciclo principal realice operaciones en su lugar.

En un entorno más complejo (¡5 interrupciones son NO lotes!), si los recursos lo permiten, puede considerar la creación de una cola de eventos de interrupción, donde se agrega un evento a una lista de eventos entrantes cuando se produce una interrupción, y su bucle principal es libre de procesar esos eventos en orden. Es posible que deba usar colas con diferentes prioridades para diferentes interrupciones.

Eso no es realmente factible en una MCU pequeña como la '328P, ya que carece de los recursos para administrar efectivamente ese tipo de colas.

    
respondido por el Majenko
2
  

Tengo miedo de perder las interrupciones que pueden activarse cuando mi código está dando servicio a otra interrupción.

Majenko declaró que "El sistema de interrupciones luego realiza un ciclo a través de las interrupciones en busca de cualquier indicador de interrupción que se haya establecido, y si la interrupción está habilitada, salta al ISR". Esto no es del todo cierto porque:

  

Las interrupciones tienen prioridad de acuerdo con su posición del vector de interrupción. Cuanto menor sea la dirección del vector de interrupción, mayor será la prioridad.

Esto significa que una fuente de interrupción puede "morir de hambre". Una vez que se completa un ISR, el controlador preferirá las interrupciones de alta prioridad. Dependiendo de la frecuencia de interrupción, puede suceder que siempre haya un conjunto de indicadores de interrupción de alto nivel, esencialmente bloqueando un prio inferior uno permanentemente.

Mantener el ISR corto y saber su tiempo de ejecución es un buen consejo.

5 interrupciones en realidad no son muchas, pero aún así requieren cuidado en un sistema simple de prioridad fija.

AVR XMEGA, por ejemplo, lo lleva a otro nivel. Tengo un proyecto XMEGA que tiene que manejar 22 fuentes de interrupción diferentes (4xUART tx / rx = 8 + 4 temporizadores + 8 ADC completos + 2 otros). Sin embargo, el XMEGA presenta un "controlador de interrupción multinivel programable". Esto le permite asignar manualmente uno de los tres niveles de interrupción a cada interrupción (dentro de ellos, la prioridad del número de vector de interrupción aún cuenta). Además, puede activar un esquema de prioridad de round-robin, que aborda el problema de "inanición" antes mencionado.

  

Para evitar el posible problema de inanición por interrupciones de bajo nivel con prioridad estática, donde es posible que no se sirvan algunas interrupciones, el PMIC ofrece una programación de turnos completos

Con respecto a tu pregunta original:

  

Entonces, ¿hay algún método más estructurado para gestionar interrupciones en un proyecto grande?

Depende de las capacidades de su sistema. Para un controlador como el ATMega328 con una gestión de interrupciones impulsada por una prioridad estática simple, asegúrese de que no haya interrupciones de hambre y mantenga presionado "short" y "conozca su tiempo de ejecución". Para un controlador como el XMEGA, hay más planificación involucrada porque solo tienes más control. Debe distribuir cuidadosamente las prioridades y considerar el uso de funciones como "round robin".

    
respondido por el Rev1.0

Lea otras preguntas en las etiquetas