real operating examples embedded operating-system interrupt processor rtos

embedded - operating - Método basado en sondeo o interrupción



real time operating system examples (13)

¿Cuándo se debe usar el método de sondeo y cuándo se debe usar el método basado en interrupciones? ¿Hay escenarios en los que ambos se pueden usar?


A veces, realmente necesitas usar ambos. Por ejemplo, si los eventos son esporádicos pero vienen en una ráfaga de alta velocidad; es posible que deba responder primero a una interrupción y, luego, antes de volver a habilitar la encuesta de interrupción para ver si ya se ha producido otro evento, evitando algunos de los gastos generales del cambio de contexto de interrupción. Creo que la Interfaz de red Linux funciona de esta manera.


Al decidir sobre el sondeo o la interrupción, debe comprender completamente la naturaleza del evento que intenta seguir y su respuesta al mismo.

Las interrupciones no requieren procesamiento cuando no ocurre nada, pero requieren toda su atención cuando algo está sucediendo. Si el evento es externo y tiene bordes ruidosos o pulsos rápidos, esto puede causar dolores de cabeza importantes con interrupciones, debe tener cuidado con la configuración de las interrupciones.

En este ejemplo, la rutina de interrupción está respondiendo a un rayo láser que se ha aclarado y se está configurando para un evento donde se bloquea:

BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/ /*Set the beam interrupt for the next clear to blocked event*/ BEAM_INTR_EDGE = CLEAR_TO_BLOCKED; BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/

Hay 2 puntos débiles de este código: 1) Si el rayo láser se ha bloqueado nuevamente antes de que se borre el indicador de interrupción (BEAM_INTR_FLAG = FALSE;). La interrupción se habrá perdido y el código no estará sincronizado con el estado del rayo láser.

2) Cuando se configuran interrupciones en la rutina de fondo o para una prioridad más alta que la prioridad en la que está activado este código, se debe tener cuidado al habilitar la interrupción. Si el indicador de interrupción ya estaba configurado (incorrectamente) antes de habilitarlo, la rutina de interrupción se llamaría incorrectamente tan pronto como se habilitara y tal vez para el borde incorrecto.

La manera más fácil de arreglar 1) es verificar dos veces después de configurar la interrupción, si ha ocurrido, forzar una interrupción. Para arreglar 2) mover la habilitación de las interrupciones después de la doble verificación:

/*Set the beam interrupt for the next clear to blocked event*/ BEAM_INTR_EDGE = CLEAR_TO_BLOCKED; BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/ /*Double check beam state to see if it has already gone blocked*/ if (BEAM_STATE == BEAM_BLOCKED) { BEAM_INTR_FLAG = TRUE; /*Force the interrupt to re-enter the ISR after exiting*/ } BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/

El forzamiento de la interrupción hace que el sistema funcione con la misma máquina de estado, solo forzándola a girar manualmente para cubrir el punto ciego.

Básicamente:

Set the edge to detect the next interrupt event Clear the interrupt flag if (the event has already occurred) { Set the interrupt flag to force the interrupt } Enable the interrupt

Si el tiempo de la respuesta a un evento debe ser constante (por ejemplo, 1ms +/- 10us después de que la línea de entrada sube, transmite la señal de evento), las interrupciones suelen ser las mejores.

Si el tiempo de la respuesta a un evento debe ser dentro de un tiempo determinado (por ejemplo, dentro de 1 ms de la línea de entrada que sube, transmita la señal de evento), entonces sería mejor una interrupción.

El problema con las interrupciones es que debes empezar a pensar en el subprocesamiento y que dos códigos pueden acceder a los mismos datos al mismo tiempo.

Las interrupciones también son buenas para permitir que los procesadores entren en modos de bajo consumo (inactivo / inactivo, etc.) mientras esperan que ocurra algo.

Habiendo dicho que todas las encuestas pueden dar respuestas de tiempo muy apretadas a los eventos si solo hay una cosa para el procesador, a menudo el hardware de interrupción demora varios ciclos para responder a un evento mientras que un ciclo de sondeo apretado lo hará.

Si el evento no es cronometrado y potencialmente ruidoso (por ejemplo, alguien presionando un interruptor), el sondeo permite un filtrado simple sin perder las transiciones a largo plazo. Un error común es sondear varias veces al configurar las cosas:

void fnInitialiseSystem(void) { if (MODE_INPUT == MODE_A) /*First polling of the MODE_INPUT*/ { PR2 = PR2_MODE_A; } else { PR2 = PR2_MODE_B; } OpenTimer2( TIMER_INT_ON & T2_PS_1_1 & T2_POST_1_8 ); if (MODE_INPUT == MODE_A) /*Second polling of the MODE_INPUT*/ { CurrentMode = MODE_A; PROBE_INT_EDGE = CLEAR_TO_BLOCKED; } else { CurrentMode = MODE_B; PROBE_INT_EDGE = BLOCKED_TO_CLEAR; } }

En el ejemplo anterior, MODE_INPUT es un interruptor externo; si se sondean las dos veces MODE_INPUT, el comportamiento es inesperado. Al leer este tipo de señales, es mejor utilizar el filtrado para decidir el estado a largo plazo de la entrada y realizar acciones en la versión filtrada.

Por ejemplo, con el cambio de rebote del interruptor simplemente verifique un interruptor regularmente (cada 1ms?) Y si varios de ellos (digamos 16) son diferentes (interruptor cerrado) de la versión filtrada (interruptor abierto) luego actualice el resultado y realice la acción requerida . Tenga cuidado con el aliasing de señal, ¡una señal oscilante puede parecer estable!

Un ejemplo de uso de sondeo e interrupciones es, una vez más, para el uso de una entrada que no cambia a menudo pero que es ruidosa cuando lo hace. Una vez más, un interruptor es un buen ejemplo de esto: el código puede configurar una interrupción para verificar un cambio en el estado del interruptor, cuando ocurre una interrupción, entonces el interruptor puede sondearse regularmente hasta que el estado del interruptor sea "estable" (ya sea cambiado estado o de vuelta a lo que era). Esto brinda la ventaja de una baja sobrecarga de procesamiento cuando no ocurre nada y de un filtrado de ruido cuando algo sucede.



Básicamente, el modo encuestado se utiliza en caso de que el modo de interrupción no esté disponible debido a razones de hardware o software. Por lo tanto, el modo de interrupción es más preferible desde el punto de vista del consumo de energía, el rendimiento, etc. (de acuerdo con Paul R). El modo de sondeo también se puede usar en prototipos, para núcleos sin periféricos necesarios y para algunos propósitos de prueba.


El modo de sondeo puede ser útil en sistemas con eventos de alta frecuencia, donde la sobrecarga asociada con la entrada y la salida de manejadores de interrupción utiliza más ciclos de CPU que el simple sondeo. Por ejemplo, el sondeo podría usarse en un enrutador de IP para maximizar el ancho de banda de la CPU disponible para el procesamiento de paquetes.


El sondeo debe evitarse siempre que sea posible, ya que normalmente consume muchos ciclos de CPU innecesariamente (a menos que (a) solo va a sondear durante un tiempo corto o (b) puede permitirse dormir durante un tiempo razonable en su ciclo de sondeo ) Perder los ciclos de la CPU no solo es malo desde el punto de vista del rendimiento, sino que también aumenta el consumo de energía, lo que puede ser un problema para las aplicaciones integradas que funcionan con baterías.


Hay muchas limitaciones de diseño que pueden impulsar la decisión. Mi aplicación tiene una combinación de interrupción y sondeo:

  • Las fuentes de reloj externo e interno provocan interrupciones; es fundamental marcar con una marca de tiempo con precisión para que podamos sincronizarlas.
  • Los mensajes seriales entrantes provocan interrupciones. Los FIFO recibidos deben recibir servicio antes de que se desborden.
  • Los mensajes salientes disparan interrupciones cuando el FIFO está parcialmente vacío; debe rellenarse antes de que se desactive.
  • Los semáforos establecidos del ISR que se sondean en segundo plano. Esto tiene 2 ventajas:
    • El cálculo necesario para manejar eventos entrantes puede ser largo; si se dejara en el ISR, podría retrasar otros ISR más allá de los plazos del servicio.
    • Los eventos pueden ser secuenciados. Por ejemplo, un ciclo de sondeo puede garantizar que el cálculo X siempre ocurra entre la recopilación de datos de ADC y el análisis de mensajes entrantes, incluso si a veces el mensaje llega un poco antes de lo esperado.

Las interrupciones son preferidas cuando se requiere baja latencia. Si sondeas para alguna condición N veces por segundo, en promedio descubrirás esa condición a tiempo la mitad de 1 / N después de que realmente haya sucedido.

El sondeo a veces se prefiere cuando se requiere un tiempo determinista absoluto. Por su propia naturaleza, las interrupciones pueden ocurrir en momentos impredecibles y complicar en gran medida el análisis de tiempo, mientras que con los sistemas encuestados, es relativamente fácil hacer declaraciones comprobables sobre la satisfacción del plazo.


No desea tener a su host esperando en el bucle ocupado durante mucho tiempo, y también el sondeo puede volverse ineficiente cuando se realizan comprobaciones frecuentes para datos que no están allí con frecuencia. Entonces, si el anfitrión y el dispositivo son rápidos, entonces sondean muy rápido.


Si el evento de interés es:

  1. Asincrónico
  2. Urgente
  3. Infrecuente

entonces un manejador basado en interrupciones tendría sentido.

Si el evento de interés es:

  1. Sincrónico (es decir, usted sabe cuándo esperarlo dentro de una ventana pequeña)
  2. No es urgente (es decir, un intervalo de sondeo lento no tiene efectos negativos)
  3. Frecuente (es decir, la mayoría de sus ciclos de votación crean un ''hit'')

entonces las encuestas podrían ser una mejor opción.

Otras consideraciones incluyen si está escribiendo un controlador de dispositivo para un sistema operativo o simplemente está escribiendo un código bare metal sin soporte de subprocesos. En situaciones de metal desnudo, la CPU a menudo solo hace bucles cuando no está ocupada, por lo que también podría estar sondeando algo.


Siempre use una interrupción. De esa forma nunca perderás datos. En aplicaciones impulsadas por eventos o roscados, incluso las señales más lentas deben ser accionadas por interrupciones.

El único momento en que debe usar el sondeo es cuando usa un programador y los almacenamientos intermedios en su hardware son lo suficientemente profundos para garantizar que no se pierdan datos.


la respuesta corta es usar el método de interrupción cuando el sondeo es demasiado lento. (Por demasiado lento, quiero decir si el sondeo pierde datos, es necesario el método de interrupción)


Es mucho mejor ir con el Interrupt based design comparación con el polling based porque la encuesta basada es defectuosa en el sentido de que espera que los datos se devuelvan en cada encuesta. Ahora, usted podría decir que voy a sortear este caso en el que una sola encuesta me ha devuelto un error, pero ¿por qué diablos desperdiciar todos los ciclos de CPU sondeando por algo cuando también podría devolver un error? Y esperar que una encuesta falle es un escenario práctico del producto.

Interrupt based designs tienen aún más sentido cuando hay muchas capas de funciones involucradas en una única encuesta. Para mí es una práctica común: ¿seguirías preguntando ( sondeando ) a tu amigo una y otra vez todos los días si él tiene la información que necesitas O simplemente le dirías que me interrupt cuando tengas la información que necesito. Creo que hacemos lo correcto en el día a día pero no nos damos cuenta.

Pero las interrupt based architectures cuando se implementan requieren una comprensión sólida del publish-subscribe design principle . Y, cuando se hace en los dominios de la aplicación, requieren que la parte del código que envía interrupciones esté realmente bien escrita. Esto es bueno ya que exprime la complejidad en un solo lugar también.

Además de lo anterior, a continuación se detallan las otras ventajas que la arquitectura basada en sondeos le ofrece sin costo:

  • Asynchrounous
  • Se adapta bien en caso de eventos / actualizaciones poco frecuentes
  • Actualizar solo cuando haya escenarios de datos disponibles
  • Mejor manejo y manejo de errores
  • Mejor uso de ciclos de CPU
  • Mejor duración de la batería mgmt
  • Mantiene a los oyentes libres de complejidad debajo

Siempre que diseñe sw y tenga esta opción, siempre debe elegir un diseño basado en interrupt basado en polling , porque un diseño basado en interrupt puede llenarse para una situación basada en polling utilizando oyentes, pero un diseño basado en sondeo nunca puede cumplir el requisito que requiere interrupt diseño.

Lo que sigue es una breve matriz de comparación:

-INTERRUPT- -LOOP- Speed fast slow Eficiency good poor CPU waste low high multitasking yes no complexity high low debugging +/- easy easy critical in time excellent poor code bloat low impact high impact