C12 - Interrupts
Interrupt Concepts
Definición
- Es cuando se suspende temporalmente la ejecución del programa para ejecutar una subrutina
- Cuando acaba la interrupción se vuelve a reanudar la ejecución donde se habia quedado
- La interrupción se "dispara" (trigger) a través de una acción del hardware
Interrupt Setup ritual
- Arm/Disarm
- Arm - Permite al hardware hacer trigger a la interrupción
- Disarm - Deshabilita la función de trigger
- Cada interrupción tiene un bit de arm/disarm
- Enable NVIC (Nested Vectored Interrupt Controller)
- Es un módulo que controla todas las interrupciones. Se activa el NVIC específico para el device que usaremos
- Para deshabilitar hacemos un set al bit PRIMASK
- En C hay las funciones EnableInterrupts() y Disable Interrupts() para activar/desactivar las interrupciones
- Global enable bit I
- Este bit se activa haciendo un clear. Este bit activa y desactiva todas las interrupciones
- Si el bit es 1 muchas de las interrupciones no están permitidas, estan disable
- Priority
- No se si se refiere a la prioridad del device al thread principal o a que puede haber varias devices por interrupción y cada una tiene una prioridad
- El registro BASEPRI controla la prioridad de las interrupciones
- Trigger - Es un evento asincrono. Es el encargado de activar el device que activa la interrupción. En el registro RIS hay un bit que nos indica que ha habido un trigger.
5 condiciones que han de ser true para que una interrupción sea generada
- Device arm
- NVIC enable
- Global enable
- Prioridad de la itnerrupción actual ha de ser superior al nivel actual
- Hardware event trigger
Context Switch
- Es el proceso de cambiar del main program a la rutina de la interrupción
Que pasa cuando ocurre una interrupción?
- 1.- Acaba la instrucción que está procesando
- 2.- Se suspende la ejecución del programa main
- Guarda en la posición en en la que se ha quedado
- Se guarda R0, R1, R2, R3, R12, R14 (LR), R25 (PC) y PSR y se hace un push a la pila
- 3.- Se pone un "special code" en el LR (Link Register) LR = 0xFFFFFFF9 Esto indica que estamos ejecutando una ISR
- 4.- En el registro IPSR se guarda el número de la interrupción
- 5.- En PC se carga la dirección de la ISR. La dirección de la ISR se llama vector
Volver del ISR al main thread
Al final del ISR hay la instrucción BXLR. Esta hace un pop de la pila (donde había guardado el estado de ejecución del main thread)
Good Practices
- Acknowledge - Acordarse de siempre hacer un clear del trigger flag
- Hacer que la interrupción sea lo más corta posible para asegurarnos que se pueda dar servicio a todas las interrupciones
- No deben haber delay loops
- Hay que tener en cuenta cada cuante se ejecuta una interrupción y el tiempo que le lleva. Si el tiempo que le lleva es tiempo cada cuanto se ejecuta es un problema