STM32 FreeRTOS - UART延迟中断问题

Posted

技术标签:

【中文标题】STM32 FreeRTOS - UART延迟中断问题【英文标题】:STM32 FreeRTOS - UART Deferred Interrupt Problem 【发布时间】:2020-10-02 17:46:06 【问题描述】:

我正在尝试使用 UART 接收中断读取大小未知的数据。在回调函数中,我启用了 Rx 中断以读取字符,直到获得 \n。如果 \n 被获取,则被延迟中断处理程序的更高优先级任务被唤醒。问题是我尝试通过回调函数逐个读取字节,并尝试将每个字符放入缓冲区,但不幸的是缓冲区无法获取任何字符。此外,延迟中断处理程序无法被唤醒。

我的STM32板子是STM32F767ZI,我的IDE是KEIL。

分享代码前的一些重要说明: 1. rxIndex 和 gpsBuffer 被声明为全局。 2. 周期函数没有任何问题。

这是我的代码:

    周期性函数,优先级 = 1
void vPeriodicTask(void *pvParameters)

    const TickType_t xDelay500ms = pdMS_TO_TICKS(500UL);

    while (1) 
        vTaskDelay(xDelay500ms);

        HAL_UART_Transmit(&huart3,(uint8_t*)"Imu\r\n",sizeof("Imu\r\n"),1000);
        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);

    

    延迟中断,优先级 = 3
void vHandlerTask(void *pvParameters)

    const TickType_t xMaxExpectedBlockTime = pdMS_TO_TICKS(1000); 

    while(1) 
        if (xSemaphoreTake(xBinarySemaphore,xMaxExpectedBlockTime) == pdPASS) 
            HAL_UART_Transmit(&huart3,(uint8_t*)"Semaphore Acquired\r\n",sizeof("Semaphore 
                                                                                 Acquired\r\n"),1000);
            // Some important processes will be added here
            rxIndex = 0;
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
        
    

    回调函数:
void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)

        gpsBuffer[rxIndex++] = rData;
        if (rData == 0x0A) 
            BaseType_t xHigherPriorityTaskWoken;

            xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken);
            portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
        
        HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);

    主要功能
    HAL_UART_Receive_IT(&huart3,&rData,1);
    xBinarySemaphore = xSemaphoreCreateBinary();
    if (xBinarySemaphore != NULL) 
        //success
        xTaskCreate(vHandlerTask,"Handler",128,NULL,1,&vHandlerTaskHandler);

        xTaskCreate(vPeriodicTask,"Periodic",128,NULL,3,&vPeriodicTaskHandler);

        vTaskStartScheduler();
    

【问题讨论】:

【参考方案1】:

    使用 HAL 是解决问题的最佳方法。它使用依赖于 systick 的 HAL_Delay,您应该重写此函数以改为读取 RTOS 滴答声。

    我使用队列来传递数据(对数据的引用),但它应该可以工作。使用 HAL 函数时,总会有一个大大的问号。

void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)

     BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        gpsBuffer[rxIndex++] = rData;
        if (rData == 0x0A) 

            if(xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken) == pdFALSE)
            
                /* some error handling */
            
        
     HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
     portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);

最后,如果我使用 HAL 和 RTOS,我总是会修改 HAL 处理超时的方式。

【讨论】:

感谢您的关注!我要试试看:) 我不知道,因为我没有这个问题。但是我不使用 HAL 来处理像 UART 这样的简单外设

以上是关于STM32 FreeRTOS - UART延迟中断问题的主要内容,如果未能解决你的问题,请参考以下文章

在 STM32 上使用 FreeRTOS 处理多个中断

禁用中断让freeRTOS在stm32上运行

Stm32的中断在测试FREERTOS的时候的问题

stm32 uart停止释放

stm32 freertos 中回调函数需要做个任务么

STM32G0学习手册——Cortex M0+ NVIC 与FreeRTOS中断管理