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

FreeRTOS队列程序异常:串口监视器未打印队列数值

问题分析与解决方案:ESP32 FreeRTOS队列无输出

核心问题:loop函数未被执行

你在setup函数末尾调用了vTaskDelete(NULL),这会直接删除当前运行的任务——也就是Arduino核心用于执行setup和后续loop循环的任务。没有这个任务,loop函数永远不会被触发,计数器num根本没机会写入队列,自然没有数据能被printMessages任务读取打印。

修复步骤

  1. 移除vTaskDelete(NULL):删除setup末尾的这行代码,让Arduino核心的任务能正常进入loop循环,执行队列写入逻辑。
  2. 优化队列读取逻辑(可选但更高效):原代码中printMessages任务用非阻塞方式轮询队列(超时时间为0),配合1秒延时可能导致数据处理不及时。改为阻塞式读取(用portMAX_DELAY作为超时),任务会自动等待队列有数据再处理,无需额外延时:
    if (xQueueReceive(msg_queue, (void *)&item, portMAX_DELAY) == pdTRUE)
    {
      Serial.println(item);
    }
    
  3. 增加队列创建校验:添加队列创建结果检查,避免因内存不足导致的空指针问题:
    if (msg_queue == NULL) {
      Serial.println("Queue creation failed!");
      while(1); // 挂起系统,提示错误
    }
    

修复后的完整代码

// Use only core 1 
#if CONFIG_FREERTOS_UNICORE
  static const BaseType_t app_cpu = 0;
#else
  static const BaseType_t app_cpu = 1;
#endif

// Settings
static const uint8_t msg_queue_len = 5;

// Globals
static QueueHandle_t msg_queue;


// Task: wait for item and print it
void printMessages(void *parameters)
{
  int item;

  // Loop forever
  while(1)
  {
    // Block until a message is available
    if (xQueueReceive(msg_queue, (void *)&item, portMAX_DELAY) == pdTRUE)
    {
      Serial.println(item);
    }
  }
}

// main (runs as its own task with priority 1 on core 1)
void setup() 
{
  // Configure Serial
  Serial.begin(115200);

  // Wait a moment to start (so we don't miss Serial output)
  vTaskDelay(1000 / portTICK_PERIOD_MS);
  Serial.println();
  Serial.println("---FreeRTOS Heap Demo---");

  // Create queue
  msg_queue = xQueueCreate( msg_queue_len, sizeof(int) );

  // Check if queue creation succeeded
  if (msg_queue == NULL) {
    Serial.println("Queue creation failed!");
    while(1);
  }

  // Start Serial receive task
  xTaskCreatePinnedToCore(printMessages,
                          "Print Message",
                          1024,
                          NULL,
                          1,
                          NULL,
                          app_cpu);
}

void loop() 
{
  static int num = 0;

  // Try to add item to queue for 10 ticks, fail if queue is full
  if (xQueueSend(msg_queue, (void *)&num, 10) != pdTRUE)
  {
    Serial.println("Queue full");
  }
  num++;

  // Wait before trying again
  vTaskDelay(1000 / portTICK_PERIOD_MS);
}

预期输出

---FreeRTOS Heap Demo---
0
1
2
3
4
Queue full
Queue full
...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:07:38