天天看点

zephyr--堆内存池(heap memory pool)堆内存池概念实现建议的用法配置选项API

堆内存池

堆内存池(heap memory pool) 是一个预定义的内存池对象,它允许线程像使用

malloc()

那样从一段通用内存区动态地申请内存。

概念

堆内存池只能定义一个。与其它内存池不同的是,堆内存池不能通过内存地址对其引用。

堆内存池的大小是可配置的,支持如下大小:256 字节,1024 字节,4096 字节和 16384 字节。

线程可以调用函数

k_malloc()

来动态申请一大块堆内存。所分配的地址是 4 字节对齐的。如果内核没有找到合适的内存块,将返回一个

NULL

当线程使用完堆内存后,它应当调用

k_free()

将其释放到堆内存池中。

内部操作

堆内存池定义了一个包含整个堆的单一的最大尺寸块;即单一块的大小是 256、1024、4096 或 16384 字节。堆内存池也定义了一个最小尺寸块 —— 64 字节。下表展示了堆内存池在每种块尺寸下所能支持的块的数量。

堆尺寸 64字节的块 256字节的块 1025字节的块 4096字节的块 16384字节的块
256 4 1
1024 16 4 1
4096 64 16 4 1
16384 256 64 16 4 1
对于某个给定的尺寸的内存块,能同时分配到的数量通常小于上面的表所列举的结果。例如,每当从大小为 1024 字节的堆内存中分配一个大小为 256 字节的块后,所能分配到的大小为 64 字节的块的数量就会减 4。内存池 buffer 中的碎片也会进一步减小可用块的数量。

内存块被分配后,它的前 16 个字节将被内核用于记录块描述符。内核随后会使用该描述符释放块。因此,如果应用程序请求的堆内存大小是 N 字节,实际至少会使用 N+16 字节。

实现

定义堆内存池

配置选项

CONFIG_HEAP_MEM_POOL_SIZE

用于指定堆内存池的大小。

默认情况下,堆内存池的大小是零字节,它指示内核不要去定义堆内存池对象。

分配内存

函数

k_malloc()

用于分配一块堆内存。

下面的代码先申请了 200 字节的堆内存空间,然后将其填充为零。如果没有获取到所需的空间,它将打印一条警告消息。

注意,应用程序实际会接收到一个大小为 256 字节的内存块,因为这是堆内存池所支持的最接近的尺寸。

char *mem_ptr;
      
      
      
       mem_ptr = k_malloc(
       200);
      
      
       if (mem_ptr != 
       NULL)) {
      
          
       memset(mem_ptr, 
       0, 
       200);
      
      
           ...
      
      
       } 
       else {
      
          
       printf(
       "Memory not allocated");
      
      
       }
            

释放内存

函数

k_free()

用于释放一块堆内存。

下面的代码申请了 75 字节的内存块,并在不再使用时释放。(基于安全考虑,实际上会从堆内存池使用 256 字节的内存块。

char *mem_ptr;
      
      
      
       mem_ptr = k_malloc(
       75);
      
      
       ... 
       /* use memory block */
      
      
       k_free(mem_ptr);
            

建议的用法

您可以像使用

malloc()

那样使用堆内存池动态地分配内存。

配置选项

相关的配置选项:

  • CONFIG_HEAP_MEM_POOL_SIZE

API

头文件

kernel.h

中提供了如下的堆内存池 API:

  • k_malloc()

  • k_free()

继续阅读