首页 > 解决方案 > STM32 FreeRTOS - UART延迟中断问题

问题描述

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

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

分享代码前的一些重要说明: 1. rxIndex 和 gpsBuffer 被声明为全局。2. 周期功能正常工作。

这是我的代码:

  1. 周期函数,优先级 = 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);

    }
}
  1. 延迟中断,优先级 = 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);
        }
    }
}
  1. 回调函数:
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);
}
  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();
    }

标签: stm32semaphoreuartfreertos

解决方案


  1. 使用 HAL 是解决问题的最佳方法。它使用依赖于 systick 的 HAL_Delay,你应该重写这个函数来读取 RTOS 滴答声。

  2. 我使用队列来传递数据(对数据的引用),但它应该可以工作。使用 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 处理超时的方式。


推荐阅读