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

我正在尝试使用 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();
    }

【问题讨论】:

    标签: stm32 semaphore uart freertos


    【解决方案1】:
    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 处理超时的方式。

    【讨论】:

    • 感谢您的关注!我要试试看:)
    • 我不知道,因为我没有这个问题。但是我不使用 HAL 来处理像 UART 这样的简单外设
    猜你喜欢
    • 2020-05-06
    • 1970-01-01
    • 2019-09-20
    • 2021-04-01
    • 2020-03-23
    • 2019-02-26
    • 2018-07-14
    • 2017-04-07
    • 2021-01-16
    相关资源
    最近更新 更多