这个标题属实是有点狂了哈~
在计算机系统里面,数据是不停的流动的,一般又需要知道地址和对数据的操作方式,CPU一直做这种搬来搬去的工作有点呆,而且大多数时候都是中断型的。
DMA(Direct Memory Access,直接内存访问) 是一种允许外设和存储器之间直接进行数据传输的技术,不需要CPU的干涉,大大提高了数据传输效率。
看一个框图
下面是使用场景,基本上全部都囊括了。
外设数据采集: 将外设采集到的数据传输到内存中。
数据缓存: 将数据从一个内存区域复制到另一个内存区域。
DMA双缓冲: 使用两个缓冲区交替进行传输,提高数据处理效率。
我这里想说一下数据缓存这个事情:数据缓冲区,简单来说就是一块用于临时存储数据的内存区域。它就像一个中转站,在数据从一个地方传输到另一个地方的过程中,起到暂存、缓冲的作用。
同步不同速率的设备: 当数据产生和消费的速度不一致时,缓冲区可以起到调节的作用。比如,生产数据的设备速度较快,而处理数据的设备速度较慢,数据可以先存储在缓冲区中,等待处理设备有空闲时再取出。
提高数据传输效率: 大块数据传输比小块数据传输效率更高。通过缓冲区,可以将小块数据合并成大块数据进行传输。
解耦系统模块: 缓冲区可以将系统中的不同模块解耦,使模块之间相对独立,提高系统的可维护性。
我们日常使用的有四种类型:
循环缓冲区: 数据在缓冲区中循环写入和读取,适用于需要连续传输的数据。
双缓冲区: 使用两个缓冲区交替进行读写,提高数据处理效率。
FIFO缓冲区: 先进先出队列,数据按照先入先出的顺序进行读写。
LIFO缓冲区: 后进先出队列,数据按照后入先出的顺序进行读写。
不同的DMA外设可能有不一样的控制功能,但是大体上是差不多的。
指示数据传输的起始地址,即外设设备中数据缓冲区的地址。DMA控制器从这个地址开始读取数据。
指示数据传输的目的地址,即系统内存中的指定地址。DMA控制器将读取到的数据写入到这个地址。
指定DMA传输的方式,包括单次传输、循环传输、乒乓传输等。不同的传输模式适用于不同的应用场景。
常见传输模式:
单次传输(Single Transfer): 传输完成后,DMA控制器停止工作。
循环传输(Circular Transfer): 传输完成后,DMA控制器自动回到起始地址,继续传输,适用于需要连续传输的数据。
乒乓传输(Ping-Pong Transfer): 使用两个缓冲区交替进行传输,提高数据处理效率。
有时候需要数据对齐,这个主要是迁就硬件其实:
总线宽度: 现代处理器通常采用32位或64位的数据总线,这意味着一次内存访问可以传输32位或64位的数据。如果地址不对齐,DMA控制器就需要进行多次访问才能完成一次数据传输,降低了效率。
可以减少内存访问次数: 地址对齐可以减少内存访问的次数,提高数据传输的吞吐量。然后充分利用总线带宽: 地址对齐可以最大程度地利用总线的带宽,提高数据传输速度。
部分字传输(避免数据损坏): 如果地址不对齐,可能导致DMA控制器在一次传输中只传输部分数据,而将剩余部分数据覆盖到下一个内存单元,从而导致数据损坏。
举个栗子:
假设一个系统的数据总线宽度为32位,即一次可以传输4个字节。如果一个数据的起始地址是0x1003,那么DMA控制器在访问这个数据时,就需要两次访问:第一次访问0x1000,第二次访问0x1004。这样一来,就浪费了一次内存访问,降低了传输效率。
总结一下使用的步骤:
配置DMA控制器: 设置源地址、目标地址、传输长度、传输模式等参数。
启动DMA传输: 发送一个启动命令给DMA控制器,DMA控制器就开始按照配置的参数进行数据传输。
DMA传输完成: 当传输的数据量达到设定的长度时,DMA控制器会产生一个中断信号,通知CPU传输完成。