Así es como funciona una interrupción:
Cuando ocurre un evento determinado (el que dispara la interrupción correspondiente) el procesador detiene lo que está haciendo, guarda el punto de ejecución actual (el contador del programa) y comienza a ejecutar el controlador de interrupción. Por lo general, la última instrucción de un controlador de interrupciones es una instrucción especial que le dice al procesador que continúe la ejecución desde el punto en que se guardó antes de ingresar la interrupción.
Para ejecutar el controlador de interrupciones, el procesador necesita saber dónde está.
A menudo esto se hace así: cada interrupción tiene una dirección correspondiente en la memoria del programa y los procesadores comienzan a ejecutar las instrucciones desde allí, por lo general estas direcciones están al principio de la memoria del programa. Debido a que una instrucción generalmente no es suficiente para un controlador de interrupciones, la instrucción generalmente es un jmp para el controlador real. Esto crea un problema: si al inicio de la memoria del programa tiene un montón de jmp que van a los controladores de interrupción correspondientes, entonces la primera instrucción que ve el procesador después del encendido es un jmp para el primer controlador de interrupción y ejecutará eso En lugar del programa principal. Debido a esto, la primera instrucción en la memoria del programa suele ser un jmp al código del programa principal (puede pensar en un reinicio como un tipo especial de interrupción del que no regresa), y lo sigue el jmp a los manejadores de interrupciones.
Por lo tanto, el programa compilado en la memoria del programa se puede desarmar en algo como esto:
jmp main_program
jmp isr_1
jmp isr_2
...
isr_1:
...
reti
isr_2:
...
reti
main_program:
...
El código del ensamblador
somewhere:
es una etiqueta. No se convierte en código binario, pero el ensamblador recuerda la dirección en la que se colocó "algún lugar" y reemplaza cualquier mención de él en la lista del ensamblador con esa dirección. Así que cuando el ensamblador ve esto:
...
jmp somewhere
...
...
somewhere:
some_instrunction
....
recuerda la dirección en la que se colocó "some_instrunction" y compila "jmp en algún lugar" del código binario "jmp_opcode address_of_some_instrunction".
Entonces, ¿qué tiene todo esto que ver con la advertencia del compilador que está recibiendo?
El compilador advierte que no ha asignado los controladores de interrupción para los eventos sobre los que está advirtiendo. Lo que el compilador hace con esto depende del compilador. Es posible que no genere una tabla de interrupciones (si las interrupciones no están habilitadas, esto no será un problema, si se producen, la interrupción saltará a algún lugar cerca del inicio de su programa, pero no del todo) (la posición exacta depende de la dirección de la interrupción)), puede colocar reti en lugar de jmps, por lo que si se activa la interrupción, regresa de inmediato, puede tener su propio controlador de interrupción de emergencia que detiene la ejecución del procesador.
¿Qué hace "#pragma vector = event" y "__interrupt void function_name ()"?
"__interrupt" le dice al compilador que la siguiente función es en realidad un controlador de interrupciones, por lo que no puede tener ningún argumento, en lugar de una instrucción ret, la función termina con un reti, y algunas sobre cosas como qué registros se guardan en la pila, etc.
"#pragma vector = event" le dice al compilador la interrupción de qué evento es la función siguiente y usar la dirección de esa función como un argumento para la instrucción jmp colocada en la dirección de la interrupción del "evento".
Por lo tanto, el código que escribió que detuvo las advertencias es un controlador para todos los eventos en las #pragmas escritas.
Cuando eliminó la función en sí misma, básicamente le dijo al compilador "la siguiente función es un controlador de interrupciones" pero no le dio una función. Así que el compilador todavía no tiene un controlador de interrupción. Colocar un #pragma como este (sin la función de la que está hablando) es peligroso, porque le gustaría comenzar a escribir otra cosa y que otra cosa se convertirá en un controlador de interrupciones. Aún más doloroso sería colocar tal #pragma en un archivo ".h" (¿o es el alcance de un #pragma solo un archivo?).
¿Son esas advertencias un problema?
Debe asegurarse de haber definido el controlador de interrupciones para todas las interrupciones que están habilitadas. Por lo general, hay un bit global_enable_interrupts que debe configurarse para que funcionen las interrupciones y un bit de habilitación por cada posible interrupción. Normalmente, el bit de habilitación de cada interrupción se encuentra en los registros de configuración del módulo periférico (uart, temporizador, etc.) que activa esa interrupción. Además, los bits de interrupt_triggered del módulo periférico generalmente se activan / desactivan incluso cuando las interrupciones están deshabilitadas (por ejemplo, uart tiene una interrupción byte_recieve, la interrupción está deshabilitada, pero el software puede verificar ese bit para ver si hay un byte se ha recibido, esto se puede utilizar para recibir bytes con sondeo).
Otra cosa que debes tener en cuenta es el NMI (interrupción no enmascarable), debes pensar qué pasará si / cuando se activa.