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

在FreeRTOS中使用LinkedList无法保存值的问题咨询

在Arduino FreeRTOS任务中使用LinkedList类无法正确保存值的解决方案

我在搭载Atmel 328P和2560的Arduino上运行FreeRTOS 10.0时,也碰到过几乎一模一样的问题——LinkedList(甚至换QList库)在标准Arduino的loop()里工作完全正常,但放到RTOS任务中后,虽然size()计数器能正常递增,可调用get()返回的结果全是0。

结合你提供的代码和输出来看,核心问题出在任务栈空间不足上,下面是具体的分析和解决步骤:

问题根源分析

你创建TaskTest任务时指定的栈大小是128,但在AVR架构的FreeRTOS中,栈大小的单位是字(Word),每个字占2字节,所以128字实际只有256字节的栈空间。而你在任务函数里创建的LinkedList<byte> list是栈上对象,再加上循环中频繁add()操作需要的临时变量、函数调用栈帧,这点空间完全不够,会直接导致栈溢出,覆盖链表节点存储的真实数据,最终出现get()返回0的异常。

而标准Arduino的loop()函数使用的是主栈,主栈大小通常远大于RTOS任务栈(比如AVR的主栈一般有几KB),所以不会触发这个问题。

解决步骤

1. 优先增大任务栈空间

修改xTaskCreate中的栈大小参数,至少调整到512(对应1024字节),如果是Arduino Mega 2560这类内存更大的板子,可以直接调到1024:

xTaskCreate( TaskTest , (const portCHAR *)"Test" , 512 , NULL , 2 , NULL );

2. 优化链表对象的存储位置

如果增大栈后还是有异常,可以把链表对象从任务栈移到全局空间,或者用动态分配放在堆上:

  • 全局对象方式:
#include <Arduino_FreeRTOS.h>
#include <LinkedList.h>

LinkedList<byte> list; // 全局声明链表对象

void TaskTest( void *pvParameters );

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }
  xTaskCreate( TaskTest , (const portCHAR *)"Test" , 256 , NULL , 2 , NULL );
}

void loop() { }

void TaskTest( void *pvParameters __attribute__((unused)) ) {
  for (int i = 0; i < 256; i++) {
    list.add(i);
    Serial.print(i);
    Serial.print(',');
    Serial.print(list.get(list.size() - 1));
    Serial.print(',');
    Serial.println(list.size());
  }
  for (;;) {
    vTaskDelay(1);
  }
}
  • 堆分配方式:
void TaskTest( void *pvParameters __attribute__((unused)) ) {
  LinkedList<byte>* list = new LinkedList<byte>(); // 在堆上分配链表对象
  for (int i = 0; i < 256; i++) {
    list->add(i);
    Serial.print(i);
    Serial.print(',');
    Serial.print(list->get(list->size() - 1));
    Serial.print(',');
    Serial.println(list->size());
  }
  for (;;) {
    vTaskDelay(1);
  }
}

3. 确认FreeRTOS内存堆配置

如果链表内部使用了动态内存分配(比如malloc),要确保FreeRTOS的堆配置足够。可以在FreeRTOSConfig.h中调整configTOTAL_HEAP_SIZE的值,比如设置为2048(2KB):

#define configTOTAL_HEAP_SIZE    ( ( size_t ) 2048 )

验证结果

按照上述方法修改后,任务应该能正确保存链表值,输出会和标准Arduino代码一致:

249,249,250
250,250,251
251,251,252
...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:23:09