cancel
Showing results for 
Search instead for 
Did you mean: 

multiple definition of `USART1_IRQHandler' after enabling global interrupts in cubemx.

gazzatav
Associate III

I am trying to transmit repeatedly using HAL_UART_Transmit_DMA(). The first transmit works. All following fail. The HAL_UART_TxCpltCallback() does not fire. All information I can find on this says you have to check the box 'USART1 global interrupt/...

After checking that box I get the error:

multiple definition of `USART1_IRQHandler'; ./Application/User/stm32f30x_mc_it.o:C:/Software/STM32CubeIDE/STM32-20220817_mcrot/Src/stm32f30x_mc_it.c:147: first defined here.

Searching for 'usart1' in stm32f30x_mc_it.c reveals there is no such definition. In fact the only mention of this function is in the startup file and stm32fxx_it.c. There is a definition for USART_IRQHandler in stm32f30x_mc_it.c.

I'm using the reference manual UM1786. Is there something better? The section 'How to use this driver' on p. 598 is not much use because after generating the code with CubeMX it is not clear what still needs to be done.

So do I need to enable global interrupts and if so, how do I get past this issue?

1 ACCEPTED SOLUTION

Accepted Solutions
gazzatav
Associate III

This looks like a bug in CubeMX. After generating, parameters_conversion.h has a define:

#define USART_IRQHandler USART1_IRQHandler

In stm32f3xx_it.c we have:

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
 
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
 
  /* USER CODE END USART1_IRQn 1 */
}

and then in stm32f3xx_mc_it.c we have:

void USART_IRQHandler(void)
{
 
 /* USER CODE BEGIN USART_IRQn 0 */
 
  /* USER CODE END USART_IRQn 0 */
  if (LL_USART_IsActiveFlag_RXNE(pUSART.USARTx)) /* Valid data have been received */
  {
    uint16_t retVal;
    retVal = *(uint16_t*)UFCP_RX_IRQ_Handler(&pUSART,LL_USART_ReceiveData8(pUSART.USARTx));
    if (retVal == 1)
    {
      UI_SerialCommunicationTimeOutStart();
    }
    if (retVal == 2)
    {
      UI_SerialCommunicationTimeOutStop();
    }
  /* USER CODE BEGIN USART_RXNE */
 
  /* USER CODE END USART_RXNE  */
  }
 
  if (LL_USART_IsActiveFlag_TXE(pUSART.USARTx))
  {
    UFCP_TX_IRQ_Handler(&pUSART);
    /* USER CODE BEGIN USART_TXE */
 
    /* USER CODE END USART_TXE   */
  }
 
  if (LL_USART_IsActiveFlag_ORE(pUSART.USARTx)) /* Overrun error occurs */
  {
    /* Send Overrun message */
    UFCP_OVR_IRQ_Handler(&pUSART);
    LL_USART_ClearFlag_ORE(pUSART.USARTx); /* Clear overrun flag */
    UI_SerialCommunicationTimeOutStop();
    /* USER CODE BEGIN USART_ORE */
 
    /* USER CODE END USART_ORE   */
  }
  /* USER CODE BEGIN USART_IRQn 1 */
 
  /* USER CODE END USART_IRQn 1 */
 
}

That's never going to work is it. I can't believe I'm the first person to hit this problem!

Guess I'll comment out the define in parameters_conversion and see what happens.

View solution in original post

1 REPLY 1
gazzatav
Associate III

This looks like a bug in CubeMX. After generating, parameters_conversion.h has a define:

#define USART_IRQHandler USART1_IRQHandler

In stm32f3xx_it.c we have:

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
 
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
 
  /* USER CODE END USART1_IRQn 1 */
}

and then in stm32f3xx_mc_it.c we have:

void USART_IRQHandler(void)
{
 
 /* USER CODE BEGIN USART_IRQn 0 */
 
  /* USER CODE END USART_IRQn 0 */
  if (LL_USART_IsActiveFlag_RXNE(pUSART.USARTx)) /* Valid data have been received */
  {
    uint16_t retVal;
    retVal = *(uint16_t*)UFCP_RX_IRQ_Handler(&pUSART,LL_USART_ReceiveData8(pUSART.USARTx));
    if (retVal == 1)
    {
      UI_SerialCommunicationTimeOutStart();
    }
    if (retVal == 2)
    {
      UI_SerialCommunicationTimeOutStop();
    }
  /* USER CODE BEGIN USART_RXNE */
 
  /* USER CODE END USART_RXNE  */
  }
 
  if (LL_USART_IsActiveFlag_TXE(pUSART.USARTx))
  {
    UFCP_TX_IRQ_Handler(&pUSART);
    /* USER CODE BEGIN USART_TXE */
 
    /* USER CODE END USART_TXE   */
  }
 
  if (LL_USART_IsActiveFlag_ORE(pUSART.USARTx)) /* Overrun error occurs */
  {
    /* Send Overrun message */
    UFCP_OVR_IRQ_Handler(&pUSART);
    LL_USART_ClearFlag_ORE(pUSART.USARTx); /* Clear overrun flag */
    UI_SerialCommunicationTimeOutStop();
    /* USER CODE BEGIN USART_ORE */
 
    /* USER CODE END USART_ORE   */
  }
  /* USER CODE BEGIN USART_IRQn 1 */
 
  /* USER CODE END USART_IRQn 1 */
 
}

That's never going to work is it. I can't believe I'm the first person to hit this problem!

Guess I'll comment out the define in parameters_conversion and see what happens.