5 votos

Interrupción de reinicio - ¿Inicio o fin de ISR?

Estoy trabajando en un uC que tiene interrupciones configuradas para varios FIFO presentes en el uC. Cada FIFO está conectado a un bus común y puede recibir datos de forma independiente (en cualquier punto del tiempo). Ahora, cada vez que un FIFO recibe 8 bytes de datos se llama a un único ISR y en el ISR tengo que identificar qué FIFO causó la interrupción.

Lo que me gustaría saber es si la Interrupción debe reiniciarse al principio de la función ISR o al final.

Problema1 que puede surgir : Supongamos que reinicio la interrupción al principio del ISR, si otro FIFO se llena mientras estoy en el ISR, ya que he reiniciado la interrupción, ¿qué pasará? ¿Volverá a entrar automáticamente en el ISR después de que ejecute la última línea del ISR o se producirá algún otro problema?

Problema2 que puede surgir : Supongamos que reinicio la interrupción al final de la ISR, si se llena otro FIFO mientras estoy en la ISR, como todavía no he reiniciado la interrupción, ¿volveré a entrar en la ISR que he ejecutado la última línea de la ISR?

¿Cuál es el mejor lugar para reiniciar la interrupción? Por favor, disculpe si mi comprensión de las interrupciones es errónea.

6voto

RelaXNow Puntos 1164

Tu pregunta no se limita a los FIFO ni a ningún hardware que provoque interrupciones en particular.

Borre las condiciones de interrupción tan pronto como sepa que va a manejar esa condición.

En el caso de las interrupciones vectorizadas, esto ocurre muy al principio de la rutina de interrupción, ya que se conoce la causa de la interrupción por el mero hecho de estar ahí. Podrías hacer el guardado normal de estado antes de cualquier otra cosa, pero borrar la condición de interrupción debería ser lo siguiente que hagas.

En el caso de una rutina de interrupción compartida, primero hay que comprobar qué dispositivo está causando la interrupción. Una vez que has encontrado un dispositivo con su condición de interrupción establecida, pasas al código para manejar ese dispositivo. Borrar la condición de interrupción debería ser normalmente lo primero que hace este código.

La razón principal para borrar la condición de interrupción antes de dar servicio a la interrupción es no perder una interrupción. Supongamos que haces lo contrario. El dispositivo interrumpe, tú lo manejas, luego ocurre otro evento justo antes de que borres la condición de interrupción. Ahora la condición para el nuevo evento ha sido borrada, pero tu código no lo sabe. El estado de ese dispositivo ahora está colgado porque necesita servicio y probablemente no puede generar nuevos eventos, pero el evento que causó la condición actual ya ha sido borrado. Ups.

Tenga en cuenta que el dispositivo al que acaba dando servicio en una rutina de interrupción compartida puede no ser el que causó originalmente la interrupción. Múltiples dispositivos podrían tener sus condiciones de interrupción establecidas para el momento en que los revises. Generalmente los reviso en un orden fijo, manejo el primero que encuentro que necesita servicio, luego salgo de la interrupción. Si otro dispositivo también tiene su condición de interrupción establecida, entonces el procesador causará otra interrupción. Algunas personas vuelven atrás y hacen un bucle hasta que ningún dispositivo tiene su condición establecida, pero esto hace que la interrupción sea más larga en la mayoría de los casos.

También tenga cuidado al comprobar dispositivos que puedan tener su interrupción enmascarada en tiempo de ejecución. Un ejemplo común es la interrupción de transmisión UART. Normalmente se desactiva cuando se vacía el FIFO de salida, y se activa justo después de introducir algo en el FIFO. En muchos procesadores, enmascarar la interrupción sólo evita que se genere la propia interrupción, no que se indique la condición de interrupción. Si algún otro dispositivo causa una interrupción compartida y compruebas primero el transmisor UART, pensarás erróneamente que necesita servicio ya que su condición de interrupción está activada aunque su capacidad de interrupción esté enmascarada. Para cualquier dispositivo que pueda tener su capacidad de interrupción enmascarada, también tienes que comprobar esa máscara e ignorar el dispositivo si está enmascarado. Esto puede parecer obvio, pero es un error común de los novatos.

0voto

filo Puntos 1

Es mejor borrar la bandera de interrupción ("resetear la interrupción") al principio del ISR porque no perderás otra interrupción si ocurre mientras la primera invocación aún está en ejecución.

Un ejemplo rápido: recibes datos usando algún periférico, el ISR tarda algún tiempo en procesarlos, si recibes un segundo byte mientras el ISR está todavía en marcha y borras el flag al principio sólo obtendrás una segunda interrupción. Si lo borras al final, perderás datos.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X