Diferencia entre revisiones de «C12 - Interrupts»
| (No se muestran 5 ediciones intermedias del mismo usuario) | |||
| Línea 29: | Línea 29: | ||
<b>Context Switch</b><br> | <b>Context Switch</b><br> | ||
*Es el proceso de cambiar del main program a la rutina de la interrupción | *Es el proceso de cambiar del main program a la rutina de la interrupción | ||
* | *Pasos que ocurren cuando se pasa del main program a la interrupción | ||
**1.- Acaba la instrucción que está procesando | **1.- Acaba la instrucción que está procesando | ||
**2.- Se suspende la ejecución del programa main | **2.- Se suspende la ejecución del programa main | ||
| Línea 86: | Línea 86: | ||
Producer se refiere al thread que "produce" el dato y Consumer se refiere al thread que utiliza ese dato.<br> | Producer se refiere al thread que "produce" el dato y Consumer se refiere al thread que utiliza ese dato.<br> | ||
COMPLETAR<br> | COMPLETAR<br> | ||
<br> | |||
= NVIC on the ARM Cortex-M Processor = | |||
<br> | |||
<br> | |||
= Edge-triggered Interrupt = | |||
<br> | |||
*Esto es un tipo de interrupción que usa un cambio en la señal (flanco) para disparar la interrupción. Es útil cuando tenemos un evento físico que debemos "capturar" en el momento exacto cuando sucede. | |||
*Para leer la señal se usa un puerto del µC configurado como GPIO de entrada | |||
*Se usa los flancos (subida o bajada) que generan los devices (sensor temperatura, presión, humo, switch ...) en su señal para detectar los cambios en su estado | |||
*Si manejamos estas señales con interrupciones tenemos que el software responde inmediatamente a eventos físicos. Tenemos un sistema real-time | |||
<br> | |||
Imagen<br> | |||
<br> | |||
*Para usar un pin como edge-trigger interrupt | |||
**Cualquier pin digital I/O puede configurarse como edge-triggering input | |||
**Se sigue la inicialización habitual como puerto GPIO input | |||
***Enable clock RCGC2 | |||
***Enable bit DEN | |||
***Clear PCTL | |||
***Clear AFSEL (alternative function) | |||
***Clear DIR (input) | |||
***Clear AMSEL (digital pin) | |||
**A parte se configurar otros bits para poder tener el modo edge-trigger | |||
***IS - Si es 0 significa que detecta los flancos | |||
***IEV - Si es 0 significa falling edge, si es 1 significa rising edge | |||
***IBE - Si es 1 significa que tiene en cuenta los dos flancos | |||
***IME - Si es 1 significa que cuando detecte un flanco activa la interrupción | |||
<br> | |||
{|cellpadding="5" border="1" cellspacing="0" | |||
! style="text-align: center; font-weight: bold;" | DIR | |||
! style="text-align: center; font-weight: bold;" | IS | |||
! style="text-align: center; font-weight: bold;" | IBE | |||
! style="text-align: center; font-weight: bold;" | IEV | |||
! style="text-align: center; font-weight: bold;" | IME | |||
! style="text-align: center; font-weight: bold;" | Port mode | |||
|- | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 1 | |||
| style="text-align: center;" | falling | |||
|- | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 1 | |||
| style="text-align: center;" | 1 | |||
| style="text-align: center;" | rising | |||
|- | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 0 | |||
| style="text-align: center;" | 1 | |||
| style="text-align: center;" | - | |||
| style="text-align: center;" | 1 | |||
| style="text-align: center;" | both edges | |||
|} | |||
<br> | |||
<b>Ejemplo</b><br> | |||
Tenemos un switch (lógica positiva) que conectamos a un puerto digital del µC. Queremos "capturar" la pulsación cuando se produzca (flanco de subida) y guardar el número de pulsaciones. El evento (la pulsación) es crítica y necesitamos que se "capture" en el momento exacto en que se produce. Para ello utilizaremos una interrupción de tipo edge-triggering.<br> | |||
<br> | |||
= Systick Periodic Interrupt = | |||
<br> | |||
<br> | |||
= DC Motor Interface with PWM = | |||
<br> | |||
<br> | |||
= Robot Car construction = | |||
<br> | |||
<br> | <br> | ||
Revisión actual - 14:24 8 abr 2015
Interrupt Concepts
[editar]
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
- Pasos que ocurren cuando se pasa del main program a la 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 Este patrón 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 Interrupt Service Routine hay la instrucción BXLR
- Ésta 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 cuanto 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
Las interrupciones son mas apropiadas que otros sistemas de sincronización
- Cuando el tiempo en que ocurre el evento es variable y la estructura I/O es compleja
- Cuando los diferentes devices tienen diferentes velocidades de sincronización
- Cuando es necesario desarrollar un sistema de real-time
- Cuando tiene que ver con eventos importantes del sistema
Aspectos esenciales que debe tener el µC para usar interrupciones
- La interrupción debe tener una conexión separada al procesador para cada device
- El µC debe poder determinar de que device vino la interrupción
- El µC tiene que poder hacer acknowledge (poder hacer clear al flag de trigger)
- Cuando se diseña una interrupción es importante saber que device activó el flag de trigger y hacer clear de ese flag
Inter-thread Communication and Synchronization
[editar]
Multi-threading
- Un main program y multiples ISRs
- Sincronizar varios threads es crítico y tiene que ser eficiente
- Hay 3 métodos para sincronizar los threads (pasar info del main thread al background thread) - Se utilizan variables globales porque son accesibles por los dos threads
- Binary semaphore (flag)
- Mailbox
- Fifo buffer
Binary semaphore (flag)
- El flag se usa para indicar un cambio de estado en el device
- Es una variable global
- El main quiere saber si ha ocurrido un evento para ello comprueba el flag El flag lo activa el ISR cuando ocurre el evento
- Tiene dos componentes: el flag y el data
- El flag tiene la misma función que con Binary semaphore
- En el data se pasa cualquier valor entre el ISR y el main program (ej. los datos del registro UART_DR_R)
Fifo Buffer
- Ponemos el data que recoge la ISR en el fifo buffer - Hacemos un PUT
- Desde el main recogemos los datos del fifo buffer con un GET
Explicar a parte de que el método mailbox y fifo son unos paradigmas llamados producer consumer.
Producer se refiere al thread que "produce" el dato y Consumer se refiere al thread que utiliza ese dato.
COMPLETAR
NVIC on the ARM Cortex-M Processor
[editar]
Edge-triggered Interrupt
[editar]
- Esto es un tipo de interrupción que usa un cambio en la señal (flanco) para disparar la interrupción. Es útil cuando tenemos un evento físico que debemos "capturar" en el momento exacto cuando sucede.
- Para leer la señal se usa un puerto del µC configurado como GPIO de entrada
- Se usa los flancos (subida o bajada) que generan los devices (sensor temperatura, presión, humo, switch ...) en su señal para detectar los cambios en su estado
- Si manejamos estas señales con interrupciones tenemos que el software responde inmediatamente a eventos físicos. Tenemos un sistema real-time
Imagen
- Para usar un pin como edge-trigger interrupt
- Cualquier pin digital I/O puede configurarse como edge-triggering input
- Se sigue la inicialización habitual como puerto GPIO input
- Enable clock RCGC2
- Enable bit DEN
- Clear PCTL
- Clear AFSEL (alternative function)
- Clear DIR (input)
- Clear AMSEL (digital pin)
- A parte se configurar otros bits para poder tener el modo edge-trigger
- IS - Si es 0 significa que detecta los flancos
- IEV - Si es 0 significa falling edge, si es 1 significa rising edge
- IBE - Si es 1 significa que tiene en cuenta los dos flancos
- IME - Si es 1 significa que cuando detecte un flanco activa la interrupción
| DIR | IS | IBE | IEV | IME | Port mode |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 | falling |
| 0 | 0 | 0 | 1 | 1 | rising |
| 0 | 0 | 1 | - | 1 | both edges |
Ejemplo
Tenemos un switch (lógica positiva) que conectamos a un puerto digital del µC. Queremos "capturar" la pulsación cuando se produzca (flanco de subida) y guardar el número de pulsaciones. El evento (la pulsación) es crítica y necesitamos que se "capture" en el momento exacto en que se produce. Para ello utilizaremos una interrupción de tipo edge-triggering.
Systick Periodic Interrupt
[editar]
DC Motor Interface with PWM
[editar]
Robot Car construction
[editar]