Bienvenido: Ingresar

Empty target given.

Quitar mensaje
location: LabElectronica / ManejoExcepcionesARM

Modos de Excepción y Manejo de Interrupciones

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

expmod.png

Entrada a una Excepción[1][2][3]

Cuando una excepción causa un cambio de modo, el procesador !ARM7TDMI toma las siguientes acciones:

  1. Preserva la dirección de la siguiente instrucción en el LR (R14) apropiado.
  2. Copia el CPSR en el SPSR apropiado.
  3. Impone en los bits de Modo del CPSR un valor que depende de la excepción.
  4. 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:

  1. Mover el LR, menos un desplazamiento (offset) al PC.
  2. Restaurar el valor del SPSR al CPSR.
  3. Limpiar las banderas de deshabilitación de interrupción que fueron establecidas a la entrada.

Esto se puede hacer de 2 maneras:

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

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:

  1. Sobrescribe R14_svc y SPSR_svc copiando los valores que en ese momento tuvieran el PC y el CPSR. Dichos valores son indeterminados.
  2. Impone M[4:0] a b10011 (Modo Supervisor). Establece los Bits I y F y borra el bit T del CPSR.
  3. Impone al PC para leer la próxima instrucción en la dirección 0x00.
  4. 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

  1. DDI 0100I - ARM Architecture Reference Manual - 2005
  2. DDI 0210C - !ARM7TDMI Technical Reference Manual - 2004
  3. ARM System Developer's Guide, Designing and Optimizing System Software - 2004 - Elsevier.