Modificar tabla de vector de interrupción de Atmega32

4

Un proyecto en el que estoy trabajando implica una rutina de servicio de interrupción de ciclo preciso. Esta rutina está escrita en el ensamblaje de AVR donde acabo de escribir:

.org oc1aadr
rjmp INTRP

(para configurar el IVT) Y funcionó perfectamente bien. Sin embargo, tuve que usar tanto C como ensamblaje para este proyecto, así que cambié a GCC y, después de buscar algo de documentación, encontré que solo tenía que escribir la rutina con una etiqueta:

TIMER1_COMPA_vect:

Ahora la interrupción está funcionando bien también, pero la cosa es que ahora toma 3 ciclos ingresar al ISR. Al buscar el código del desensamblador, vi que el IVT es así:

+00000000:   940C002A    JMP     0x0000002A       Jump
+00000002:   940C0047    JMP     0x00000047       Jump
+00000004:   940C0047    JMP     0x00000047       Jump
+00000006:   940C0047    JMP     0x00000047       Jump
+00000008:   940C0047    JMP     0x00000047       Jump
+0000000A:   940C0047    JMP     0x00000047       Jump
+0000000C:   940C0047    JMP     0x00000047       Jump
+0000000E:   940C0049    JMP     0x00000049       Jump
+00000010:   940C0047    JMP     0x00000047       Jump

La instrucción JMP toma 3 ciclos a diferencia de RJMP, que solo toma 2. He intentado escribir:

.org 0x0E
rjmp INTRP

Pero aún así no funcionará, también he intentado escribir (.section .init0) antes de .org, pero aún no tengo efecto. Entonces, ¿hay alguna manera en que pueda cambiar la instrucción a RJMP? Nota: solo la rutina de interrupción se escribe en el ensamblaje.

Para mi segunda pregunta: ¿Hay alguna diferencia en los ciclos de reloj requeridos por una instrucción cuando se usan compiladores / ensambladores diferentes? MI rutina completa toma 3 ciclos menos usando GCC en comparación con el ensamblador AVR. No sé si GCC depende del ensamblador AVR o no, pero ¿existe la posibilidad de que esto suceda? (Lo pregunto en base a la salida del simulador AVR).

    
pregunta tecfreak

1 respuesta

1

La respuesta está en avr / interrupt.h línea 228 que decide para utilizar jmp en ATMEGA y rjmp en otros micros. Es de suponer que podría anularlo de nuevo a rjmp siempre que se asegure de que la dirección de su ISR esté dentro del rango permitido para rjmp .

La documentación para avr / interrupt.h como se menciona en otra respuesta explica cómo para marcar el ISR como desnudo para evitar cualquier sobrecarga de configuración / eliminación de funciones. Incluso podría escribir la función utilizando el ensamblaje en línea, pero probablemente también pueda obtener exactamente las instrucciones que desee de C.

    
respondido por el joeforker

Lea otras preguntas en las etiquetas