Subido por aleluis.fiee

El gestor de interrupciones stm32 braindtic

Anuncio
Gestor de interrupciones
El gestor de interrupciones es quien se encarga de lidiar con eventos
asincrónicos. La mayoría de estos eventos vienen de periféricos de hardware.
Por ejemplo, un temporizador que alcanza un valor de período configurado, o un
puerto UART que advierte sobre la llegada de datos. Otros son originados por el
“mundo exterior”, por ejemplo, el usuario presiona un interruptor que hace que
se genere una interrupción.
Imagen 1. Diagrama de bloques de un núcleo Cortex-M.
Una interrupción es un evento asíncrono que provoca detener la ejecución del
código actual en base a una prioridad (cuanto más importante es la interrupción,
mayor será su prioridad, lo que hará que una interrupción de menor prioridad se
suspenda). La rutina que se ejecuta durante una interrupción se denomina
“Rutina de servicio de interrupción” o “Interrupt Service Routine” por sus siglas
en ingles ISR.
Las interrupciones son una fuente de multiprogramación: el hardware es
responsable de guardar el contexto de ejecución actual (es decir, los datos de
la pila, el actual Contador de Programa y entre otras cosas) antes de cambiar al
ISR. Esta funcionalidad es explotada por los sistemas operativos en tiempo real
para introducir la noción de tareas. Sin ayuda del hardware es imposible contar
con un verdadero sistema preventivo, que permita conmutar varios contextos de
ejecución sin perder irreparablemente el flujo de ejecución actual.
Las interrupciones pueden originarse tanto por el hardware como por el propio
software. La arquitectura ARM distingue entre los dos tipos: interrupciones
originadas por el hardware, interrupciones por el software (por ejemplo, un
acceso a una ubicación de memoria no válida). En la terminología ARM, una
interrupción es un tipo de excepción.
Los procesadores Cortex-M proporcionan una unidad dedicada a la
administración de interrupciones el cual se llama “Nested Vectored Interrupt
Controller” (NVIC).
NVIC (Administrador de vector de interrupciones anidadas).
Es una unidad de hardware dentro de los microcontroladores basados en CortexM que es responsable de la administración de interrupciones. La imagen 2
muestra la relación entre la unidad NVIC, el núcleo del procesador y los
periféricos. Aquí tenemos que distinguir dos tipos de periféricos: los externos al
núcleo Cortex-M, pero internos a la MCU STM32 (por ejemplo, temporizadores,
UARTS, etc.) y los periféricos externos a la MCU. La fuente de las interrupciones
procedentes de la última clase de periféricos son puertos GPIO, que pueden
configurarse como entrada o salida (por ejemplo, un botón conectado a un pin
configurado como entrada) o para excitar un periférico externo avanzado (por
ejemplo, un módulo USB). Un controlador programable dedicado, llamado
“External Interrupt/Event Controller” (EXTI), es responsable de la interconexión
entre las señales de E/S externas y el controlador NVIC, como veremos a
continuación.
Imagen 2. Relación entre NVIC, el núcleo Cortex-M y los perifericos del
STM32.
Como se indicó anteriormente, ARM distingue entre las excepciones del sistema,
que se originan dentro del núcleo de la CPU, y las excepciones de hardware
procedentes de periféricos externos, también llamadas “Solicitudes de
Interrupción” (IRQ). Los programadores manejan las interrupciones mediante el
uso de ISRs específicos, que están codificados en un nivel superior (a menudo
usando el lenguaje C). El procesador sabe dónde ubicar estas rutinas gracias a
una tabla indirecta que contiene las direcciones en memoria de las Rutinas de
Servicio de Interrupción. Esta tabla se denomina comúnmente tabla del vector
de interrupciones, y cada microcontrolador STM32 define su propia.
Características principales.




82 canales de interrupciones.
16 niveles de prioridades programables.
Re-priorización dinámica de las interrupciones.
Agrupación de valores de prioridad y subprioridades.
El NVIC y la interfaz del núcleo del procesador están estrechamente acoplados,
lo que permite una baja latencia procesamiento de interrupciones y
procesamiento eficiente. Todas las interrupciones, incluidas las excepciones
básicas, son gestionadas por NVIC.
El procesador guarda automáticamente el contexto durante la incidencia de una
interrupción y retorna a ese estado al atender dicha interrupción.
Tabla del Vector de interrupciones en un STM32.
Esta tabla puede ser encontrada en el manual de referencia RM0090 en la
Tabla número 61.
En la imagen número 3 se muestra una parte de dicha tabla, la cual nos ofrece
información de la interrupción como:






Posición en el vector de interrupción
Prioridad de la interrupción.
El tipo de prioridad (Si es configurable o no).
Nombre de la interrupción.
Una pequeña descripción de la interrupción.
Dirección en memoria del microcontrolador.
Imagen 3. Tabla del vector de interrupciones para STM32F405xx/07xx.
Incluso si la tabla vectorial contiene las direcciones de las rutinas del controlador,
el núcleo de Cortex-M necesita una forma de encontrar la tabla vectorial dentro
de la memoria. Por convención, la tabla vectorial comienza en la dirección de
hardware 0x00000000 en todos los procesadores basados en Cortex-M. Si la
tabla vectorial reside en la memoria no volátil interna, y dado que dicha memoria
en todas los MCUs STM32 está asignado desde la dirección 0x08000000, como
se muestra en la imagen 4, pero en cuanto el microcontrolador enciende,
enmascara esta dirección y la ve como 0x00000000.
Imagen 4. Fragmento del mapa de memoria de un STM32.
La imagen 5 muestra cómo se organiza la tabla de vectores en la memoria. El
cero de entrada de esta matriz es la dirección del puntero de la pila principal
(MSP) dentro de la SRAM. Normalmente, esta dirección corresponde al final de
la SRAM, es decir, su dirección base más su tamaño. A partir de la segunda
entrada de esta tabla, podemos encontrar todas las excepciones y el manejador
de interrupciones.
Imagen 5. Vector de interrupciones de un microcontrolador STM32.
Interrupciones externas.
Como hemos visto en la imagen 2, los microcontroladores STM32 proporcionan
un número variable de fuentes de interrupción externas conectadas al NVIC a
través del controlador EXTI, que a su vez es capaz de gestionar varias líneas
EXTI. El número de fuentes y líneas de interrupción depende de la familia STM32
específica.
Los GPIO están conectados a las líneas EXTI, y es posible habilitar
interrupciones para cada GPIO de MCU, incluso si la mayoría de ellos comparten
la misma línea de interrupción. Por ejemplo, para una MCU STM32F4, hasta 114
GPIOs están conectados a 16 líneas EXTI. Sin embargo, sólo 7 de estas líneas
tienen una interrupción independiente asociada con ellas.
En la imagen 6 podemos ver que todos los pines Px0 están conectados a EXTI0,
todos los pines Px10 están conectados a EXTI10 y todos los pines Px15 están
conectados a EXTI15. Sin embargo, las líneas EXTI 10 y 15 comparten el mismo
IRQ dentro del NVIC (y por lo tanto son atendidas por el mismo ISR).
Esto significa que:

Sólo un pin PxY puede ser una fuente de interrupción. Por ejemplo, no
podemos definir PA0 y PB0 como pines de interrupción de entrada.

Para las líneas EXTI que comparten el mismo IRQ dentro del controlador
NVIC, tenemos que codificar el ISR correspondiente para que debamos
ser capaces de discriminar qué líneas generaron la interrupción. Por
ejemplo, si definimos PA10 y PA15, nesecitamos leer los dos pines para
identificar cual genero el evento de interrupción.
Imagen 6. Líneas EXTI 0, 10 y 15 en un MCU STM32F4.
Para futuras referencias, puede consultar el manual de referencia RM0090 en la
sección 12.2.5 “External interrupt/event line mapping”.
Niveles de prioridad para las interrupciones.
Un rasgo distintivo de la arquitectura ARM Cortex-M es la capacidad de priorizar
interrupciones (excepto las tres primeras excepciones de software que tienen
una prioridad fija, como se muestra en la imagen 7). La prioridad de interrupción
permite definir dos cosas:


Los ISR que se ejecutarán primero en caso de interrupciones
simultáneas;
Aquellas rutinas que se pueden optar opcionalmente para iniciar la
ejecución de un ISR con una prioridad más alta.
El mecanismo de prioridad de interrupción en Cortex-M4 es más avanzado que
el disponible en los microcontroladores basados en Cortex-M0/0+. Los
desarrolladores tienen un mayor grado de flexibilidad. En los núcleos CortexM3/4/7, la prioridad de cada interrupción se define a través del registro IPR. Se
trata de un registro de 8 bits en la arquitectura de núcleo ARMv7-M que permite
hasta 255 niveles de prioridad diferentes. Sin embargo, en la práctica, los MCUs
STM32 que implementan estos núcleos utilizan solamente los cuatro bits
superiores de este registro, viendo todos los otros bits igual a cero.
Imagen 7. Registro IPR implementado en un STM32.
La imagen 8 muestra claramente cómo se interpreta el contenido de los DPI.
Esto significa que tenemos los únicos dieciséis niveles de prioridad máxima:
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0,
0xD0, 0xE0, 0xF0. Cuanto menor sea este número, mayor será la prioridad. Es
decir, un IRQ que tiene una prioridad igual a 0x10 tiene una prioridad más alta
que un IRQ con un nivel de prioridad igual a 0xA0. Si dos interrupciones disparan
al mismo tiempo, el que tenga la mayor prioridad será atendido primero. Si el
procesador ya está atendiendo una interrupción y una prioridad más alta
interrumpe, entonces la ejecución de la actual interrupción se suspende y el
control pasa a la interrupción de prioridad más alta. Cuando la ejecución de la
interrupción de alta prioridad se completa, la ejecución vuelve a la interrupción
anterior, mientras no se produzca otra interrupción con mayor prioridad.
Hasta ahora, el mecanismo es sustancialmente el mismo de Cortex-M0/0+. La
complicación surge del hecho de que el registro IPR puede subdividirse
lógicamente en dos partes: una serie de bits que definen la prioridad de prioridad
y una serie de bits que definen la sub-prioridad. El primer nivel de prioridad rige
las prioridades de prioridad entre ISRs. Si un ISR tiene una prioridad más alta
que otra, prevendrá la ejecución del ISR de menor prioridad en caso de que se
active. La sub-prioridad determina qué ISR se ejecutará primero, en caso de un
ISR múltiple pendiente.
Imagen 8. Subdivisión del registro IPR entre prioridad y sub-prioridad.
La imagen 9 muestra un ejemplo de interrupciones de diferentes prioridades. La
letra A representa un IRQ con una prioridad baja (0x20) que se dispara en el
tiempo t0. El ISR inicia la ejecución de A-ISR, pero el B-IRQ que tiene una
prioridad más alta (0x10), se dispara en el instante t1. Entonces la ejecución de
A-ISR se detiene y comienza la ejecución de B-ISR. Después en un tiempo t3 se
dispara C-IRQ (prioridad 0x00), la ejecución de B-ISR se detiene y se inicia la
ejecución de C-ISR. Cuando la ejecución de C-ISR termina, se reanuda la
ejecución de B-ISR hasta que termina. Finalmente se reanuda la ejecución de AISR hasta el final. A este proceso de control de interrupciones se le llama:
“anidado”. El mecanismo inducido por prioridades de interrupción conduce al
nombre del controlador NVIC o Controlador de Interrupción Vectorial
Anidado.
Imagen 9. Interrupciones anidadas.
Descargar