内容纲要
本课时介绍RTOS提供的变长内存分配方案原理及应用。
主要内容
在《自己动手从0到1写嵌入式操作系统》课程中,并没有实现变长存储管理。
不同的RTOS在实现变长存储管理时(即动态内存分配),功能和标准库malloc()/free()的功能基本一致,只不过有可能允许根据特定的硬件配置对具体实现方案进行配置。我们这节课时只讲一般性的实现原理和注意事项。
为何提供标准库已有的功能
- 有些开发工具中定义接口,但没有实现
- 标准C库提供的接口,不具备线程安全
- 有些设计者觉得标准库的实现过于复杂、性能低
外部碎片
在进行大量、不同大小的内存分配与释放时,有可能造成外部碎片。
在小型MCU上,虽然RTOS内部的内存管理算法会进行相相邻内存的合并与回收;但是光靠这些算法并不能完全解决外部碎片的问题。所以在使用这种内存分配方案时,要尽量避免这种方式分配内存。
实际分配究竟大小
如课程中所述,实际分配的内存空间总是比申请的大,因为OS必须用一些额外的内存用于帮助这些这种方式的内存分配。
具体实例
课程中演示的是使用标准库接口。如果你将来使用的RTOS也没有提供这种定长分配这群,也可以采用这种方式。
void task1Entry (void *param) {
Packet *packet;
int i = 0;
for (;;) {
tMutexWait(&heapMutex, 0);
packet = (Packet *)malloc(sizeof(Packet));
tMutexNotify(&heapMutex);
//tMemBlockWait(&packetMemBlock, (void **) &packet, 0);
packet->size = i++;
tMboxNotify(&packetMbox, packet, tMBOXSendNormal);
tTaskDelay(1);
}
}
/**
* 任务的运行代码
* @param param 任务初始运行参数
*/
void task2Entry (void *param) {
Packet *packet;
for (;;) {
tMboxWait(&packetMbox, (void **) &packet, 0);
xprintf("packet size:%d\n", packet->size);
//tMemBlockNotify(&packetMemBlock, packet);
tMutexWait(&heapMutex, 0);
free(packet);
tMutexNotify(&heapMutex);
}
}