|
|
hace 1 año | |
|---|---|---|
| adapter | hace 1 año | |
| example | hace 1 año | |
| include | hace 1 año | |
| pic | hace 1 año | |
| src | hace 1 año | |
| LICENSE | hace 1 año | |
| README.md | hace 1 año | |
| SConscript | hace 1 año | |
| flow.drawio | hace 1 año |
RMP(Rice Memory Pool)全称内存池,它是超级高效,并且线程安全的内存池组件。
场景1:在一些协议设计场景中,且协议报文长度相近
场景2:在RTOS环境中,邮箱的传输过程,邮箱指传输报文的起始地址,它不像消息队列一样内部实现会做数据拷贝。所以需要防护传输报文的内存。
├─adapter
│ └─rtthread
│ ├─rmp_mutex.c // rtthread mutex适配层
│ └─rmp_sem.c // rtthread sem适配层
├─example
│ └─rmp_rtt_example.c // rtthread 平台实例
├─include
│ ├─rmp_def.h // rmp 通用接口定义
│ └─rmp.h // rmp 对外头文件
└─src
└─rmp.c // rmp 核心代码源文件
| 接口 | 说明 |
|---|---|
| rmp_create | 动态创建内存池 |
| rmp_delete | 删除动态创建的内存池 |
| rmp_init | 内存池初始化 |
| rmp_deinit | 内存池去初始化 |
| rmp_alloc | 阻塞方式从内存池申请内存块 |
| rmp_try_alloc | 非阻塞方式从内存池申请内存块 |
| rmp_free | 释放内存块 |
| rmp_available | 内存池剩余内存块个数 |
动态创建内存池
内存池的空间通过malloc方式申请
mp_t *rmp_create(uint32_t size, uint32_t count);
| 参数 | 描述 |
|---|---|
| size | -- |
| count | -- |
| 返回 | —— |
| mp | 创建成功,返回内存池句柄 |
| NULL | 创建失败 |
删除动态创建的内存池
内存池的空间通过free方式释放。
void rmp_delete(rmp_t *mp);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| 返回 | —— |
| - |
内存池初始化
告知内存池单个内存块的大小和内存块个数
void rmp_init(rmp_t *mp, void *mem, uint32_t size, uint32_t count);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| mem | 指向内存池的指针,由用户提供 |
| size | 单个内存块的大小 |
| count | 内存块个数 |
| 返回 | —— |
| - |
内存池去初始化
void rmp_deinit(rmp_t *mp);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| 返回 | —— |
| - |
阻塞方式从内存池申请内存块
在非RTOS环境,它是非阻塞方式从内存池申请内存块
void *rmp_alloc(rmp_t *mp);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| 返回 | —— |
| mem | 申请到内存块 |
| NULL | 申请不到内存块 |
非阻塞方式从内存池申请内存块
在非RTOS环境,它和rmp_alloc功能一样。它是非阻塞方式从内存池申请内存块。
void *rmp_try_alloc(rmp_t *mp);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| 返回 | —— |
| mem | 申请到内存块 |
| NULL | 申请不到内存块 |
释放内存块
在非RTOS环境,它是非阻塞方式从内存池申请内存块
void rmp_free(rmp_t *mp, void *ptr);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| ptr | 需要释放的内存块 |
| 返回 | —— |
| - |
内存池中可用内存块剩余个数
uint32_t rmp_available(rmp_t *mp);
| 参数 | 描述 |
|---|---|
| mp | 内存池句柄 |
| 返回 | —— |
| num | 内存块剩余个数 |
实验说明:分别通过静态和动态定义一个内存池,内存池大小为(16 * 4),每个内存块为16,一共4块。连续申请5块,再释放第4块,再申请一块。
静态内存池方式:
#include "rmp.h"
int rmp_init(void)
{
uint8_t buff[16 * 4];
rmp_t mp;
rmp_init(&mp, buff, 16, 4);
void *mem1 = rmp_try_alloc(&mp);
if (mem1 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem1);
else
rt_kprintf("mem: NULL\n");
void *mem2 = rmp_try_alloc(&mp);
if (mem2 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem2);
else
rt_kprintf("mem: NULL\n");
void *mem3 = rmp_try_alloc(&mp);
if (mem3 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem3);
else
rt_kprintf("mem: NULL\n");
void *mem4 = rmp_try_alloc(&mp);
if (mem4 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem4);
else
rt_kprintf("mem: NULL\n");
void *mem5 = rmp_try_alloc(&mp);
if (mem5 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem5);
else
rt_kprintf("mem: NULL\n");
rmp_free(&mp, mem4);
void *mem6 = rmp_try_alloc(&mp);
if (mem6 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem6);
else
rt_kprintf("mem: NULL\n");
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rmp_init);
动态内存池方式:
#include "rmp.h"
int rmp_init(void)
{
rmp *mp = NULL;
mp = rmp_create(16, 4);
if (mp == NULL)
{
rt_kprintf("rmp create failed\n");
return -1;
}
void *mem1 = rmp_try_alloc(mp);
if (mem1 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem1);
else
rt_kprintf("mem: NULL\n");
void *mem2 = rmp_try_alloc(mp);
if (mem2 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem2);
else
rt_kprintf("mem: NULL\n");
void *mem3 = rmp_try_alloc(mp);
if (mem3 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem3);
else
rt_kprintf("mem: NULL\n");
void *mem4 = rmp_try_alloc(mp);
if (mem4 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem4);
else
rt_kprintf("mem: NULL\n");
void *mem5 = rmp_try_alloc(mp);
if (mem5 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem5);
else
rt_kprintf("mem: NULL\n");
rmp_free(&mp, mem4);
void *mem6 = rmp_try_alloc(mp);
if (mem6 != NULL)
rt_kprintf("mem: 0x%08X\n", (int)mem6);
else
rt_kprintf("mem: NULL\n");
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rmp_init);
实验运行结果:成功申请4次,失败1次,然后释放了1次,又可以申请1次。