【问题标题】:Malloc fails to allocate memory on atmega2561 and freeRTOSMalloc 无法在 atmega2561 和 freeRTOS 上分配内存
【发布时间】:2015-12-09 00:20:56
【问题描述】:

我正在尝试使用 malloc() 函数为链接列表创建节点。在我的例子中,该函数在以下虚拟代码段上返回 NULL。

我在 atmega 2561 上运行 FREERTOS。

 if (!malloc(sizeof(struct Event))
    {
        //The code gets inside here
    } else {
        //
    }

节点的结构如下:

struct Event 
{
    uint8_t shouldCarBrake;
    uint16_t tachoPoint;
    struct Event *next;
};

【问题讨论】:

  • 我不知道 atmega2561。你知道你是否有足够的内存吗?
  • 是的,我已经检查过了
  • 这一行:if (!malloc(sizeof(struct Event)) 最好写成:if (NULL == (ptr = malloc(sizeof(struct Event)) ) ) 事实上,没有设置指针变量,所以发布的代码会导致内存泄漏,因为(不存在) 指针变量不能传递给free(0
  • @John :如何检查?该信息可能应该在问题中。这不仅仅是拥有空闲内存的问题。该内存必须分配给堆,并且堆本身必须有一个连续的内存块来满足分配请求(即,即使累积起来有足够的内存,也不能太碎片化而无法分配)。
  • 你使用谁的编译器和标准库实现?一些库(例如Newlib)需要存根实现以支持堆管理,而其他库(avr-libc)可能需要对您的目标进行配置。

标签: c embedded avr atmel freertos


【解决方案1】:

如果项目设置为使用 FreeRTOS 随附的五个示例堆内存管理文件中的四个,则 C 库提供的堆大小可能为零。在 5 个中只有 heap_3 使用 malloc。请参阅http://www.freertos.org/a00111.html 了解更多信息。

【讨论】:

    【解决方案2】:

    标准库malloc() 通常不是线程安全的,因此可能不应该在这种情况下使用。一些库为标准库的互斥锁提供存根,但如果不是这种情况,或者您选择不实现它们,那么malloc() 本身应该被包装在一个带有互斥锁的函数中,或者一个替代的线程安全堆管理实现用过的。 FreeRTOS 提供了这两个选项,如 here 所述。

    标准的malloc() 实现也是非确定性的——另一个不在实时关键代码中使用它的原因;您无法确定互斥锁将被锁定多长时间,因此不仅分配的线程是不确定的,任何等待分配的线程也是如此。

    即使没有 FreeRTOS 对各种分配器的支持,也很容易以一种易于移植到任何 RTOS 的方式实现确定性固定块内存分配器。您只需预先分配一个(或多个)内存块池(静态地或在实时调度开始之前从标准堆中),并用指向块的指针填充一个 RTOS 队列。然后分配就是从队列中获取一个指针,然后通过将指针返回到队列来解除分配。

    【讨论】:

      猜你喜欢
      • 2017-12-05
      • 2012-02-26
      • 2015-01-05
      • 1970-01-01
      • 2012-12-26
      • 2013-02-23
      • 2013-07-04
      • 1970-01-01
      • 2022-11-10
      相关资源
      最近更新 更多