RTX笔记10 - 内存池Memory Pool

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:内存块已经被释放会内存池。

osErrorParameter:mp_id参数错误,block指向不可用的内存。

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

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

osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id)

删除一个内存池。

返回值:

osOK:内存池已经被删除。

osErrorParameter:mp_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 }

相关推荐

什么是库存管理散件?如何高效管理库存散件解析
365bet投注盘口

什么是库存管理散件?如何高效管理库存散件解析

📅 08-21 👁️ 8920
暗影诗章
office365无法登录激活

暗影诗章

📅 08-20 👁️ 7426
歌手【张磊】最新歌曲下载
365BET导航

歌手【张磊】最新歌曲下载

📅 09-06 👁️ 6589
怎么用U盘安装win10原版系统
office365无法登录激活

怎么用U盘安装win10原版系统

📅 07-24 👁️ 7779
微信朋友圈为什么可以设置3天可见,主要有以下三点原因,秒懂
玩游戏用win7还是win8
365bet投注盘口

玩游戏用win7还是win8

📅 08-02 👁️ 458