现在的位置: 首页 > 技术文章 > 正文

DAVINCI之路—CMEM模块分析

2015年07月08日 技术文章 ⁄ 共 2133字 ⁄ 字号 DAVINCI之路—CMEM模块分析已关闭评论 ⁄ 阅读 2,464 次

cmem用于管理一个或者多个连续的物理块内存并提供地址转换(虚拟地址转换到物理地址或物理地址转换到虚拟地址)功能,物理连续地址内存用于主处理器与DSP(或者协处理器、DMA)的数据BUF共享。

在系统启动的时候,av_capture_load.sh运行加载cmemk.ko驱动初始化,注册字符设备CMEM,并传递命令参数到内核,格式如下:

Insmod cmemk.ko phys_start=0x83C00000,phys_end=0x88000000
pools=50x512,2x4096,2x8192,2x16384,1x32768,1x51200,1x102400,1x4096000

phys_start、phys_end代表CMEM的开始和结束物理地址,16进制表示。
pools代表分配的内存池,指定了大小和数量,如50x512,表示分配50个512大小的空间,十进制表示。

上面SH文件中的命令行创建了8个pools,分别是:50 buffers of size 512,2 buffers of size 4096,2 buffers of size 8192,2 buffers of size 16384,1 buffers of size 32768,1 buffers of size 51200,1 buffers of size 102400,1 buffers of size 4096000。实际分配是以页为最小单位,大小依赖于平台页的大小(PAGE_SIZE,一般为4K),如50x512,实际分配的是50x4096。因此,实际分配的Pools空间大于等于命令行请求的大小。CMEM剩余空间用于Heap的分配。

Davinci系统内存可以分成两大类:

LINUX系统管理——kmalloc获取内核空间内存,malloc获取用户空间内存。

CMEM模块管理——CMEM_alloc获得cmem内存,CMEM_free()释放cmem内存

memory

memory

通过修改U-BOOT的参数bootargs配置linux系统内存大小,剩下的内存通过加载CMEM,用于内核模块CMEM使用。

CMEM内存可以分成4种类型:

Video/Audio codec usage memory

Encode data circular buffer

Cache pool buffer

Input/output buffer

CMEM模块软件结构包括两部分:驱动和封装的中间库。中间库是调用驱动的接口(open、release、mmap、ioctl)实现,用于向应用层提供统一API接口函数。

提供的API接口如下:


/* Initialize the CMEM module. Must be called before other API calls. */

int CMEM_init (void)
/*Finalize the CMEM module.*/

CMEM_exit (void)
/*Find the pool that best fits a given buffer size and has a buffer available*/

int CMEM_getPool (size_t size)
/* Allocate memory from a specified pool*/
void * CMEM_allocPool (int poolid, CMEM_AllocParams *params)

/*Allocate memory of a specified size.*/
void * CMEM_alloc (size_t size, CMEM_AllocParams *params)
/*Free a buffer previously allocated with CMEM_alloc()/CMEM_allocPool().*/

int CMEM_free (void *ptr, CMEM_AllocParams *params)

/*Register shared usage of an already-allocated buffer.*/

void * CMEM_registerAlloc (unsigned long physp)
/*Unregister use of a buffer previously registered with CMEM_registerAlloc()*/

int CMEM_unregister (void *ptr, CMEM_AllocParams *params)

/*Get the physical address of a contiguous buffer*/

unsigned long CMEM_getPhys (void *ptr)

以H264编码算法为例,算法内存分配主要用到以下5个API接口函数:

CMEM_init,CMEM_exit ,CMEM_alloc,CMEM_free,CMEM_getPhys

×