(Específico para el Arduino Uno ...)
¿Qué le sucede a la pila cuando ocurre una interrupción en un microcontrolador AVR y llamo a una función? ¿El compilador incorpora el código? ¿Almacena la pila en algún lugar y luego restablece el puntero de la pila? ¿Tiene una pila secundaria solo para interrupciones?
Según tengo entendido, el vector para la interrupción es un comando GOTO directo en ensamblador. Además, no creo que el microcontrolador se meta automáticamente con la pila, por lo que probablemente se quede solo. Sin embargo, eso todavía no explica cómo funcionan las funciones durante un ISR.
arduino
interrupts
compiler
Pingüino anónimo
fuente
fuente
Respuestas:
El AVR es una arquitectura RISC, por lo que tiene un manejo bastante básico del hardware de las interrupciones. La mayoría de los procesadores se meten con la pila durante las interrupciones, aunque hay un par, especialmente ARM y PowerPC, que utilizan diferentes métodos.
En cualquier caso, esto es lo que hace el AVR para las interrupciones:
Cuando se produce una interrupción, el hardware del procesador realiza estos pasos, que no son solo un simple GOTO:
Ahora en este punto, el hardware ha hecho todo lo que va a hacer. El software tiene que estar escrito correctamente para no romper cosas. Por lo general, los siguientes pasos son a lo largo de estas líneas.
Empuje el registro de estado en la pila. (Esto debe hacerse primero antes de cambiarlo).
Empuje cualquier registro de CPU que se (o pueda) cambiar en la pila. El modelo de programación define qué registros que deben guardarse de esta manera. El modelo de programación lo define el compilador.
Ahora se puede ejecutar el código de interrupción de trabajo. Para responder el caso en la cuestión de llamar a una función, simplemente hace lo que siempre hace, empuja el valor de retorno en la pila y luego lo vuelve a abrir cuando termina. Esto no afecta a ninguno de estos valores anteriores que guardamos en la pila hasta ahora.
Ahora hemos terminado y queremos volver de la interrupción. Primero tenemos que hacer la limpieza del software.
Ejecute la instrucción RTI. El hardware realiza estos pasos para esta instrucción:
a. Habilite la bandera de interrupción global. (Tenga en cuenta que al menos una instrucción debe ejecutarse antes de que se cumpla la próxima interrupción. Esto evita que las interrupciones intensas bloqueen completamente el trabajo en segundo plano).
si. Introduzca la dirección de retorno guardada en la PC.
Ahora volvemos al código normal.
Tenga en cuenta que hay algunos puntos en los que debemos ser muy cuidadosos, especialmente en relación con el registro de estado y guardar registros que podrían modificarse. Afortunadamente, si está utilizando un compilador de C, todo esto se maneja debajo de las cubiertas.
Además, debes observar la profundidad de tu stack. En cualquier momento cuando las interrupciones están habilitadas, un ISR podría usar más de la pila de lo que es obvio al mirar el código local. Por supuesto, esto realmente no surge mucho a menos que esté llevando su memoria al límite.
Aquí hay un enlace que describe este proceso si desea una referencia.
fuente
ISR_NAKED
). Esto le permite omitir los pasos 5,6,8,9, en un contexto en el que realmente necesita esos ciclos. La desventaja es que debe estar absolutamente seguro de que conservará los registros relevantes o podrá sobrescribirlos sin dañarlos.