首页 > 解决方案 > 用于将中断与 FreeRTOS 中的任务同步的二进制信号量

问题描述

大家好,我正在使用 RTOS 迈出第一步。UART我试图在中断模式下接收大量数据。我有一个显示任务,其中命令被写入全局缓冲区,我刚刚创建了一个UART Handler Task我想读取字节的位置。我面临的问题是。

  1. 我在里面使用的信号量UART Task是未知的,即使我在主函数中声明它是全局的,所以xSemaphoreTake()函数在那里有错误。也许一个有用的注意:这UART Task是在一个单独的文件中。
  2. 我的实现HAL_UART_RxCpltCallbackUART Task干净的吗?

这是我写的代码:

SemaphoreHandle_t uartInterruptSemaphore = NULL;
int main(void)
{
  /* USER CODE BEGIN 1 */

    void mainTask(void* param) {
        uartInterruptSemaphore = xSemaphoreCreateBinary();
        if(uartInterruptSemaphore != NULL) {
            // Display Thread with a 2 priority
            xTaskCreate(&displayTask, "Display Thread", 1000, &huart4, 2, NULL);

            // deferred Interrupt to be synchronized with the Display Task, must have a higher priority than the display task
            xTaskCreate(&UartHandlerTask, "UART Handler Task", 1000, &huart4, 3, NULL);
        }
        for(;;){
        }
}

我写的回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uart_cb) {

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    if(uart_cb->Instance == USART4) {
        xSemaphoreGiveFromISR(uartInterruptSemaphore, &xHigherPriorityTaskWoken);
    }
    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}

和处理程序任务:

void UartHandlerTask(void* param) {

    huart_cache = param;
    const uint8_t tmp = rx_byte; //rx byte is global volatile variable
    for(;;){
        if(xSemaphoreTake(uartInterruptSemaphore, portMAX_DELAY) == pdPASS) {
            HAL_UART_Receive_IT((UART_HandleTypeDef *)huart_cache, (uint8_t *)&rx_byte, 1);
            // write data to the buffer
            RX_interrupt(tmp);
        }
    }
}

标签: cmicrocontrolleruartfreertos

解决方案


我建议在尝试使用 RTOS 之前更好地处理 C。与使用二进制信号量相比,这还将向您展示一种从中断中解除阻塞任务的更好方法:https ://www.freertos.org/2020/09/decrease-ram-footprint-and-accelerate-execution-with-freertos -notifications.html


推荐阅读