linux DMA接口知识点详解
1.两种DMA映射类型
1.1.一致性DMA映射(ConsistentDMAmappings)
主要用于映射长时间使用的区域。
CPU和DMAcontroller不需要考虑cache的影响。
这里的consistent实际上是coherent的概念,不能保证consistent,也就是说需要memorybarrier来保证memoryorder。
1.2流式DMA映射(streamingDMAmapping)
主要用于一次性DMA传输,传输完成后就会释放。
2.指定DMA设备的寻址范围
include/linux/dma-mapping.h
//用于一致性内存映射的映射范围 staticinlineintdma_set_coherent_mask(structdevice*dev,u64mask) //用于流式内存映射的映射范围 staticinlineintdma_set_mask(structdevice*dev,u64mask);
3.DMA映射接口
3.1一致性DMA接口
分配较大DMAbuffer
//devDMA控制器设备 //size要分配的DMAbuffer大小 //dma_handle返回DMAbuf的物理地址 //flag分配标志 //返回值DMAbuffer的虚拟地址 void*dma_alloc_coherent(structdevice*dev,size_tsize,dma_addr_t*dma_handle,gfp_tflag) //devDMA控制器设备 //size释放的DMAbuffer大小 //cpu_addrDMAbuf的虚拟地址 //dma_handleDMAbuf的物理地址 voiddma_free_coherent(structdevice*dev,size_tsize, void*cpu_addr,dma_addr_tdma_handle)
分配较小DMAbuffer,从dmapoll中申请。
/** *dma_pool_alloc-从dmapoll获得一块一致性内存 *@pool:产生内存块的dmapool *@mem_flags:GFP_*bitmask *@handle:返回内存块的dma地址 */ void*dma_pool_alloc(structdma_pool*pool,gfp_tmem_flags, dma_addr_t*handle) /** *dma_pool_free-将内存释放回dmapool *@pool:产生内存块的dmapool *@vaddr:内存块的虚拟地址 *@dma:内存块的物理地址 */ voiddma_pool_free(structdma_pool*pool,void*vaddr,dma_addr_tdma)
3.2流式DMA接口
//dev需要映射内存的设备 //ptr映射的buffer虚拟地址 //size映射的大小 //dir传输方向 //attr属性 //返回值dma物理地址 dma_addr_tdma_map_single_attrs(structdevice*dev,void*ptr, size_tsize, enumdma_data_directiondir, unsignedlongattrs) //dev需要映射内存的设备 //addrdma区域的物理地址 //size映射的大小 //dir传输方向 //attr属性 voiddma_unmap_single_attrs(structdevice*dev,dma_addr_taddr, size_tsize, enumdma_data_directiondir, unsignedlongattrs)
page映射
dma_addr_tdma_map_page(structdevice*dev,structpage*page, size_toffset,size_tsize, enumdma_data_directiondir) voiddma_unmap_page(structdevice*dev,dma_addr_taddr, size_tsize,enumdma_data_directiondir)
返回dma映射错误
//返回dma映射错误 intdma_mapping_error(structdevice*dev,dma_addr_tdma_addr)
映射scatterlist
intdma_map_sg_attrs(structdevice*dev,structscatterlist*sg, intnents,enumdma_data_directiondir, unsignedlongattrs) voiddma_unmap_sg_attrs(structdevice*dev,structscatterlist*sg, intnents,enumdma_data_directiondir, unsignedlongattrs) //返回map后的dma地址和长度 sg_dma_address(structscatterlist*sg) sg_dma_len(structscatterlist*sg)
sync操作
voiddma_sync_single_for_cpu(structdevice*dev,dma_addr_taddr, size_tsize, enumdma_data_directiondir) voiddma_sync_single_for_device(structdevice*dev, dma_addr_taddr,size_tsize, enumdma_data_directiondir) void dma_sync_sg_for_cpu(structdevice*dev,structscatterlist*sg, intnelems,enumdma_data_directiondir) void dma_sync_sg_for_device(structdevice*dev,structscatterlist*sg, intnelems,enumdma_data_directiondir)
以上就是本次介绍的全部相关知识点,如果大家有任何补充可以联系毛票票小编。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。