Hi,
I have a question regarding uart_interrupt.c:
How does the ISR (DEMO_UART_IRQHandler) get invoked?
I cxhanged the example code from using UART0 to using UART4 and have updated the macros like this:
#define DEMO_UART_IRQn UART4_RX_TX_IRQn
#define DEMO_UART_IRQHandler UART4_RX_TX_IRQHandler
then enabling the interrupts looks like:
/* Enable RX interrupt. */
UART_EnableInterrupts(DEMO_UART, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable);
EnableIRQ(DEMO_UART_IRQn);
but I'm not sure now, if UART4RxInterrupt really invokes DEMO_UART_IRQHandler() and if it does, how is DEMO_UART_IRQHandler associated with the interrupt? I feel like I'm missing a piece somewhere.
Solved! Go to Solution.
Hey @stdcerr
If you Left click on UART4_RX_TX_IRQHandler and then hit F3 (to bring up the definition) you'll see:
WEAK void UART4_RX_TX_IRQHandler(void)
{ UART4_RX_TX_DriverIRQHandler();
}
This is the default definition of the interrupt handler for the UART4 RX/TX and if you repeat the F3 operation with the link inside the method, yoiu'll find that it leads to:
void UART1_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
and if you F3 "IntDefaultHandler" you'll get to:
//*****************************************************************************
// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.
//*****************************************************************************
WEAK_AV void IntDefaultHandler(void)
{ while(1) {}
}
Which is what you expect (ie if you haven't defined an interrupt handler, you're going to a default one that does nothing).
The default handler referenced above has the "WEAK" option which means that if the "UART4_RX_TX_IRQHandler" is redefined, as in the definition code, then the original vector (which leads to "IntDefaultHandler") is overwritten with the address of your (or the demo) handler code.
This is a feature of C99 which is completely non-intuitive but once you understand and accept it things become a bit more consistent when working with things like adding interrupt handlers.
Good luck,
myke
Hey @stdcerr
If you Left click on UART4_RX_TX_IRQHandler and then hit F3 (to bring up the definition) you'll see:
WEAK void UART4_RX_TX_IRQHandler(void)
{ UART4_RX_TX_DriverIRQHandler();
}
This is the default definition of the interrupt handler for the UART4 RX/TX and if you repeat the F3 operation with the link inside the method, yoiu'll find that it leads to:
void UART1_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler);
and if you F3 "IntDefaultHandler" you'll get to:
//*****************************************************************************
// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.
//*****************************************************************************
WEAK_AV void IntDefaultHandler(void)
{ while(1) {}
}
Which is what you expect (ie if you haven't defined an interrupt handler, you're going to a default one that does nothing).
The default handler referenced above has the "WEAK" option which means that if the "UART4_RX_TX_IRQHandler" is redefined, as in the definition code, then the original vector (which leads to "IntDefaultHandler") is overwritten with the address of your (or the demo) handler code.
This is a feature of C99 which is completely non-intuitive but once you understand and accept it things become a bit more consistent when working with things like adding interrupt handlers.
Good luck,
myke
I'm using spifi driver and sample code of polling transfer. my code was going in "WEAK_AV void IntDefaultHandler(void)
{ while(1) {}
}"
as well. Why do we need an interrupt handler? Why is the SKD sample code not taking care of the SPIFI interrupt?
Hi stdcerr:
Please see the vector table in devices/MK64F12\mcuxpresso\startup_mk64f12.c,
__attribute__ ((used, section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
// Core Level - CM4
&_vStackTop, // The initial stack pointer
ResetISR, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
PendSV_Handler, // The PendSV handler
SysTick_Handler, // The SysTick handler
// Chip Level - MK64F12
DMA0_IRQHandler, // 16 : DMA Channel 0 Transfer Complete
DMA1_IRQHandler, // 17 : DMA Channel 1 Transfer Complete
DMA2_IRQHandler, // 18 : DMA Channel 2 Transfer Complete
DMA3_IRQHandler, // 19 : DMA Channel 3 Transfer Complete
DMA4_IRQHandler, // 20 : DMA Channel 4 Transfer Complete
DMA5_IRQHandler, // 21 : DMA Channel 5 Transfer Complete
DMA6_IRQHandler, // 22 : DMA Channel 6 Transfer Complete
DMA7_IRQHandler, // 23 : DMA Channel 7 Transfer Complete
DMA8_IRQHandler, // 24 : DMA Channel 8 Transfer Complete
DMA9_IRQHandler, // 25 : DMA Channel 9 Transfer Complete
DMA10_IRQHandler, // 26 : DMA Channel 10 Transfer Complete
DMA11_IRQHandler, // 27 : DMA Channel 11 Transfer Complete
DMA12_IRQHandler, // 28 : DMA Channel 12 Transfer Complete
DMA13_IRQHandler, // 29 : DMA Channel 13 Transfer Complete
DMA14_IRQHandler, // 30 : DMA Channel 14 Transfer Complete
DMA15_IRQHandler, // 31 : DMA Channel 15 Transfer Complete
DMA_Error_IRQHandler, // 32 : DMA Error Interrupt
MCM_IRQHandler, // 33 : Normal Interrupt
FTFE_IRQHandler, // 34 : FTFE Command complete interrupt
Read_Collision_IRQHandler, // 35 : Read Collision Interrupt
LVD_LVW_IRQHandler, // 36 : Low Voltage Detect, Low Voltage Warning
LLWU_IRQHandler, // 37 : Low Leakage Wakeup Unit
WDOG_EWM_IRQHandler, // 38 : WDOG Interrupt
RNG_IRQHandler, // 39 : RNG Interrupt
I2C0_IRQHandler, // 40 : I2C0 interrupt
I2C1_IRQHandler, // 41 : I2C1 interrupt
SPI0_IRQHandler, // 42 : SPI0 Interrupt
SPI1_IRQHandler, // 43 : SPI1 Interrupt
I2S0_Tx_IRQHandler, // 44 : I2S0 transmit interrupt
I2S0_Rx_IRQHandler, // 45 : I2S0 receive interrupt
UART0_LON_IRQHandler, // 46 : UART0 LON interrupt
UART0_RX_TX_IRQHandler, // 47 : UART0 Receive/Transmit interrupt
UART0_ERR_IRQHandler, // 48 : UART0 Error interrupt
UART1_RX_TX_IRQHandler, // 49 : UART1 Receive/Transmit interrupt
UART1_ERR_IRQHandler, // 50 : UART1 Error interrupt
UART2_RX_TX_IRQHandler, // 51 : UART2 Receive/Transmit interrupt
UART2_ERR_IRQHandler, // 52 : UART2 Error interrupt
UART3_RX_TX_IRQHandler, // 53 : UART3 Receive/Transmit interrupt
UART3_ERR_IRQHandler, // 54 : UART3 Error interrupt
ADC0_IRQHandler, // 55 : ADC0 interrupt
CMP0_IRQHandler, // 56 : CMP0 interrupt
CMP1_IRQHandler, // 57 : CMP1 interrupt
FTM0_IRQHandler, // 58 : FTM0 fault, overflow and channels interrupt
FTM1_IRQHandler, // 59 : FTM1 fault, overflow and channels interrupt
FTM2_IRQHandler, // 60 : FTM2 fault, overflow and channels interrupt
CMT_IRQHandler, // 61 : CMT interrupt
RTC_IRQHandler, // 62 : RTC interrupt
RTC_Seconds_IRQHandler, // 63 : RTC seconds interrupt
PIT0_IRQHandler, // 64 : PIT timer channel 0 interrupt
PIT1_IRQHandler, // 65 : PIT timer channel 1 interrupt
PIT2_IRQHandler, // 66 : PIT timer channel 2 interrupt
PIT3_IRQHandler, // 67 : PIT timer channel 3 interrupt
PDB0_IRQHandler, // 68 : PDB0 Interrupt
USB0_IRQHandler, // 69 : USB0 interrupt
USBDCD_IRQHandler, // 70 : USBDCD Interrupt
Reserved71_IRQHandler, // 71 : Reserved interrupt
DAC0_IRQHandler, // 72 : DAC0 interrupt
MCG_IRQHandler, // 73 : MCG Interrupt
LPTMR0_IRQHandler, // 74 : LPTimer interrupt
PORTA_IRQHandler, // 75 : Port A interrupt
PORTB_IRQHandler, // 76 : Port B interrupt
PORTC_IRQHandler, // 77 : Port C interrupt
PORTD_IRQHandler, // 78 : Port D interrupt
PORTE_IRQHandler, // 79 : Port E interrupt
SWI_IRQHandler, // 80 : Software interrupt
SPI2_IRQHandler, // 81 : SPI2 Interrupt
UART4_RX_TX_IRQHandler, // 82 : UART4 Receive/Transmit interrupt
UART4_ERR_IRQHandler, // 83 : UART4 Error interrupt
UART5_RX_TX_IRQHandler, // 84 : UART5 Receive/Transmit interrupt
UART5_ERR_IRQHandler, // 85 : UART5 Error interrupt
CMP2_IRQHandler, // 86 : CMP2 interrupt
FTM3_IRQHandler, // 87 : FTM3 fault, overflow and channels interrupt
DAC1_IRQHandler, // 88 : DAC1 interrupt
ADC1_IRQHandler, // 89 : ADC1 interrupt
I2C2_IRQHandler, // 90 : I2C2 interrupt
CAN0_ORed_Message_buffer_IRQHandler, // 91 : CAN0 OR'd message buffers interrupt
CAN0_Bus_Off_IRQHandler, // 92 : CAN0 bus off interrupt
CAN0_Error_IRQHandler, // 93 : CAN0 error interrupt
CAN0_Tx_Warning_IRQHandler, // 94 : CAN0 Tx warning interrupt
CAN0_Rx_Warning_IRQHandler, // 95 : CAN0 Rx warning interrupt
CAN0_Wake_Up_IRQHandler, // 96 : CAN0 wake up interrupt
SDHC_IRQHandler, // 97 : SDHC interrupt
ENET_1588_Timer_IRQHandler, // 98 : Ethernet MAC IEEE 1588 Timer Interrupt
ENET_Transmit_IRQHandler, // 99 : Ethernet MAC Transmit Interrupt
ENET_Receive_IRQHandler, // 100: Ethernet MAC Receive Interrupt
ENET_Error_IRQHandler, // 101: Ethernet MAC Error and miscelaneous Interrupt
}; /* End of g_pfnVectors */
when interrupt (82 : UART4 Receive/Transmit interrupt) fires, then isr UART4_RX_TX_IRQHandler will be called.
Regards
Daniel