本课时介绍RTOS提供的变长内存分配方案原理及应用。

主要内容

在《自己动手从0到1写嵌入式操作系统》课程中,并没有实现变长存储管理。
不同的RTOS在实现变长存储管理时(即动态内存分配),功能和标准库malloc()/free()的功能基本一致,只不过有可能允许根据特定的硬件配置对具体实现方案进行配置。我们这节课时只讲一般性的实现原理和注意事项。

为何提供标准库已有的功能

  • 有些开发工具中定义接口,但没有实现
  • 标准C库提供的接口,不具备线程安全
  • 有些设计者觉得标准库的实现过于复杂、性能低

    外部碎片

    在进行大量、不同大小的内存分配与释放时,有可能造成外部碎片。
    在小型MCU上,虽然RTOS内部的内存管理算法会进行相相邻内存的合并与回收;但是光靠这些算法并不能完全解决外部碎片的问题。所以在使用这种内存分配方案时,要尽量避免这种方式分配内存。
    变长内存管理 - 图1

    实际分配究竟大小

    如课程中所述,实际分配的内存空间总是比申请的大,因为OS必须用一些额外的内存用于帮助这些这种方式的内存分配。
    变长内存管理 - 图2

    具体实例

    课程中演示的是使用标准库接口。如果你将来使用的RTOS也没有提供这种定长分配这群,也可以采用这种方式。 ``` void task1Entry (void param) { Packet packet; int i = 0;

    for (;;) {

    1. tMutexWait(&heapMutex, 0);
    2. packet = (Packet *)malloc(sizeof(Packet));
    3. tMutexNotify(&heapMutex);
    4. //tMemBlockWait(&packetMemBlock, (void **) &packet, 0);
    5. packet->size = i++;
    6. tMboxNotify(&packetMbox, packet, tMBOXSendNormal);
    7. tTaskDelay(1);

    } }

/**

  • 任务的运行代码
  • @param param 任务初始运行参数 / void task2Entry (void param) { Packet *packet; for (;;) {

    1. tMboxWait(&packetMbox, (void **) &packet, 0);
    2. xprintf("packet size:%d\n", packet->size);
    3. //tMemBlockNotify(&packetMemBlock, packet);
    4. tMutexWait(&heapMutex, 0);
    5. free(packet);
    6. tMutexNotify(&heapMutex);

    } } ```

重点难点

注意事项

常见问题