头图

main入口


int main(void)
{
    // 硬件初始化 。。。
    
    user_main();
  
    while (1)
    {
    }

下面这段代码是一个使用FreeRTOS实现的简单示例,目的是演示多个任务如何使用队列进行UART(通用异步接收/发送器)发送

通信机制

这个示例的核心是通过队列在不同任务之间安全地传递数据。在该示例中,队列充当了生产者(vTask1和vTask2)和消费者(vTaskUartSend)之间的缓冲区。

#include "user_main.h"
#include <stdbool.h>
#include <string.h>

#include "arm_math.h"
#include "main.h"
#include "usart.h"

#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
#include "task.h"

// UART发送缓冲队列
QueueHandle_t xUARTSendQueue;

void vTask1(void *argument);
void vTask2(void *argument);
void vTaskUartSend(void *argument);

void user_main(void)
{
    // 创建队列
    xUARTSendQueue = xQueueCreate(50, sizeof(char));
    // 创建任务
    xTaskCreate(vTask1, "vTask1", 128, NULL, 1, NULL);
    xTaskCreate(vTask2, "vTask2", 128, NULL, 1, NULL);
    // 创建UART发送任务
    xTaskCreate(vTaskUartSend, "vTaskUartSend", 128, NULL, 2, NULL);
    
    // 启动调度
    vTaskStartScheduler();

    Error_Handler();
}

任务vTask1vTask2

这两个任务作用相同,它们每500毫秒发送一个字符串到UART发送队列。在发送字符串之前,它们通过调用taskENTER_CRITICALtaskEXIT_CRITICAL进入和退出临界区,字符串的每个字符都逐个加入到xUARTSendQueue队列中,以保证字符串作为一个整体被放入队列,避免被另一个任务打断


void vTask1(void *argument)
{
    (void)argument;
    const char *txt = "vTask1\n";
    while (1)
    {
        // 进入临界区
        taskENTER_CRITICAL();
        //将字符串每个字符一次传入到队列中
        for(int i = 0; i < strlen(txt); i++) {
            xQueueSend(xUARTSendQueue, &txt[i], NULL);
        }
        // 退出临界
        taskEXIT_CRITICAL();
        
        vTaskDelay(500);
    }
}

void vTask2(void *argument)
{
    (void)argument;
    const char *txt = "vTask2\n";
    while (1)
    {
        taskENTER_CRITICAL();
        for(int i = 0; i < strlen(txt); i++) {
            xQueueSend(xUARTSendQueue, &txt[i], NULL);
        }
        taskEXIT_CRITICAL();
        
        vTaskDelay(500);
    }
}

UART发送任务vTaskUartSend

这个任务的作用是从xUARTSendQueue队列中持续读取字符,并通过HAL_UART_Transmit函数将它们发送出去。任务使用xQueueReceive从队列中接收字符,如果队列为空,该任务会阻塞直到队列中有数据可读。portMAX_DELAY参数确保了在队列为空时,任务会无限期等待直到有数据可用。


void vTaskUartSend(void *argument)
{
    (void)argument;

    char c;
    
    while (1)
    {
        // 从队列中依次读取字符,并打印。
        xQueueReceive(xUARTSendQueue, &c, portMAX_DELAY);
        HAL_UART_Transmit(&huart1, (uint8_t *)&c, 1, 10);
    }
}


step1nto
1 声望1 粉丝