Borrar / reconocer las interrupciones activadas por nivel

1

Estoy confundido con la eliminación / confirmación de las interrupciones activadas por nivel en un SoC. Cuando se dispara una interrupción de nivel, la eliminación se debe realizar en el controlador de interrupción o en el controlador de bus (controlador spi, controlador gpio) o en el propio dispositivo periférico. Si tengo que despejar el dispositivo periférico, entonces debo conectar una línea desde mi núcleo de SoC al dispositivo, ¿correcto? ¿Alguien también podría dar un ejemplo del dispositivo SPI que utiliza el nivel de activación?

    
pregunta mindentropy

1 respuesta

1

Con una interrupción activada por flanco, puede salir de manera segura del ISR de inmediato sin ninguna acción adicional, ya que la interrupción no se activará hasta que el pin de interrupción baje (o sea alto, según sea el caso) nuevamente.

Con una interrupción activada por nivel, se asume que el periférico que causa la interrupción no restablece el nivel que entra en el pin de interrupción por sí mismo, ya que no puede conocer la latencia del ISR. Si esta interrupción funcionó de esta manera, y el microcontrolador se configuró para bloquear la condición de la señal alta o baja, esto sería lo mismo que una interrupción activada por el borde.

Por lo tanto, el microcontrolador debe hacer que el nivel se restablezca, ya sea dentro del ISR o en el nivel base que sigue al ISR.

Dependiendo del periférico, puede haber dos formas de restablecer la señal de interrupción. Uno es cuando el periférico tiene un pin específico para este propósito, generalmente llamado reconocimiento de interrupción. Pulsar este cable de alto a bajo y atrás (o viceversa) restablece el nivel de interrupción. Este es el único método disponible si el microcontrolador no tiene una interfaz disponible para manipular registros dentro del periférico.

La otra forma de restablecer una interrupción activada por nivel, que es mucho más común, es restablecer (o establecer) un bit de reconocimiento de interrupción en uno de los registros del dispositivo. Este bit lo establecerá el propio periférico cuando se genere la interrupción, y el microcontrolador lo restablecerá (o viceversa). Obviamente, esto solo tiene sentido si hay registros internos que pueden ser direccionados por el microcontrolador, ya sea a través de I²C, SPI, bus paralelo u otros medios. Este restablecimiento de un indicador de interrupción es casi siempre la forma en que el microcontrolador reconoce una interrupción generada por un periférico ubicado dentro de sí mismo.

El problema con el segundo enfoque, es que realizar una transferencia SPI o I²C lleva tiempo y es posible que no desee pasar mucho tiempo en su ISR. Por lo tanto, puede deshabilitar la interrupción que se activó y establecer un indicador. Tan pronto como salga del ISR, e ingrese algún tipo de condición de inactividad, luego, según el indicador que se está configurando, puede realizar la transferencia I²C o SPI para restablecer el indicador de interrupción en el periférico y luego volver a habilitar la interrupción. Si está utilizando un sistema operativo multitarea de algún tipo, puede generar un evento desde el ISR o lo que sea necesario en su sistema operativo para activar una tarea para realizar esta operación.

Si no puede deshabilitar solo la interrupción que se activó, y debe deshabilitar todas las interrupciones, este obviouls tendrá un efecto mucho más drástico en su sistema, y podría ser preferible solo hacer la comunicación I²C o SPI dentro de el ISR y se hará con él.

Entonces, si es tanto problema manejar las interrupciones activadas por nivel, ¿por qué tenerlas en primer lugar? Porque permite tener varios periféricos diferentes atados al mismo pin de interrupción y poder identificar de dónde proviene la interrupción.

Digamos que solo tiene una interrupción externa (llamada Not_Interrupt_In (ya que no puedo usar \ $ \ mathsf {\ small \ overline {\ text {Interrupt In}}} \ $ en CircuitLab) y dos periféricos que pueden generar cada uno interrupciones activadas por nivel (Not_Interrupt_0 y Not_Interrupt_1). Atas las salidas de interrupción de cada una de ellas al mismo pin externo de interrupción a través de un diodo. Se supone que todas están configuradas como de drenaje abierto, es decir, la condición normal de una lógica. 1, y cuando se produce una interrupción, la salida pasa a la lógica 0. (Si uno o ambos pf de las perillas de interrupción de un periférico no están abiertos, simplemente omita la resistencia correspondiente).

Los diodos crean una puerta OR; Puede parecer que están al revés, pero recuerde que estamos tratando con señales negativas (0 = afirmado). He verificado la operación del circuito en CircuitLab.

Entonces, cualquiera de las fuentes de interrupción causará que la línea de interrupción externa en el microcontrolador pase a 0, generando una interrupción. Mientras tanto, cada línea de interrupción tiene su propia entrada a uno de los puertos del microcontrolador, en este caso, los puertos 0 y 1 del puerto. Por lo tanto, cuando se produce la interrupción, el ISR puede mirar al puerto A y determinar qué periférico generó la interrupción.

Tenga en cuenta que esto no se puede hacer con interrupciones activadas desde el borde, ya que no se puede suponer que la línea de interrupción aún se afirma en el momento en que el ISR obtiene el control, por lo que una encuesta no funcionará. Uno podría alimentar externamente las interrupciones de borde en pestillos, que podrían ser encuestados, pero tendrían que ser restablecidos por el ISR, y hay algunas condiciones de carrera desagradables que deben evitarse.

    
respondido por el tcrosley

Lea otras preguntas en las etiquetas