带有 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)?