直接内存访问笔记
来源:互联网 发布:rfcn网络 编辑:程序博客网 时间:2024/06/14 15:26
1.两种引发数据传输的方式
1.1 软件对数据的请求
当进程调用read,驱动程序函数分配一个DMA缓冲区,让硬件将数据传输到这个缓冲区中,进程处于睡眠状态;硬件将数据写入到DMA缓冲区中,当写入完毕,产生一个中断;中断处理程序获得输入的数据,应答中断,并唤醒进程,该进程现在可以读取数据。
1.2 硬件异步的将数据传输给系统
硬件产生中断,宣告新数据的到来;中断处理程序分配一个缓冲区,并且告诉硬件向哪里传输数据;外围设备将数据写入缓冲区,完成后产生另外一个中断;处理程序分发新数据,唤醒任何相关进程,然后执行清理工作。
2.分配DMA缓冲区
2.1处理复杂的硬件
如果设备不能在32位地址上执行DMA,则应该调用下面的函数:
int dma_set_mask(struct device *dev, u64 mask);
mask显示与设备寻址能力对应的位,比如设备受限于24位寻址,则mask应该是0xffffff。如果使用指定的mask时dma能够正常工作则返回非0值;如果返回0,则对该设备部能使用DMA。因此一个受限于24位DMA操作的驱动程序初始化代码有如下形式:
if (dma_set_mask(dev, 0xffffff))
card->use_dma = 1;
else {
card->use_dma = 1;
printk(KERN_WARN, "mydev:DMA not supported\n");
}
根据DMA缓冲区期望保留的时间长短,PCI代码区分两种类型的DMA映射:
一致性DMA映射
存在于驱动程序生命周期中,一致性映射的缓冲区必须可以同时被CPU和外围设备访问。
流式DMA映射
单独的操作建立流式映射。内核开发者建议尽量使用流式映射。第一个原因是在支持映射寄存器的系统中,每个DMA映射使用总线上的一个或者多个映射寄存器,一致性映射长时间占用这些寄存器。第二个原因是一些硬件中,流式映射可以被优化,但该方法对一致性映射无效。
建立一致性DMA映射:
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag);
建立流式DMA映射:
当只有一个缓冲区要被传输的时候,使用dma_map_single函数映射:
dma_addr_t dma_map_single(struct device *dev, void *buffer, size_t size, enum dma_data_direction direction);
返回总线地址,当传输完毕之后使用dma_unmap_single删除映射。
- 直接内存访问笔记
- DMA直接内存访问
- 直接内存访问(DMA)
- 直接内存访问指针
- 直接内存访问(DMA)
- 直接内存访问--DMA
- 直接内存访问(DMA)
- 直接内存访问(DMA)
- 直接内存访问(DMA)
- 直接内存访问DMA
- 直接访问内存[显存]地址
- 直接内存访问(DMA)【转】
- Wince直接访问物理内存
- DMA(直接内存访问)
- 内存访问——直接内存访问(DMA)
- bug list---直接访问string内存
- Java直接内存访问的技巧
- 直接内存访问(DMA)初探
- 为什么老实这样
- C++库
- JSon SuperObject 研究2:数据集与JSON对象互转
- LeetCode Longest Palindromic Substring
- Apache服务器
- 直接内存访问笔记
- nodejs提取网页内容
- 自定义链表
- 5555555555555
- 数据和操作典型异常场景
- poj 3670 Eating Together dp
- ubuntu adt eclipse error = 2
- 数据和操作典型异常场景 2
- 神神秘秘上电股份