A menudo veo algo como esto void UART2_IRQHandler(void) __irq
, y me pregunto por qué se usa __irq al declarar el controlador de interrupción, ¿es necesario o el controlador puede funcionar sin él?
Básicamente, una rutina de servicio de interrupción escrita en C es simplemente una función que no toma argumentos y no devuelve nada void someKindOfIsr(void)
.
__irq
es una extensión del lenguaje C para su compilador que se utiliza para generar instrucciones especiales de ensamblado de entrada y/o salida para manejar interrupciones. Por ejemplo, la instrucción de retorno puede ser diferente si regresa de una interrupción en lugar de una función simple para borrar algún tipo de registro de estado de interrupción.
Si es necesario o no, depende de la arquitectura ARM con la que esté trabajando. Una forma rápida de averiguar si es necesario para su plataforma es examinar el ensamblaje producido con y sin la __irq
palabra clave.
Incluso si el archivo de listado es exactamente el mismo con y sin la __irq
palabra clave, es posible que desee considerar dejar la __irq
palabra clave en su lugar para mayor claridad y portabilidad a alguna plataforma futura.
Algunos microcontroladores requieren un manejo diferente de la pila y el retorno para las funciones de manejo de interrupciones que para las funciones normales.
Para los controladores ARM, una entrada normal a una subrutina usa un PUSH para guardar cosas en la pila, y al salir de la subrutina, devolvería el estado guardado y dejaría la subrutina. ( Referencia de ensamblaje ARM página 65 )
Para un controlador de excepciones en las plataformas ARM modernas, el estado se inserta automáticamente en la pila, por lo que el compilador no necesita crear una instrucción PUSH en la entrada de la función. Además, la salida de un controlador de excepciones puede verse diferente de uno normal, la arquitectura ARMv7-M regresará de una excepción si POP/LDM, LDR o BX cargan un valor de 0xFXXXXXXX
en el contador del programa (PC).
Entonces, le __irq
dice al compilador que la entrada y salida de esta función puede requerir un tratamiento especial, y especial dependiendo del objetivo establecido (para 8051, creo que había RET para retorno normal y RETI para retorno de interrupción).
No, no puede funcionar sin _irq. es un formato general. tienes que seguir esto. de lo contrario no funcionará.
__irq
hace en el compilador?
Cisne y
AlfaGoku