ISR: ¿marcar o no marcar?

6

Por lo que leo en internet, debemos responder a las interrupciones lo más rápido posible, al programar microcontroladores; y que se deben evitar las banderas porque tienden a agravarse con el tiempo.
Pero la forma más rápida de responder a una interrupción es mediante el uso de una marca (solo necesita cambiar el valor booleano de la variable y continuar el código dentro de la función principal). ¿Cómo resolver este problema? ¿Debería usarse una máquina de estado en cualquier interrupción para evitar banderas o eso no importa?

    
pregunta Rui Lima

2 respuestas

24

Diseñar según las reglas generales que encontraste en Internet en algún lugar es una mala idea. La forma correcta es entender los problemas, hacer intercambios inteligentes.

No hay nada de malo en que un sistema tome una interrupción, borre la condición del hardware y luego establezca una bandera para que el código de primer plano haga el resto del procesamiento cuando llegue a ese punto. El peligro es que el código de primer plano podría no llegar a ese punto por un tiempo, y si se produce la misma condición antes de eso, la información podría perderse. O, si algo debe manejarse con baja latencia o fluctuación de fase, es probable que desee manejarlo en la rutina de interrupción.

Nuevamente, entienda las compensaciones. El código de interrupción se ejecuta inmediatamente después de que se produjo la condición, a expensas de todo lo demás que el procesador deba hacer en ese momento. ¿Vale la pena? Eso depende. ¿Cuánto retraso puede tolerar en el manejo de la condición? ¿Qué tan importante es que el código de primer plano no se retrase? Debería ser obvio que no hay una única respuesta universal para esto. Es altamente dependiente de la aplicación particular.

Por ejemplo, si parte del trabajo de los procesadores es responder a una secuencia de comandos en serie que se le envía a 115.2 kbaudios, los bytes se pueden recibir tan rápido como cada 87 µs. La rutina de interrupción podría simplemente establecer un indicador para que la rutina de primer plano sepa que debe leer un byte desde el UART, pero eso requeriría que el código de primer plano compruebe el indicador al menos cada 87 µs. En muchos casos, eso sería difícil. Una buena compensación para muchos casos (de nuevo, esto podría no coincidir con ningún caso en particular) sería que la rutina de interrupción tome el byte del UART, borre la condición del hardware y rellene el byte en un FIFO de software. El código de primer plano luego vacía la FIFO en la medida de lo posible, probablemente en ráfagas entre otras tareas que pueden llevar más tiempo que el tiempo de byte de 87 µs.

Por otra parte, la rutina de interrupción para un botón de usuario solo puede realizar el desmonte y establecer una marca cuando el botón se encuentra en un nuevo estado. El sistema solo necesita responder al botón en tiempo humano, que puede ser de muchos milisegundos. Si el código de primer plano comprueba todos los eventos al menos cada pocos milisegundos, entonces no es necesario que la rutina de interrupción realice más procesos de procesamiento que los descritos.

En general, la rutina de interrupción debe hacer lo que sea necesario para el procesamiento inmediato de latencia o de fluctuación de fase debido al evento, luego establecer el estado para que el procesamiento que pueda responder más lentamente se pueda realizar más tarde desde el código de primer plano. Una vez más, sin embargo, no se limite a usar eso como una regla de oro. Entender porqué. Entonces no necesitarás ninguna regla de oro.

    
respondido por el Olin Lathrop
0

No, no es necesario responder a las interrupciones lo antes posible. Supongamos que tiene una interrupción para avisarle cuando un búfer de transmisión UART está vacío. Si no tiene nada que necesita, envíe, entonces puede esperar todo el tiempo que desee para reparar esa interrupción.

Creo que lo que has leído es que las rutinas de servicio de interrupción deben ser lo más cortas posible. Esto suele ser cierto, ya que las rutinas de servicio de interrupción prolongadas pueden retrasar la respuesta a otras interrupciones o provocar fluctuaciones en el tiempo de respuesta.

No sé lo que quieres decir con "banderas". Si se refiere a una variable estática, entonces no debería haber ningún problema al escribir en una variable de este tipo dentro de un ISR y usar su valor fuera del ISR. Sin embargo, si tiene una variable compartida , una que se puede modificar dentro de un ISR así como fuera de un ISR, entonces puede tener problemas. La forma más sencilla de manejar esto es deshabilitar todas las interrupciones cuando un fragmento de código modifique la variable compartida y hacerlo lo más rápido posible.

Le he dado respuestas muy simples, aunque el campo de la multitarea en sistemas integrados incluye muchas soluciones posibles a estos problemas. A menos que pueda hacer una pregunta más específica, será difícil darle mejores respuestas.

    
respondido por el Joe Hass

Lea otras preguntas en las etiquetas