[应用相关] Freertos队列传输复杂数据

[复制链接]
 楼主| renzheshengui 发表于 2025-7-12 15:03 | 显示全部楼层 |阅读模式
我们在使用队列进行传输数据的时候一般都是传一些传感器数据或者全局变量,但是如果有很多数据需要传输,那就需要开一堆队列进行传输和接收,这会使得系统变得冗杂,这时候我们可以采用结构体方法进行传输,代码如下
typedef enum        //枚举定义,可拓展传感器类型
{
    temp,
    hub
}data_source_t;
typedef struct      //存储传感器数据和类型
{
    int value;
    data_source_t data_source;
}data_t;
data_t data_send[2]=        //定义data_t类型的数组存储初始值
{
    {26,temp},
    {88,hub}
};



然后是任务堆栈和句柄已经任务函数分配
#define START_TASK_PRIO  1                 
#define START_TASK_SIZE  128               
TaskHandle_t StartTask_Handler;
void Start_Task(void *pvParameters);      //开始任务用于创建以下所有任务

#define TASK1_PRIO  2               
#define TASK1_SIZE  128              
TaskHandle_t  Task1_Handler;
void Task1(void *pvParameters);          //第一个任务led一直闪烁用于测试系统是否正常运行

#define TASK2_PRIO  3                 
#define TASK2_SIZE  128               
TaskHandle_t  send_temp_Handler;
TaskHandle_t  send_hub_Handler;
void send_task(void *pvParameters);
QueueHandle_t queue_handle;                //第二个任务是队列发送

#define TASK3_PRIO  4               
#define TASK3_SIZE  128              
TaskHandle_t  receive_Handler;
void receive_task(void *pvParameters);     //第三个任务是队列接收





void freertos_demo(void)                //这个函数放入main函数中创建开始任务
{
    xTaskCreate((TaskFunction_t )Start_Task,        
                (const char*    )"start_task",      
                (uint16_t       )START_TASK_SIZE,   
                (void*          )NULL,              
                (UBaseType_t    )START_TASK_PRIO,   
                (TaskHandle_t*  )&StartTask_Handler);
    vTaskStartScheduler();
}

void Start_Task(void *pvParameters)        //开始任务
{
    taskENTER_CRITICAL();                    //进入临界区

    queue_handle=xQueueCreate(5,sizeof(data_t));//创建队列

    xTaskCreate((TaskFunction_t )Task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1_Handler);

    xTaskCreate((TaskFunction_t )send_task,        //创建温度传感器队列发送任务
                (const char*    )"send_temp",
                (uint16_t       )TASK2_SIZE,
                (void*          )&data_send[0],
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&send_temp_Handler); //这两个任务使用同一个任务函数
                                                      //但是传入参数不同,句柄也不同
    xTaskCreate((TaskFunction_t )send_task,
                (const char*    )"send_hub",
                (uint16_t       )TASK2_SIZE,        //创建湿度传感器队列发送任务
                (void*          )&data_send[1],
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&send_hub_Handler);      

    xTaskCreate((TaskFunction_t )receive_task,
                (const char*    )"receive_task",
                (uint16_t       )TASK3_SIZE,            //队列接收任务
                (void*          )NULL,
                (UBaseType_t    )TASK3_PRIO,
                (TaskHandle_t*  )&receive_Handler);
    vTaskDelete(StartTask_Handler);
    taskEXIT_CRITICAL();
}   

void Task1(void *pvParameters)            //led闪烁检测系统是否不断运行
{
    while(1)
    {
        Led_On();
        vTaskDelay(500);
        Led_Off();
        vTaskDelay(500);
    }
}
void send_task(void *pvParameters)            //队列发送函数
{
    BaseType_t qStatus;
    TickType_t wait_time = pdMS_TO_TICKS(200);
    while (1)
    {                                        //根据pvParameters决定发送哪一个传感器数据
        qStatus = xQueueSend(queue_handle, pvParameters, wait_time);
        if (qStatus != pdPASS)
       {
            printf("Queue send failed! Parameter value: %d\n", ((data_t *)pvParameters)->value);
        }
        else
        {
            printf("Queue send success! Parameter value: %d\n", ((data_t *)pvParameters)->value);
        }
        vTaskDelay(100);
    }
}
void receive_task(void *pvParameters)        //队列接收
{
    BaseType_t qStatus;
    data_t receive_buffer;
    TickType_t wait_time = pdMS_TO_TICKS(100);
    while (1)
    {
        qStatus = xQueueReceive(queue_handle, &receive_buffer, wait_time);
        if (qStatus == pdPASS)                //判断接收数据的传感器类型进行区分数据
        {
            printf("Received data: value = %d, source = %d\r\n", receive_buffer.value, receive_buffer.data_source);
            if (receive_buffer.data_source == temp)
            {
                Serial_SendByte(receive_buffer.value);
            }
            else if (receive_buffer.data_source == hub)
            {
                Serial_SendByte(receive_buffer.value);
            }   
        }
    }
}



已经在代码中写入注释,本质上就是用枚举存储多种传感器类型,往结构体中存入传感器类型和数据,队列用同一个任务进行发送,但是传输不同的数据,这样队列数据会交替发送,在接收任务中对接收到的数据进行解包,分别判断2是哪个传感器类型的数据进行操作.
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/2301_80143498/article/details/149151702

小小蚂蚁举千斤 发表于 2025-7-28 23:12 | 显示全部楼层
Freertos队列传输复杂数据
您需要登录后才可以回帖 登录 | 注册

本版积分规则

109

主题

4307

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部