Modos de Excepción y Manejo de Interrupciones
Tabla de Contenidos
-
Modos de Excepción y Manejo de Interrupciones
- Introducción
- Excepciones y Modos de Excepción[1][3]
- Entrada a una Excepción[1][2][3]
- Salida de una Excepción[2]
- Fast Interrupt Request (FIQ) [2]
- Interrupt Request (IRQ)[2]
- Abort[1][2]
- Software Interrupt (SWI) [2]
- Undefined Istruction (UND) [1][2]
- Vectores de Excepción [2]
- Prioridades de las Excepciones[2]
- Latencias de las Interrupciones[2]
- Reset[2]
- Referencias
Introducción
Una excepción es cualquier condición que necesita alterar el funcionamiento normal del programa. Los microcontroladores ARM poseen 5 modos de excepción, a los que se puede ingrasar desde 7 tipos de excepciones y cada una tiene algunas particularidades.
En lo microcontroladores ARM las interrupciones son un tipo especial de excepción, por lo tanto, para procesarlas hay que entender como funcionan las excepciones en general.
Excepciones y Modos de Excepción[1][3]
Cada excepción hace que el procesador entre en un modo específico. También se puede cambiar entre los distintos modos manualmente, modificando el CPSR y de hecho, esta es la única forma de cambiar a los modos 'Usuario' y 'Sistema'.
Excepciones y sus Modos Asociados
Entrada a una Excepción[1][2][3]
Cuando una excepción causa un cambio de modo, el procesador !ARM7TDMI toma las siguientes acciones:
- Preserva la dirección de la siguiente instrucción en el LR (R14) apropiado.
- Copia el CPSR en el SPSR apropiado.
- Impone en los bits de Modo del CPSR un valor que depende de la excepción.
- Pone en el PC el valor de la instrucción del vector de excepciones relevante.
En pseudocódigo:[1]
R14_<exception_mode> = return link SPSR_<exception_mode> = CPSR CPSR[4:0] = número de modo de excepción CPSR[5] = 0 /* Ejecuta en Estado ARM */ if <exception_mode> == Reset or FIQ then CPSR[6] = 1 /* Desactiva FIQs */ else CPSR[6] sin cambios CPSR[7] = 1 /* Desactiva IRQ */ CPSR[9] = CP15_reg1_EEbit /* Endianness on entry */ PC = dirección del vector de excepción
Nota: A los modos de excepción siempre se entra en estado ARM, automáticamente. También se debe salir en modo ARM, pero esto es responsabilidad del programa.
Salida de una Excepción[2]
Cuando la excepción ha concluido, el manejador de la misma debe:
- Mover el LR, menos un desplazamiento (offset) al PC.
- Restaurar el valor del SPSR al CPSR.
- Limpiar las banderas de deshabilitación de interrupción que fueron establecidas a la entrada.
Esto se puede hacer de 2 maneras:
- Utilizando una instrucción de procesamiento de datos con el bit S establecido y el PC como destino.
- Utilizando la instrucción Load Multiple with Restore CPSR instruction, LDM, como se mostrará más adelante.
Fast Interrupt Request (FIQ) [2]
En estado ARM, tiene un banco de 8 registros para eliminar la necesidad de salvar registros y así minimizar la sobrecarga del cambio de contexto. Se genera externamente llevando la señal nFIQ a BAJO, y la entrada pasa al núcleo a través de un sincronizador. El manejador de la FIQ retorna de una interrupción ejecutando: SUBS PC,R14_fiq,#4 Las excepciones FIQ pueden deshabilitarse dentro de un modo privilegiado estableciendo la bandera F en el CPSR. Cuando esta bandera está en 0, el procesador chequea el estado del sincornizador de la FIQ al finalizar cada instrucción.
Interrupt Request (IRQ)[2]
Se genera externamente llevando la señal nIRQ a BAJO, y la entrada pasa al núcleo a través de un sincronizador. El manejador de la FIQ retorna de una interrupción ejecutando: SUBS PC,R14_irq,#4 Puede deshabilitarse estableciendo en bit I del CPSR en un modo privilegiado.
Abort[1][2]
Indica que no se pudo completar un acceso a memoria. Se indica a través de la señal externa ABORT. El procesador !ARM7TDMI chequea esta señal al final de cada ciclo de acceso a memoria. Hay 2 tipos: Aborto de Lectura de Instrucción y Aborto de Lectura de Datos.
Texto
Para volver del manejador SUBS, R14_abt, #4 → Recupera el PC y el CPSR y vuelve a ejecutar la instrucción abortada. SUBS PC,R14_abt, #8 → Idem para datos.
Software Interrupt (SWI) [2]
Se utiliza para entrar en Modo Supervisor, generalmente requiriendo algún servicio (cuando hay un sistema operativo más que nada).
R14_svc = dirección de la instrucción posterior a la que causó la SWI SPSR_svc = CPSR CPSR[4:0] = 0b10011 /* Entrar al Modo Supervisor */ CPSR[5] = 0 /* Execute in ARM state */ /* CPSR[6] sin cambios */ CPSR[7] = 1 /* Deshabilita IRQ */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if (vectores altos configurados) then PC = 0xFFFF0008 else PC = 0x00000008
- Recupera el PC y el CPSR y va hacia la instrucción posterior a la que causó la SWI.
Undefined Istruction (UND) [1][2]
Se utiliza para procesar instrucciones que no son entendidas ni por el núcleo, ni por algún coprocesador. De esta forma se puede expandir el set de instrucciones o emular por software funciones de un coprocesador.
R14_und = dirección de la instrucción posterior a la indefinida SPSR_und = CPSR CPSR[4:0] = 0b11011 /* Entrar al Modo Undefined Instruction*/ CPSR[5] = 0 /* Ejecutar en Estado ARM */ /* CPSR[6] din cambios */ CPSR[7] = 1 /* Deshabilita IRQ */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if (vectores altos configurados) then PC = 0xFFFF0004 else PC = 0x00000004
Se regresa con: MOVS PC, R14_und
Esta instrucción restaura el PC desde R14_und y el CPSR desde SPSR_und y retorna a la instrucción posterior a la que generó la interrupción.
Vectores de Excepción [2]
Dirección </td> <td width="24%">
Excepción </td> <td width="20%">
Modo en Entrada </td> <td width="20%">
I en Ent </td> <td width="20%">
F en Ent </td> </tr> <tr valign="top"> <td width="16%">
0x00000000 </td> <td width="24%">
Reset </td> <td width="20%">
Supervisor </td> <td width="20%">
1 </td> <td width="20%">
1 </td> </tr> <tr valign="top"> <td width="16%">
0x00000004 </td> <td width="24%">
Undefined Instruction </td> <td width="20%">
Undefined </td> <td width="20%">
1 </td> <td width="20%">
Sin cambio </td> </tr> <tr valign="top"> <td width="16%">
0x00000008 </td> <td width="24%">
Software Interrupt </td> <td width="20%">
Supervisor </td> <td width="20%">
1 </td> <td width="20%">
Sin cambio </td> </tr> <tr valign="top"> <td width="16%">
0x0000000C </td> <td width="24%">
Prefetch Abort </td> <td width="20%">
Abort </td> <td width="20%">
1 </td> <td width="20%">
Sin cambio </td> </tr> <tr valign="top"> <td width="16%">
0x00000010 </td> <td width="24%">
Data Abort </td> <td width="20%">
Abort </td> <td width="20%">
1 </td> <td width="20%">
Sin cambio </td> </tr> <tr valign="top"> <td width="16%">
0x00000014 </td> <td width="24%">
Reserved </td> <td width="20%">
Reserved </td> <td width="20%">
- </td> <td width="20%">
- </td> </tr> <tr valign="top"> <td width="16%">
0x00000018 </td> <td width="24%">
IRQ </td> <td width="20%">
IRQ </td> <td width="20%">
1 </td> <td width="20%">
Sin cambio </td> </tr> <tr valign="top"> <td width="16%">
0x0000001C </td> <td width="24%">
FIQ </td> <td width="20%">
FIQ </td> <td width="20%">
1 </td> <td width="20%">
1 </td> </tr> </tbody></table>
Prioridades de las Excepciones[2]
Se aplica cuando varias excepciones se producen al mismo tiempo
Prioridad </td> <td width="73%">
Excepción </td> </tr> <tr valign="top"> <td width="27%">
1 </td> <td width="73%">
Reset </td> </tr> <tr valign="top"> <td width="27%">
2 </td> <td width="73%">
Data Abort </td> </tr> <tr valign="top"> <td width="27%">
3 </td> <td width="73%">
FIQ </td> </tr> <tr valign="top"> <td width="27%">
4 </td> <td width="73%">
IRQ </td> </tr> <tr valign="top"> <td width="27%">
5 </td> <td width="73%">
Prefetch Abort </td> </tr> <tr valign="top"> <td width="27%">
6 </td> <td width="73%">
Undefined Instruction y SWI </td> </tr> </tbody></table>
Latencias de las Interrupciones[2]
Cuando las FIQs están habilitadas, el peor caso se produce por una combinación de causas:
Tsyncmax </td> <td width="87%">
Tiempo más largo que puede tomarle al pedido atravesar el sincronizador es de 4 ciclos </td> </tr> <tr valign="top"> <td width="13%">
Tldm </td> <td width="87%">
Tiempo que tarda en completarse la instrucción más larga. Ésta es LDM cuando carga todos los registros, incluido el PC. El tiempo es 20 ciclos cuando no hay configurados tiempos de espera en el acceso a memoria. </td> </tr> <tr valign="top"> <td width="13%">
Texc </td> <td width="87%">
El tiempo de entrada a Data Abort (que tiene mayor prioridad que FIQ) es de 3 ciclos. </td> </tr> <tr valign="top"> <td width="13%">
Tfiq </td> <td width="87%">
El tiempo de entrada a la FIQ es de 2 ciclos. </td> </tr> </tbody></table>
La latencia mínima para la FIQ o una IRQ es el mínimo que puede tomarle pasar por el sincronizador, Tsyncmin más Tfiq. En total son 5 ciclos de procesador.
Reset[2]
Cuando la señal nRESET se pone en BAJO el procesador para la ejecución de la instrucción actual. Caundo vuelve a ALTO el núcleo !ARM7TDMI:
- Sobrescribe R14_svc y SPSR_svc copiando los valores que en ese momento tuvieran el PC y el CPSR. Dichos valores son indeterminados.
- Impone M[4:0] a b10011 (Modo Supervisor). Establece los Bits I y F y borra el bit T del CPSR.
- Impone al PC para leer la próxima instrucción en la dirección 0x00.
- Vuelve al Estado ARM si es necesario y restablece la ejecución.
Los valores de todos los demás registros quedan indeterminados.
En pseudocódigo:
R14_svc = valor IMPREDECIBLE SPSR_svc = valor IMPREDECIBLE CPSR[4:0] = 0b10011 /* Entra a Modo Supervisor */ CPSR[5] = 0 /* Cambia a Estado ARM */ CPSR[6] = 1 /* Deshabilita FIQ */ CPSR[7] = 1 /* Deshabilita IRQ */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if (vectores altos configurados) then PC = 0xFFFF0000 else PC = 0x00000000
Referencias
- DDI 0100I - ARM Architecture Reference Manual - 2005
- DDI 0210C - !ARM7TDMI Technical Reference Manual - 2004
- ARM System Developer's Guide, Designing and Optimizing System Software - 2004 - Elsevier.