Android PMEM驱动研究(2)——在应用程序中使用PMEM
放假结束,继续研究PMEM。
====================================================================================== Android PMEM主要有两个作用(来自android mail list): 1. GPU or VPU buffers shared with CPU core 2. Android service heap. 其中1是不能cache的,2可以cache,平台设备注册中cached = X即控制是否可以被cache。
======================================================================================= 简单看PMEM驱动,主要有以下内容:
pmem_init()驱动加载 | pmem_probe()platform加载 | pmem_setup() 初始化 pmem[id] 启动时输出信息,格式为[名称][是否可以被cache] eg:pmem_adsp: 0 init misc_register() 初始化所有的bitmap 通过ioremap获取所有pmem[id].vbase
pmem_map() 提供mmap接口
pmem_ioctl() #define PMEM_GET_PHYS 获取物理地址 #define PMEM_MAP pmem_remap() #define PMEM_GET_SIZE pmem_getsize() #define PMEM_UNMAP pmem_remap(®ion, file, PMEM_UNMAP); #define PMEM_ALLOCATE 分配pmem空间,len是参数,如果文件已被分配则失败 #define PMEM_CONNECT 将一个pmem file与其他相连接 #define PMEM_GET_TOTAL_SIZE 返回pmem region的全部尺寸
这而也有篇文章值得参考http://linux.chinaunix.net/techdoc/net/2009/04/21/1108452.shtml =======================================================================================
应用程序中使用PMEM,有待深入研究
#include "android_pmem.h"
int pmem_fd; void *pmem_base; unsigned int size; struct pmem_region region;
pmem_fd = open("/dev/pmem_adsp", O_RDWR, 0);//打开设备,为了操作硬件引擎,要noncache的
if (pmem_fd >= 0) { if (ioctl(pmem_fd, PMEM_GET_TOTAL_SIZE, ®ion) < 0) //获取全部空间 { printf("PMEM_GET_TOTAL_SIZE failed\n"); size = 4<<20; // 4 MiB } else { size = region.len; } pmem_base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);//mmap操作 if (pmem_base == MAP_FAILED) { pmem_base = 0; close(pmem_fd); pmem_fd = -1; printf("mmap pmem error!\n"); }
if ( ioctl(pmem_fd, PMEM_GET_PHYS, ®ion) < 0)//获取物理地址 { printf("PMEM_GET_PHYS failed\n"); }
}
其实第一个ioctl无用,只是为了获取长度。 经过以上操作,region.offset为物理地址,其空间和虚拟地址pmem_base相对应。 在程序中填充pmem_base数据,配置VPU、GPU时使用region.offset该物理地址。
======================================================================================= 最后来看看驱动调用流程
1)open操作 [drivers/misc/pmem.c:pmem_open:336] current 55 file c7355c80(1)
2)mmap 会自动调用allocate [drivers/misc/pmem.c:pmem_allocate:398] order 0 [drivers/misc/pmem.c:pmem_map_pfn_range:511] map offset 0 len 10000
3)ioctl PMEM_GET_PHYS 感觉物理地址是根据pid来确定的 [drivers/misc/pmem.c:pmem_ioctl:1081] get_phys pmem: request for physical address of pmem region from process 55.
4)munmap [drivers/misc/pmem.c:pmem_vma_close:555] current 55 ppid 47 file c7355c80 count 2
不知道如果有两个设备操作该驱动会怎么样? |