概念:
A,带有buffer缓存的设备硬件描述:
1,fifo
2,dma
1,fifo可以使用任何存储空间,包括外设的一些寄存器组,只要构成一个cpu指令无法完成的读写操作(原子操作)都可以构成buffer。
2,dma是设备,不是存储空间。dma的作用是操作和管理fifo的行为。
DMA介绍:
Dma 设备受到参数的影响,表现为: 数据搬移的原始地址,目的地址,以及搬移数据大小。搬移的效率是否占有总线的效率是由硬件设计而定。不由软件控制。
Fifo是一块任意位置的存储区域。或者被cpu占有,或者被dma占有。Cpu和dma两者同时存在通过总线访问fifo的权利(auth),这样就会产生竞争现象。
这种微观的竞争延时等待,是由硬件设计考虑。在芯片内部逻辑生成之前会有匹配度测试(最常规的事列:高性能的显卡配置在普通的主板上,未必可以发挥出最好的性能)。
系统设计:
外设与cpu之间的交互可以有很多种类型:中断,dma,fifo计数等等。只要可以同步双方的数据有效都可以称之为同步机制。
典型的中断同步:写中断,读中断,中断写,中端读。(CPU侧)
写中断:在中断中对外设写。(没有参考)
中断写:通过中断写入外设。(dma)
读中断:在中断中读取外设。(dma)
中断读:通过中断读取外设。(网络设备,键盘等)
DMA的功能分析:
DMA是一个总线上的设备。具有自己的逻辑。通常对于驱动开发来说只要进行适当配置。就可以自己运作。配合中断一起完成数据搬移和交互的过程。DMA通常会自带内部fifo。对这个fifo进行管理。当fifo满或者空时,会触发中断。告知cpu可以往里面写数据或告知cpu将下一组数据慢点写入。
通常的情况下DMA中断只是给出数据搬移的结果。告知cpu上一组数据已近搬移完毕,并且可以进行下一组数据的处理。这样,cpu就可以知道外设是否是出于忙碌状态。现在的DMA有编程(指令)接口。给DMAController正确的指令:一个死循环。在这个循环中DMA自己完成已经由软件设置的逻辑进行数据搬移和数据有效性检查。在不同的状态下给出中断告知CPU目前处理的过程。
DMA是一个设备,当DMA拿到总线的控制权进行数据搬移的时候CPU是处于无法访问总线的状态,这种状态是互斥的。一定降低了CPU使用总线的效率。因此很多外设自带fifo。这些fifo有外部设备自行进行管理。当DMA操作的时候CPU不能对某一个外设的fifo操作,颗粒化了总线的等待时间,而不是一视同仁长时间等待。同时在DMA设计的时候也会考虑到效率的问题,应尽可能的快,从而缩短总线的控制权。
以上的描述可以配合其它的外设中断对数据有效进行检查。
具体分析:
以soc devkit为例:hps写入fifo后,fpga感知fifo中有数据。当数据达到阈值后,获得总线的控制权,产生视屏贞搬移。在搬移数据结束后产生特定中断,用于告知cpu数据已近搬移完毕。Cpu获得这个中断后知道数据已经处理完毕,可以对贞缓存进行下一步操作。
操作系统会使用软件同步机制:Complete。在中断处理程序和内核驱动中保持同步。中断处理中complete置位。退出中断后,在驱动中等待这个表示位。如果置位,继续运行更新视屏缓存,否则切换其它线程。
对于数据量不大的情况下,在很短的时间内把数据处理完成的应用场景中,如中断读取gpio状态等。可以马上返回,不需要更多的机制保证。
就系统而言,cpu和外设的状态交互越密切,同步机制越是得到保证。但是频繁中断会影响cpu的效率问题。当cpu频繁响应外设的中断请求时,用户的使用感受会降低。常常表现为鼠标键盘延时等。因此有了DMA。DMA的逻辑简单,功能单一。在不大范围影响总线的情况下进行外设交互,达到了,减轻cpu负担的作用。
试想,如果任何事情,数据的有效性,缓存的满空,数据的搬移等功能都是由cpu自己来完成,那么就不需要外设模块。这些模块包括DMA。在soc 的应用场景中。Vip就是一个用fpga来实现dma的功能。以上就是cpu和外设数据交互的基本框架。在这个框架下,可以进行修改和自己实现逻辑功能,但是跳出这个框架,一定要自己实现。功能当然可以,但是效率未必会高。
以soc设计为例:
(1)Fpga 在数据进行搬移之后给出中断告知hps上一贞数据处理完毕。可以进行下一组数据处理。数据的有效性检查(fifo满或者空)之后,给出状态中断。
(2)Hps在中断处理过程中设置complete的变量,在这个变量得到改变后(即上一贞数据处理完成后)。进行更新显示缓存的操作。如果这个变量未更新,那么表示这个区域还不能更新,线程或用户进程进行主动切换。让其它更需要运行的程序接管hps,完成其它的工作。
以上的分析并不止局限于soc的开发。其分析的原理可以参考其它任何一款开发板。DM368,三星2440等。
分析中难免有不足之处。欢迎批评指正。
陆斌