带有STM32 HAL驱动程序的FreeRTOS中的UART中断

时间:2019-05-02 04:11:10

标签: embedded stm32 freertos hal

我正在研究STM32L152VB-A控制器。我正在使用FreeRTOS。
我使用CubeMX生成代码,并为USART1配置了全局中断。
非中断RX和TX(HAL_UART_Receive和HAL_UART_Transmit)正在工作。
但是我正在尝试使其与中断一起工作。

只有在我调用HAL_UART_Receive_IT之后,我才会被中断。
由于我不知道接收数据的大小,因此我计划一个接一个地接收字符。

由于我使用RTOS,因此我对在何处写入HAL_UART_Receive_IT感到困惑,因为消息可能随时出现。有人可以指导我吗?

PS:我尝试在ISR中调用HAL_UART_Receive_IT,但它也不起作用。

2 个答案:

答案 0 :(得分:2)

我认为您正在将HAL_UART_Receive_IT与实际上接收任何内容的函数混淆。不是这种情况。此功能仅启用UART外设及其接收中断。

如果要坚持使用HAL库,则需要将UART_HandleTypeDef类型的结构作为参数传递给包含以下内容的HAL_UART_Receive_IT

  • 指向接收缓冲区的uint8_t *指针
  • 您想要接收的元素数量的转移计数器

据我所知,使用此框架无法无限期地接收元素,因为一旦传输计数器达到零,接收中断就会自动被禁用。因此,如果需要此功能,最好覆盖ST定义的弱函数(最有可能称为“ UARTx_IRQHandler”)自己编写ISR。

要最终将接收中断集成到FreeRTOS中,您有两个选择:

  1. 像HAL一样,将ISR内部的数据接收到原始(uint8_t *)缓冲区中,并使用关键部分在访问时临时禁用接收中断。
  2. 使用中断安全API将ISR中的数据接收到FreeRTOS队列中。 official FreeRTOS book第6章对此进行了很好的解释。

答案 1 :(得分:1)

我创建了以下任务(考虑高优先级):

void UARTReceiveTask(void const * argument)
{
  /* USER CODE BEGIN UARTReceiveTask */
  /* Infinite loop */
  for(;;)
  {
    osSemaphoreWait(BinarySemaphoreUARTHandle, osWaitForever);
    HAL_UART_Receive_IT(&huart3, message_received, 2);
  }
  /* USER CODE END UARTReceiveTask */
}

然后,如果您使用的是HAL,则必须知道HAL_UART_RxCpltCallback()是在UART ISR上执行的,所以我写道:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
    if (huart->Instance == USART3){
        osSemaphoreRelease(BinarySemaphoreUARTHandle);
    }
}

我只按照“掌握FreeRTOS”文档(第6章)中的提示来推迟对任务的中断。

我没有深入研究它,但是我知道info对于使用FreeRTOS和Arm Cortex系统非常重要。

希望我能帮上忙!