You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FreeRTOS队列异常:发送0-4整数,接收值却全为5的问题排查

问题原因分析

你的问题核心是队列中存储的是指向同一个局部变量的指针,而非实际数值,具体逻辑如下:

  1. 任务3中,Value指针始终指向局部变量count,每次调用xQueueSend时,你传递的是&Value(即指针变量自身的地址),队列会将Value的值(也就是&count,即count的内存地址)复制到队列元素中。因此队列的5个元素存储的都是同一个地址:&count。

  2. 当for循环结束后,count的值会变为5(因为循环条件是count < 5,最后一次循环执行完count++后,count的值为5才会退出循环)。

  3. 任务4读取队列时,每次拿到的都是&count这个地址,解引用*RxValue得到的就是count当前的值5,因此所有读取结果都是5。

修正方案

方案一:发送实际数值(推荐,适合简单整数场景)

这种方式直接将整数的数值存入队列,不需要使用指针:

修改任务3代码

void task_3(void *args)
{
    uint32_t count = 0;
    ESP_EARLY_LOGI(TAG, "Task 3 entered..");

    if (myQueue_2 == NULL)
    {
        printf("myQueue_2 could not be created !\n");
    }
    
    ESP_EARLY_LOGI("TASK 3", "Data waiting in myQueue_2_1 : %d, Space available : %d", uxQueueMessagesWaiting(myQueue_2), uxQueueSpacesAvailable(myQueue_2));
   
    for (count = 0; count < 5;count++)
    {
        ESP_EARLY_LOGI("TASK 3", "Value = %d\n", count);
        // 直接发送count的地址,队列会复制count的数值到队列中
        xQueueSend(myQueue_2, &count, (TickType_t)0);
    }

    ESP_EARLY_LOGI("TASK 3", "Data waiting in myQueue_2_1 : %d, Space available : %d", 
    uxQueueMessagesWaiting(myQueue_2), uxQueueSpacesAvailable(myQueue_2));
    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

修改任务4代码

void task_4(void *args)
{
    // 用普通变量接收数值,不再用指针
    uint32_t RxValue;

    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(500));
        
        if (uxQueueMessagesWaiting(myQueue_2) > 0)
        {
            xQueueReceive(myQueue_2, &RxValue, (TickType_t)5);
            // 直接输出RxValue,不需要解引用
            ESP_EARLY_LOGI("TASK 4", "Received from myQueue_2 = %d\n", RxValue);
            ESP_EARLY_LOGI("TASK 4", "Data waiting in myQueue_2 : %d, Space available : %d", 
            uxQueueMessagesWaiting(myQueue_2), uxQueueSpacesAvailable(myQueue_2));
        }
    }
}

注意

确保队列myQueue_2创建时,元素大小设置为sizeof(uint32_t),例如:

myQueue_2 = xQueueCreate(5, sizeof(uint32_t));

方案二:发送独立内存的指针(适合复杂数据场景)

如果必须使用指针传递数据,需要为每个数值分配独立的动态内存,避免所有指针指向同一个变量:

修改任务3代码

void task_3(void *args)
{
    uint32_t count = 0;
    ESP_EARLY_LOGI(TAG, "Task 3 entered..");

    if (myQueue_2 == NULL)
    {
        printf("myQueue_2 could not be created !\n");
    }
    
    ESP_EARLY_LOGI("TASK 3", "Data waiting in myQueue_2_1 : %d, Space available : %d", uxQueueMessagesWaiting(myQueue_2), uxQueueSpacesAvailable(myQueue_2));
   
    for (count = 0; count < 5;count++)
    {
        // 为每个数值分配独立内存
        uint32_t *pValue = (uint32_t*)pvPortMalloc(sizeof(uint32_t));
        if (pValue != NULL) {
            *pValue = count;
            ESP_EARLY_LOGI("TASK 3", "Value = %d\n", *pValue);
            // 发送指针本身的值(即分配的内存地址)
            xQueueSend(myQueue_2, &pValue, (TickType_t)0);
        }
    }

    ESP_EARLY_LOGI("TASK 3", "Data waiting in myQueue_2_1 : %d, Space available : %d", 
    uxQueueMessagesWaiting(myQueue_2), uxQueueSpacesAvailable(myQueue_2));
    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

修改任务4代码

void task_4(void *args)
{
    uint32_t *RxValue = NULL;

    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(500));
        
        if (uxQueueMessagesWaiting(myQueue_2) > 0)
        {
            xQueueReceive(myQueue_2, &RxValue, (TickType_t)5);
            if (RxValue != NULL) {
                ESP_EARLY_LOGI("TASK 4", "Received from myQueue_2 = %d\n", *RxValue);
                // 使用完内存后释放,避免内存泄漏
                vPortFree(RxValue);
                RxValue = NULL;
            }
            ESP_EARLY_LOGI("TASK 4", "Data waiting in myQueue_2 : %d, Space available : %d", 
            uxQueueMessagesWaiting(myQueue_2), uxQueueSpacesAvailable(myQueue_2));
        }
    }
}

注意

队列创建时元素大小要设置为sizeof(uint32_t*):

myQueue_2 = xQueueCreate(5, sizeof(uint32_t*));

内容的提问来源于stack exchange,提问作者Softtoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:01:18