RTX笔记10 - 内存池Memory Pool

  内存池是线程安全的固定大小的内存块。它们的运行速度比动态分配的堆快得多,而且不会出现碎片问题。由于是线程安全的,因此可以从线程和ISR访问它们。

  内存池可以看作是固定大小的可用(未使用)内存块的链表。从池中分配内存(使用osMemoryPoolAlloc),只需从列表中解链一个块,并将控制权交给用户。向池释放内存(使用osMemoryPoolFree)只需将块重新链接到列表中。

  共享内存是线程间交换信息的基本模型之一。使用内存池交换数据,与消息队列相比,可以在线程之间共享更复杂的对象。内存池管理功能用于定义和管理这种固定大小的内存池。

  Note:osMemoryPoolAlloc, osMemoryPoolFree, osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize, osMemoryPoolGetCount, osMemoryPoolGetSpace可以在中断中调用。

1 typedef struct {
2   const char                   *name;   /** 指向内存池的名称 **/
3   uint32_t                 attr_bits;   /** 保留属性位 **/
4   void                      *cb_mem;    /** 指向内存池控制块的内存。NULL,使用动态内存分配内存 **/
5   uint32_t                   cb_size;   /** 内存池控制块的内存大小 **/
6   void                      *mp_mem;    /** 指向存储数据的内存。NULL,使用动态内存分配内存 **/
7   uint32_t                   mp_size;   /** 存储数据的内存大小 **/
8 } osMemoryPoolAttr_t;

  osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr)

    函数创建并初始化一个内存池对象,并返回指向内存池对象标识符的指针,在出现错误时返回NULL。不能在中断中调用。

    输入参数:

      block_count:内存块的最大数量。

      block_size  :内存块的字节大小

      attr             :内存块属性

    返回值:内存块ID,或者NULL。

  void * osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout)

     申请一个内存块。timeout参数指定系统等待分配内存的时间。当系统等待时,调用此函数的线程将被置于BLOCKED状态。只要至少有一块内存可用,线程就会变成READY。

    输入参数:

      mq_id :内存池ID。

      timeout:等待超时时间。0,函数立即返回;osWaitForever,一直等待,直到消息从消息队列中获取;others,等待的tick数。

    返回值:返回申请的内存地址,如果没有足够的内存池可以申请则返回NULL。

    Note:用户使用内存块时要注意内存块的大小,不能越界使用;如果超时时间设置为0,则可以在中断中调用。

  osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block)

    释放内存块,放回内存池中。

    输入参数:

      mq_id :内存池ID。

      block:已分配的要返回给内存池的内存块的地址。

    返回值:

      osOK:内存块已经被释放会内存池。

      osErrorParametermp_id参数错误,block指向不可用的内存。

      osErrorResource内存池处于不可用状态。

    Note:osMemoryPoolFree可能会对给定的块指针执行某些检查。但是使用osMemoryPoolFree释放的指针不是从osMemoryPoolAlloc申请的指针,会有UNPREDICTED行为。可以在中断中调用。

  osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id)

    删除一个内存池。

    返回值:

      osOK:内存池已经被删除。

      osErrorParametermp_id参数错误。

      osErrorResource内存池处于不可用状态。

      osErrorISR:中断中调用错误。

 1 #define OBJ_NBR_MAX    6
 2 
 3 typedef struct {
 4     uint8_t ix;
 5     uint32_t buf[8];
 6 } Obj;
 7 
 8 osMemoryPoolId_t mem_pool;
 9 
10 static void _ledThread(void *argument);
11 
12 void
13 testMemPool(void)
14 {
15     mem_pool = osMemoryPoolNew(OBJ_NBR_MAX, sizeof(Obj), NULL);
16     osThreadNew(_ledThread, NULL, NULL);
17 }
18 
19 static void
20 _ledThread(void *argument)
21 {
22     Obj *obj;
23     
24     argument = (void *)0;
25     
26     for(;;) {
27         obj = (Obj *)osMemoryPoolAlloc(mem_pool, 10);
28         if(NULL != obj) {
29             obj->ix = 1;
30             obj->buf[0] = (uint32_t)argument;
31             argument = (void *)((uint32_t)argument + 1);
32             menuShow(&seg_led, obj->buf[0], 0);
33             osMemoryPoolFree(mem_pool, obj);
34         }
35         osDelay(1000);
36     }    
37 }

 

posted @ 2021-10-04 22:28  Ivan0512  阅读(796)  评论(0编辑  收藏  举报