title: Why stm32nucleo board uart can't receive message after almost three or four hundred times using HAL_UART_Receive_IT
body: <p>I am developing uart communication on STMicroelectronics NUCLEO-G474RE Board(stm32G474RETX MCU, 64pins) using MDK-v5, but run into a perplexing problem these several days, make no progress on it and have to reach out to seek some help. If anyone could give me a right way to go, it would be appreciated greatly.</p>
  
  <p>Code is not complicated, I use cubeMX to initialize the code base with usart2 configured, and use two threads based on cmsis v2 api for receiving occassinally and transmiting periodically(in 2 seconds). </p>
  
  <p><strong>The auto-generated usart2 init code</strong></p>
  
  <pre><code>static void MX_USART2_UART_Init(void)
  {
  
    /* USER CODE BEGIN USART2_Init 0 */
  
    /* USER CODE END USART2_Init 0 */
  
    /* USER CODE BEGIN USART2_Init 1 */
  
    /* USER CODE END USART2_Init 1 */
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 115200;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
    huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init(&amp;huart2) != HAL_OK)
    {
      Error_Handler();
    }
    if (HAL_UARTEx_SetTxFifoThreshold(&amp;huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
      Error_Handler();
    }
    if (HAL_UARTEx_SetRxFifoThreshold(&amp;huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
      Error_Handler();
    }
    if (HAL_UARTEx_DisableFifoMode(&amp;huart2) != HAL_OK)
    {
      Error_Handler();
    }
    /* USER CODE BEGIN USART2_Init 2 */
  
    /* USER CODE END USART2_Init 2 */
  
  }
  </code></pre>
  
  <p><strong>Interrupt call back code</strong></p>
  
  <pre><code>void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
  {
      printf("Interrupt error occured(0x%x)!!!\r\n", huart-&gt;ErrorCode);
  }
  
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
  {
      UNUSED(huart);
      if(huart == &amp;huart2 || huart == &amp;huart3){
          uint8_t aEnterLine[] = "\r\n";
          //HAL_UART_Transmit(huart, aEnterLine, sizeof(aEnterLine), 0xFFFF);
          //HAL_UART_Transmit(huart, gRxBuffer, 11, 0xFFFF);
          //HAL_UART_Transmit(huart, aEnterLine, sizeof(aEnterLine), 0xFFFF);
          //printf("%s\r\n", gRxBuffer);
          if(g_cmdExecuting == 0)
              osEventFlagsSet(evt_id, 0x00000001U);
      }else if(huart == &amp;huart1){
  
      }else{
  
      }
  
      HAL_UART_Receive_IT(huart, (unsigned char*)gRxBuffer, 11);
  }
  
  int8_t app_usart_transmit(uint8_t* buf, uint8_t len)
  {
  
      return 0;
  }
  
  int8_t app_usart_init(UART_HandleTypeDef* huart)
  {
      if(huart == NULL)
          return -1;
  
      if(huart == &amp;huart2 || huart == &amp;huart3){
          uint8_t aTxStartMessage[] = "\r\n****UART-Hyperterminal commmunication based on IT****"
                                      "\r\nEnter 10 characters using keyboard: \r\n";
  
          HAL_UART_Transmit(huart, aTxStartMessage, sizeof(aTxStartMessage), 0xFFFF);                         
      }
  
      clear_rx_buffer();
      HAL_UART_Receive_IT(huart, (uint8_t*)gRxBuffer, 11);
      return 0;
  }
  </code></pre>
  
  <p><strong>rx &amp; tx worker code</strong></p>
  
  <pre><code>extern osMutexId_t myMutex01Handle;
  extern osEventFlagsId_t evt_id;
  extern osEventFlagsId_t evt_id1;
  osTimerId_t timer_id;
  
  static osThreadId gTask1Handle;
  static const osThreadAttr_t gTask1Attrbutes = {
      .name = "Task1",
      .priority = (osPriority_t) osPriorityAboveNormal,
      .stack_size = 512
  };
  
  static osThreadId gTask2Handle;
  static const osThreadAttr_t gTask2Attrbutes = {
      .name = "Task2",
      .priority = (osPriority_t) osPriorityNormal,
      .stack_size = 512
  };
  
  uint8_t g_cmdExecuting = 0;
  uint8_t g_SemExec = 0;
  uint32_t timer_cnt;
  
  void update_stat_timer(void* argument)
  {
      timer_cnt++;
      //osMutexAcquire(myMutex01Handle, osWaitForever);
      printf("update_stat_timer executes %u times, ====++++====++++\r\n", timer_cnt);
      //osMutexRelease(myMutex01Handle);
  }
  
  
  void update_stat_task_run(void* argument)
  {
      uint32_t count;
      for(;;){
          osDelay(2000);
          count++;
          osMutexAcquire(myMutex01Handle, osWaitForever);
          printf("update_stat_task_run executes %d times, ====++++====++++\r\n", count);
          osMutexRelease(myMutex01Handle);
      }
  }
  
  void exec_cmd_task_run(void* argument)
  {
      uint32_t flags;
  
      for(;;){
          flags = osEventFlagsWait(evt_id, 0x00000001U, osFlagsWaitAny, osWaitForever);
          g_cmdExecuting = 1;
          osMutexAcquire(myMutex01Handle, osWaitForever);
          osDelay(1000);
          printf("exec_cmd_task Print\r\n");
          osMutexRelease(myMutex01Handle);
          g_cmdExecuting = 0;
      }
  }
  
  int8_t app_task_init()
  {
      osStatus_t status;
  
      gTask1Handle = osThreadNew(exec_cmd_task_run, NULL, &amp;gTask1Attrbutes);
      gTask2Handle = osThreadNew(update_stat_task_run, NULL, &amp;gTask2Attrbutes);
  
      //uint32_t exec = 1;
      //timer_id = osTimerNew(update_stat_timer, osTimerPeriodic, &amp;exec, NULL);
      //if(status != osOK){
          //;
      //}
      //osTimerStart(timer_id, 2000U);
      return 0;
  }
  </code></pre>
  
  <p><strong>My Question:</strong>
  It could receive and transmit msg at very begining, but after receiving three or four hundred times, it couldn't receive the msg anymore while the transmitting is ok, and I also use the timer api to replace the transmitting thread, the result is the same, it couldn't receive any msg after hundreds times.
  <a href="https://i.stack.imgur.com/Ho0p9.png" rel="nofollow noreferrer">the testing result pic</a></p>