VxWorks提供了两个库,memPartLib和memLib,用于内存分区的管理(memory partition management)。今天以32位的Vx69为例,扒一扒相关的函数
首先是创建partition
/* 挂接创建partition的钩子函数 */
STATUS memPartCreateHookSet(FUNC_CREATE_HOOK createHook, BOOL guardEnable);
/*
* 在地址pPool上创建一个大小为size的partition
* 入参pPool可以为NULL,size可以为0,然后使用memPartAddToPool()扩展
*/
PART_ID memPartCreate(char *pPool, size_t size);
/* 当partition使用完毕,可以将其删除并释放其内存 */
STATUS memPartDelete(PART_ID partId);
/* 扩展之前创建的partition */
STATUS memPartAddToPool(PART_ID partId, char *pPool, size_t size);
有了partition,就可以使用内存块了
size_t memDefaultAlignment;/* default alignment size */
/*
* 从partition partId里,申请长度为nBytes的内存
* 起始地址对齐到memDefaultAlignment
* 例如Intel Arch里,memDefaultAlignment = 8
*/
void *memPartAlloc(PART_ID partId, size_t nBytes);
/* 也可以显式的将地址对齐到不小于memDefaultAlignment的alignment */
void *memPartAlignedAlloc(PART_ID partId, size_t nBytes, size_t alignment);
/* 可以修改已申请内存的size */
void *memPartRealloc(PART_ID partId, char *pBlock, size_t newSize);
/* 释放之前申请的内存 */
STATUS memPartFree(PART_ID partId, char *pBlock);
/* 申请count个、长度为size的内存块到pPtrArray */
STATUS memPartAllocN
(
PART_ID partId,
size_t size,
void **pPtrArray,
UINT count
);
/* 释放之前申请的count个内存块 */
STATUS memPartFreeN
(
PART_ID partId,
void **pPtrArray,
UINT count
);
typedef void *(*FUNC_ALLOC_HOOK)
(
PART_ID partId,
void *hookArg,
size_t nBytes,
size_t alignment
);
typedef STATUS (*FUNC_FREE_HOOK)
(
PART_ID partId,
void *hookArg,
char *ptr
);
typedef void *(*FUNC_REALLOC_HOOK)
(
PART_ID partId,
void *hookArg,
char *ptr,
size_t nBytes
);
typedef STATUS (*FUNC_DELETE_HOOK)
(
PART_ID partId,
void *hookArg
);
/* attach alloc, free, realloc and delete hooks */
STATUS memPartHooksInstall
(
PART_ID partId,
void *hookArg,
FUNC_ALLOC_HOOK allocHook,
FUNC_FREE_HOOK freeHook,
FUNC_REALLOC_HOOK reallocHook,
FUNC_DELETE_HOOK deleteHook
);
partition及内存块的属性
/* INCLUDE_MEM_SHOW */
/* 打印partition partId的内存使用情况 */
STATUS memPartShow
(
PART_ID partId,
int type /* 0 = statistics, 1 = statistics & list, 2 = statistics & list & extra info */
);
/* INCLUDE_MEM_MGR_INFO */
typedef struct
{
unsigned long numBytesFree; /* Number of Free Bytes in Partition */
unsigned long numBlocksFree; /* Number of Free Blocks in Partition */
unsigned long maxBlockSizeFree;/* Maximum block size that is free. */
unsigned long numBytesAlloc; /* Number of Allocated Bytes in Partition */
unsigned long numBlocksAlloc; /* Number of Allocated Blocks in Partition */
unsigned long maxBytesAlloc; /* Maximum number of Allocated Bytes at any time */
}MEM_PART_STATS;
/* 获得partition的一些属性值 */
STATUS memPartInfoGet(PART_ID partId, MEM_PART_STATS *pPartStats);
/* 查询partition中最大内存块的长度 */
ssize_t memPartFindMax(PART_ID partId);
/* 可用的option */
#if 0
/* 申请内存阶段 */
MEM_ALLOC_ERROR_EDR_FATAL_FLAG
MEM_ALLOC_ERROR_EDR_WARN_FLAG
MEM_ALLOC_ERROR_SUSPEND_FLAG
MEM_ALLOC_ERROR_LOG_FLAG
/* 释放内存阶段 */
MEM_BLOCK_ERROR_EDR_FATAL_FLAG
MEM_BLOCK_ERROR_EDR_WARN_FLAG
MEM_BLOCK_ERROR_SUSPEND_FLAG
MEM_BLOCK_ERROR_LOG_FLAG
#endif
/* 设置partition的option */
STATUS memPartOptionsSet(PART_ID partId, unsigned options);
/* 查询partition的option */
STATUS memPartOptionsGet(PART_ID partId, UINT *pOptions);
/* 查询pBlock的长度 */
size_t memBlockSizeGet(void *pBlock);
/* 验证pBlock是否有效或溢出 */
STATUS memPartBlockValidate(PART_ID partId, char *pBlock);
其实VxWorks本身已经创建了一个memory partition,它就是System Memory Partition,也叫做Heap。其PART_ID是全局变量memSysPartId。因此,VxWorks又封装了一组专门用于Heap的API,例如常见的malloc()、free()等
/* 扩展内存到Heap */
STATUS memAddToPool(char *pPool, size_t size);
/* 从Heap里申请内存 (ANSI) */
void *malloc(size_t nBytes);
/* 在Heap里修改已申请内存的长度 (ANSI) */
void *realloc(void *pBlock, size_t newSize);
/* 释放已申请的内存到Heap (ANSI) */
void free(void *ptr);
/* 以对齐的地址从Heap里申请内存 */
void *memalign(size_t alignment, size_t size);
/* 从Heap里申请内存,对齐到page的起始地址 */
void *valloc(size_t size);
/* 申请内存并初始化为0 (ANSI) */
void *calloc(size_t elemNum, size_t elemSize);
/* 释放calloc()申请的内存 */
STATUS cfree(char *pBlock);
/* 设置Heap的option */
STATUS memOptionsSet(unsigned options);
/* 查询Heap的option */
STATUS memOptionsGet(UINT *pOptions);
/* 获得Heap的一些属性值 */
STATUS memInfoGet(MEM_PART_STATS *pPartStats);
/* 查询Heap中最大内存块的长度 */
ssize_t memFindMax();
/* 打印Heap的内存使用情况 */
STATUS memShow(int type);
对比一下这两组API
Partition | Heap |
---|---|
memPartCreateHookSet | |
memPartCreate | |
memPartDelete | |
memPartAddToPool | memAddToPool |
memPartAlloc | malloc |
memPartAlignedAlloc | memalign |
memPartRealloc | realloc |
memPartFree | free |
valloc | |
calloc | |
cfree | |
memPartAllocN | |
memPartFreeN | |
memPartHooksInstall | |
memPartInfoGet | memInfoGet |
memPartFindMax | memFindMax |
memPartOptionsSet | memOptionsSet |
memPartOptionsGet | memOptionsGet |
memBlockSizeGet | |
memPartBlockValidate | |
memPartShow | memShow |
写一个小栗子,看看memory partition的使用
#include <stdio.h>
#include <stdLib.h>
#include <memLib.h>
#include <memPartLib.h>
#define PART_SIZE (5*1024*1024)
PART_ID testPartId;
char *testBuf;
static char *partAddr0;
static char *partAddr1;
void testMemPart(int type)
{
UINT32 option;
partAddr0 = malloc(PART_SIZE);
testPartId = memPartCreate(partAddr0, PART_SIZE);
printf("### memPartFindMax: %#x ###\n", memPartFindMax(testPartId));
memPartOptionsGet(testPartId, &option);
printf("### memPartOptionsGet: %#x ###\n", option);
memPartShow(testPartId, type);
printf("\n### memPartAlloc: %#x ###\n", 10);
testBuf = memPartAlloc(testPartId, 10);
printf("### size: %d ###\n", memBlockSizeGet(testBuf));
memPartShow(testPartId, type);
printf("\n### memPartRealloc: %#x ###\n", 20);
memPartRealloc(testPartId, testBuf, 20);
printf("### size: %d ###\n", memBlockSizeGet(testBuf));
memPartShow(testPartId, type);
printf("\n### memPartFree ###\n");
memPartFree(testPartId, testBuf);
memPartShow(testPartId, type);
printf("\n### memPartAddToPool ###\n");
partAddr1 = malloc(PART_SIZE);
memPartAddToPool(testPartId, partAddr1, PART_SIZE);
memPartShow(testPartId, type);
}
void testMemPartFree()
{
memPartDelete(testPartId);
free(partAddr1);
free(partAddr0);
}
代码下载地址
https://pan.baidu.com/s/1lQjA_eJUHxk95NdQ0x1d5g?pwd=s4bp
提取码:s4bp