Skip to main content

Command Palette

Search for a command to run...

CaPiTaLiZaTiOn

Published
2 min readView as Markdown

I was in the middle of adding DMA to my STM32 QuadSPI driver using the ST HAL layer. For the HAL layer to update its QSPI state I need to catch the QUADSPI_IRQn IRQ and call the corresponding HAL QSPI IRQ-handler.

The assembler code below is the STM32 startup weak definition of the QUADSPI_IRQHandler, which goes to an endless loop in Default_Handler if it is not redefined in code.

// Weak definition of the QUADSPI IRQ exception handler function
    .weak    QUADSPI_IRQHandler
    .thumb_set QUADSPI_IRQHandler,Default_Handler


/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @param  None
 * @retval : None
*/
    .section    .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
    b    Infinite_Loop
    .size    Default_Handler, .-Default_Handler

Below is the override function I defined in my .cpp file.

extern "C"
{
   /**
     * @brief  This function handles QUADSPI interrupt request.
     * @param  None
     * @retval None
     */
   void QuadSPI_IRQHandler(void)
   {
     HAL_QSPI_IRQHandler(&qspiHandle);
   }
}

My problem when running the code is that I was thrown into the endless loop default interrupt handler while I expected the interrupt to be handled in my override function.

I expected that my QuadSPI_IRQHandler function had not overridden the default handler. One way to quickly test that is to comment the original weak definition and check for compiler errors:

obj\debug\bcm4platform\boot\startup_stm32g473xx.o:(.isr_vector+0x1bc): undefined reference to `QUADSPI_IRQHandler'

After some head scratching I realized my override function was not capitalized correctly. A quick fix later and my IRQ handling function was being called!

extern "C"
{
   /**
     * @brief  This function handles QUADSPI interrupt request.
     * @param  None
     * @retval None
     */
   void QUADSPI_IRQHandler(void)
   {
     HAL_QSPI_IRQHandler(&qspiHandle);
   }
}

The lesson for today is to always check your CaPiTaLiZaTiOn.