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

Posted

技术标签:

【中文标题】带有 STM32 HAL 驱动程序的 FreeRTOS 中的 UART 中断【英文标题】:UART Interrupts in FreeRTOS with STM32 HAL driver 【发布时间】:2019-09-20 13:39:49 【问题描述】:

我正在研究 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,但它也不起作用。

【问题讨论】:

【参考方案1】:

我认为您将 HAL_UART_Receive_IT 与实际接收任何内容的函数混淆了。不是这种情况。该函数仅使能 UART 外设及其接收中断。

如果您想坚持使用 HAL 库,您需要将 UART_HandleTypeDef 类型的结构作为参数传递给 HAL_UART_Receive_IT,其中包含

指向接收缓冲区的 uint8_t* 指针 您希望接收的元素数量的传输计数器

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

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

    像 HAL 一样将 ISR 内的数据接收到原始 (uint8_t*) 缓冲区中,并使用临界区在访问时临时禁用接收中断。 使用中断安全 API 将 ISR 内的数据接收到 FreeRTOS 队列中。 official FreeRTOS book 第 6 章很好地解释了这一点。

【讨论】:

【参考方案2】:

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

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 章)中的提示来推迟对任务的中断。

我还没有深入研究,但我知道如果您使用的是 FreeRTOS 和 Arm Cortex 系统,info 很重要。

希望我能帮上忙!

【讨论】:

以上是关于带有 STM32 HAL 驱动程序的 FreeRTOS 中的 UART 中断的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 STM32 HAL_CAN 库生成格式正确的 TX CAN 帧?

带有 HAL 库的 STM32F4-Discovery (STM32F429ZIT6) 上的 RS232 (UART)?

带有 FreeRTOS 的 STM HAL,是/否/也许?

带有 STM32f103c8t6 Bluepill 和 CAN 总线的 HAL_CAN_ERROR_PARAM

STM32 HAL CAN TX 邮箱

如何重置 STM32 HAL UART 驱动程序 (HAL) 状态?