AVR: por qué cada vector de interrupción ocupa dos palabras de instrucción

Durante mi estudio de la hoja de datos Atmega328 encontré que cada vector de interrupción ocupa dos direcciones y después de buscar no puedo encontrar por qué.

Esa es una captura de pantalla de la página 82 de la hoja de datos de atmega328p

ingrese la descripción de la imagen aquí

No tengo la especificación frente a mí, pero es bastante común que las direcciones sean más grandes que una sola palabra de memoria. Cada vector de interrupción almacena una dirección, por lo que es probable que una dirección ocupe dos palabras de memoria.

Respuestas (1)

El tamaño de la unidad de la tabla de vectores depende del chip que utilice. Por ejemplo, los chips ATTiny usan 2 bytes (1 instrucción) para cada vector en la tabla.

La razón para permitir el valor de múltiples instrucciones en los procesadores más grandes es permitir el uso de instrucciones más grandes.

Para un AVR, la RJMPinstrucción es una instrucción de 2 bytes para salto relativo; sin embargo, solo puede acceder a un desplazamiento de +/- 4kB desde la tabla de vectores. Esto está bien en los procesadores más pequeños con <8kB de Flash, ya que permite que las ISR (rutinas de servicio de interrupción) se coloquen en cualquier lugar dentro de la memoria flash. Sin embargo, para AVR más grandes, como el flash ATMega328 de 32kB, esto no es suficiente (*).

Para acceder al espacio flash completo, debe usar las JMPinstrucciones. Este es un salto directo que le permite acceder a hasta 4 MB de flash. Sin embargo, la JMPinstrucción es en realidad una instrucción de 4 bytes. Para usarlos en la tabla de vectores, debe permitir 2 palabras de instrucción para cada vector. Y esto es justo lo que hacen.

Todavía es perfectamente posible usar RJMPo cualquier otra instrucción de una sola palabra dentro de una tabla de vectores de dos palabras. Todo lo que tiene que hacer es agregar un adicional NOPdespués para completar la instrucción en dos palabras.

Además, no necesariamente tienes que saltar a ningún lado. Imagine que su ISR no tuviera que hacer nada más que configurar un bit en un registro IO. En un AVR, si el registro está dentro del rango, puede usar la instrucción SBIo CBIpara hacer esto. Debido a que eso no tiene ningún efecto secundario en las banderas de ALU, puede dentro de una tabla de dos vectores de instrucciones construir su ISR completo ( SBIinstrucción seguida de RETIinstrucción) y ahorrar toda la sobrecarga de saltar a un ISR.


(*) En realidad es posible, aunque más lento, utilizar los llamados "trampolines". Este es básicamente un caso de colocar una sola JMPinstrucción en el flash dentro de un desplazamiento de +/- 4k de la tabla de vectores. La tabla de vectores contiene una RJMPinstrucción que salta a la JMPinstrucción cercana que, a su vez, salta a cualquier parte del flash.

De acuerdo con su nota (*), es posible que en nuestro caso la primera dirección se use para almacenar el vector de interrupción y la segunda dirección se use para almacenar la dirección real de la rutina de servicio de interrupción.
@mostafayasin No, si JMPse usa una instrucción, la dirección del ISR está incrustada dentro de la instrucción, es solo que la instrucción ocupa 4 bytes. Si se usa un trampolín en dispositivos con 2 bytes/vector en la tabla, entonces la RJMPinstrucción está en la tabla de vectores que almacena la dirección relativa de la JMPinstrucción que se coloca en otro lugar de la memoria. La JMPinstrucción todavía tiene la dirección del ISR incrustada dentro de ella.