DMA直接内存存取原理

  DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。

  要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程序查询或中断方式。利用中断进行数据传送,可以大大提高CPU的利用率

  但是采用中断传送有它的缺点,对于一个高速I/O设备,以及批量交换数据的情况,只能采用DMA方式,才能解决效率和速度问题。DMA在外设与内存间直接进行数据交换,而不通过CPU,这样数据传送的速度就取决于存储器和外设的工作速度。

  通常系统的总线是由CPU管理的。在DMA方式时,就希望CPU把这些总线让出来,即CPU连到这些总线上的线处于第三态--高阻状态,而由DMA控制器接管,控制传送的字节数,判断DMA是否结束,以及发出DMA结束信号。DMA控制器必须有以下功能:

  1. 能向CPU发出系统保持(HOLD)信号,提出总线接管请求;

  2. 当CPU发出允许接管信号后,负责对总线的控制,进入DMA方式;

  3. 能对存储器寻址及能修改地址指针,实现对内存的读写操作;

  4. 能决定本次DMA传送的字节数,判断DMA传送是否结束

  5. 发出DMA结束信号,使CPU恢复正常工作状态。

如图是DMA控制器硬件结构示意图。

  DMA的可能引脚说明:

  数据总线:用于传送数据。

  地址总线:用于选择存储器地址。

  数据传送信号:MEMR为存储器读操作信号,MEMW为存储器写操作信号,IOR为外设读操作信号,IOW为外设写操作信号。

  DRQ:DMA请求信号。是外设向DMA控制器提出要求DMA操作的申请信号。

  DACK:DMA响应信号。是DMA控制器向提出DMA请求的外设表示已收到请求和正进行处理的信号。

  HOLD:总线请求信号。是DMA控制器向CPU要求让出总线的请求信号。

  HLDA:总线响应信号,是CPU向DMA控制器表示允许总线请求的应答信号。

5.2  DMA工作方式   

  随着大规模集成电路技术的发展,DMA传送已不局限于存储器与外设间的信息交换,而可以扩展为在存储器的两个区域之间,或两种高速的外设之间进行DMA传送,如图所示。

  DMAC是控制存储器和外部设备之间直接高速地传送数据的硬件电路,它应能取代CPU,用硬件完成数据传送的各项功能。

  各种DMAC一般都有两种基本的DMA传送方式:

1. 单字节方式:每次DMA请求只传送一个字节数据,每传送完一个字节,都撤除DMA请求信号,释放总线。

2. 多字节方式:每次DMA请求连续传送一个数据块,待规定长度的数据块传送完以后,才撤除DMA请求,释放总线。

  在DMA传送中,为了使源和目的间的数据传送取得同步,不同的DMAC在操作时都受到外设的请求信号或准备就绪信号--Ready信号的限制。

5.3 DMA控制器8237

Intel 8237/8237-2是一种高功能的可编程的DMA控制器,采用5MHz的8237-2传送,速度可达到1.6M字节/秒。

8237的主要功能

8237的DMA传送有以下四种方式:

1. 单字节传送方式

2. 数据块传送方式

3. 请求传送方式

4. 级连方式

有一个结束处理的输入信号EOP,允许外界用此输入端结束DMA传送或重新初始化。

8237可以级连,任意扩展通道数。

 
 

8237的系统结构图如图所示。

图中的通道部分只画出了一个通道的情况(其实每个通道都有一个一个基地址寄存器(16位)、基字节数计数器(16位)、现行地址寄存器(16位)和现行字节计数器(16位),每一个通道都有一个6位的模式寄存器以控制不同的工作模式)。

8237的内部寄存器类型和数量如表所示

8237的结构中包含了三个基本的控制逻辑块:

1. 时序控制逻辑块;(根据编程规定的DMAC的工作模式,产生包括DMA请求、DMA传送以及DMA结束所需要的内部时序和外部信号)
2. 程序命令控制块;(对在DMA请求服务之前,CPU编程时给定的命令字和模式控制字进行译码,以确定DMA服务类型)
3. 优先权编码逻辑。(对同时有请求的通道进行优先编码,确定哪个通道的优先权最高。在8237中通道的优先权可能是固定的,也可以是旋转的)

另外,缓冲器、8237的数据引线、地址引线都有三态缓冲器,因而可以接管也可以释放总线。

 
 

5.3
 DMA控制器8237

8237在设计时规定它有两种主要的工作周期,即空闲周期和有效周期,每一个周期又是由若干个时钟周期所组成的。

1. 空闲周期(IDLE CYCLE)

当8237的任一通道都无请求时,就进入空闲周期,在空闲周期8237始终执行SI状态,在每一个时钟周期都采样通道的请求输入线DREQ。只要无请求就始终停留在SI状态。

在SI状态可由CPU对8237编程,或从8237读取状态(8237在SI状态也始终采样选片信号#CS,只要#CS信号变为有效,则为CPU要对8237进行读/写操作。当8237采样到#CS为低(有效)而HRQ也为低(无效),则进入程序状态CPU就可以写入8237的内部寄存器,实现对8237的编程或改变工作状态。在这种情况下,由控制信号#IOR和#IOW,地址信号A3-A0来选择8237的内部的不同寄存器)。 由于8237内部的地址寄存器和字节数计数器都是16位的,而数据线是8位的,所以,在8237的内部有一个触发器,称为高/低触发器,由它来控制写入 16位寄存器的高8位还是低8位。8237还具有一些软件命令,这些命令是通过对地址(A3-A0)和#IOW,#CS信号的译码决定的,不使用数据总 线。

2. 有效周期(Active Cycle)

当8237在SI状态采样到外设有请求时,就脱离SI而进入S0状态。当接收到HLDA,就使8237进入工作状态,开始DMA传送。工作状态由S1、S2、S3、S4组成,以完成数据传达,若外设的数据传送速度较慢,不能在S4之前完成,则可由Ready线在S2或S3与S4之间插入SW状态。

在存储器与存储器之间的传达,需要完成从存储器读和存储器写的操作,所以每一次传达需要8个时钟周期,在前四个周期S11、S12、S13、S14完成从存储器读,另外四个周期S21、S22、S23、S24完成存储器写。

 
 

5.3
 DMA控制器8237

8237在DMA传送时有四种工作方式。

1. 单字节传送方式

这种方式一次只传送一个字节。数据传送后字节计数器减量,地址要相应修改(增量或减量取决于编程)。HRO变为无效,释放系统总线。若传送使字节数减为0,TC发生或者终结DMA传送,或重新初始化。

2.多字节传送方式

这种传送方式下,8237由DREQ启动后就连续地传送数据,直至字节数计数器减到零产生TC(Terminal Count),或者由外部输入有效的EOP信号来终结DMA传送。

3.请求传送方式

在这种工作方式下,8237可以进行连续的数据传送。当出现以下三种情况之一时停止传送。

1) 字节数计数器减到0,发生TC;

2) 由外界送来一个有效的EOP信号;

3) 外界的DREQ信号变为无效

当由于第三种情况使传送停下来时,8237释放总线,CPU可以继续操作。而8237的地址和字节数的中间值,可以保持在相应通道的现行地址和字节数寄存器中。只要外设准备好了要传送的新的数据,由DREQ再次有效就可以使传送继续下去。

4. 级连方式

  这种方式用于通过级连以扩展通道的情况。第二级的HRQ和HLDA信号连到第一级的DREQ和DACK上,如图所示。

  第二级各个芯片的有限权等级与所连的通道相对应。在这种工作情况下,第一级只起优先权网络的作用,除了由某一个二级的请求向CPU输出HRQ信号外,并不输出任何其他信号。实际的操作是由第二级的芯片完成。若有需要还可由第二级扩展到第三级等等。

 8237共有9类寄存器,分别是现行地址寄存器、现行字节数寄存器、基地址和基字节数寄存器、命令寄存器模式寄存器、请求寄存器、屏蔽寄存器、状态寄存器、临时寄存器。

  1. 现行地址寄存器

   每一个通道有一个16位的现行地址寄存器。在这个寄存器中保存着用于DMA传送的地址值,在每次传送后,这个寄存器的值自动增量或减量。这个寄存器的值 可由CPU写入或读出(分两次连续操作)。若编程为自动初始化,则在每次EOP后,将其初始值(即保持在基地址寄存器中的值)转入寄存器。

  2. 现行字节数寄存器

  每个通道有一个16位的现行字节数寄存器。它保持着要传送的字节数,在每次传送后此寄存器减量。当这个寄存器的值减为零时,TC将产生。这个寄存器的值在编程状态可由CPU读出和写入。在自动初始化情况下当EOP产生时,它的值可初始化到其始状态。

  3. 基地址和基字节数寄存器

  每个通道有一对16位的基地址和基字节数寄存器。它们存放着与现行寄存器相联系的初始值。在自动初始化情况下。这两个寄存器中的值,用来恢复相应的现行寄存器中的初始值。在编程状态,基寄存器与它们相应的现行寄存器是同时由CPU写入的。这些寄存器的内容不能读出。

4. 命令寄存器

  这是一个8位的寄存器,用以控制8237的工作命令字的格式如图所示。

  D0位用来规定是否工作在存储器到存储器传送方式。

  D4位用来选择是固定优先权还是优先旋转。8237有两种优先权方式可供选择,一种是固定优先权,在这种方式下通道的优先权是固定的,通道0的优先权最高,通道3的优先权最低;另一种方式是优先权旋转,在这种方式下刚服务过的通道的优先权变为最低,其他通道的优先权也作相应的旋转,如下图所示。

  命令寄存器可由CPU写入进行编程,复位信号使其清零。

5. 模式寄存器

每个通道有一对8位的模式寄存器以规定通道的工作模式,如图所示。

在编程时用最低两位来选择写入哪个通道的模式寄存器。

最高两位(D7、D6)规定了四种工作模式中的某一种,D3、D2两位规定是DM读还是DMA写或是校验操作。

D5位用于规定地址是增量修改还是减量修改。

D4位规定是否允许自动初始化。若工作在自动初始化方式,则每当产生EOP信号时(不论是由内部的TC产生或是由外界产生)都是基地址寄存器和基字节数寄 存器的内容,使相应的现行寄存器恢复初始值。而现行寄存器和基寄存器的内容,是由CPU编程时同时写入的,但在DMA传送过程中,现行寄存器的内容是不断 修改的,而基寄存器的内容则维持不变(除非重新编程)。在自动初始化以后通道就做好了进行另一次DMA传送的准备。

6. 请求寄存器

8237的每个通道有一条硬件的DREQ请求线,当工作在数据块传送方式时,也可以由软件发出DREQ请求。所以,在8237中有一种请求寄存器,如图5-10所示。

每个通道的软件请求可以分别设置。软件请求是非屏蔽的,它们的优先权同样受优先权逻辑的控制。

软件请求位由TC或外部的EOP复位。Reset信号使整个寄存器清除。

只有在数据块传送方式,才允许使用软件请求,若用于储存器到储存器传送,则0通道必须用软件请求,以启动传送过程。

7. 屏蔽寄存器

  每个通道外设通过DREQ发出的请求,可以单独地屏蔽或允许,所以在8237中有一个屏蔽寄存器,如图所示。

  在Reset信号作用后,四个通道全置于屏蔽状态,所以,必须在编程时,根据需要复位屏蔽位。当某一个通道进行DMA传送后,产生EOP信号,如果不是工作在自动初始化方式,则这一通道的屏蔽位置位,必须再次编程为允许,才能进行下一次的DMA传送。

  也可以用如图(b)所示的格式,在一个命令字中对4个通道的屏蔽情况进行编程。

8. 状态寄存器

  8237中有一个可由CPU读取的状态寄存器,如图所示。

  状态寄存器中的低4位,反映了在读命令这个瞬间,每个通道的字节数是否已减到零。高4位反映每个通道的请求情况。

9. 临时寄存器

  在存储器到存储器的传送方式下,临时寄存器保存从源单元读出的数据,又由它写入至目的单元。在传送完成时,它保留传送的最后一个字节,此字节可由CPU读出。Ready信号使其复位。

  如上所术,8237内部存寄存器可以分成两大类,一类是通道寄存器,即每个通道都有的现行地址寄存器,现行字节数寄存器和基地址及基字节数寄存器;另一类是控制和状态寄存器。这些寄存器是由最低4位地址A3-A0以及读写命令来区分的。

  通道寄存器的寻址格式

  控制和状态寄存器的寻址如下表所示。


寄存器

操作

信号
#CS #IOR #IOW A3 A2 A1 A0

命令


0   1  0  1 0 0 0

模式


0   1  0  1 0 1 1

请求


0   1  0  1 0 0 1

屏蔽

置位/复位

0   1  0  1 0 1 0

屏蔽


0   1  0  1 1 1 1

临时


0   0  1  1 1 0 1

状态


0   0  1  1 0 0 0

1. 软件命令

  8237在编程状态还有两种软件命令,软件命令不需要通过数据总线写入控制字,而由8237直接对地址和控制信号进行译码。命令的格式如下表所示。

  1) 清除高/低触发器

  2) 主清除命令


信号
A3  A2  A1 A0 #IOR #IOW

操作

1  0  0  0  0   1

读状态寄存器

1  0  0  0  1   0

写命令寄存器

1  0  0  1  0   1

非法

1  0  0  1  1   0

写请求寄存器

1  0  1  0  0   1

非法

1  0  1  0  1   0

写单屏蔽寄存器位

1  0  1  1  0   1

非法

1  0  1  1  1   0

写模式寄存器

1  1  0  0  0   1

非法

1  1  0  0  1   0

清高/低触发器命令

1  1  0  1  0   1

读临时寄存器

1  1  0  1  1   0

主清除命令

1  1  1  0  0   1

非法

1  1  1  0  1   0

非法

1  1  1  1  0   1

非法

1  1  1  1  1   0

写所有屏蔽位

2. 8237的编程步骤

  1) 输出主清除命令

  2) 写入基与现行地址寄存器

  3) 写入基与现行字节数寄存器

  4) 写入模式寄存器

  5) 写入屏蔽寄存器

  6) 写入命令寄存器

  7) 写入请求寄存器。若有软件请求,就写入指定通道,可以开始DMA传送的过程。若无软件请求,则在完成了(1)--(6)的请求后,由通道的DREQ启动DMA传送过程。

3. 编程举例

  若要利用通道0,由外设(磁盘)输入32K字节的一个数据块,传送至内存8000H开始的区域(增量传送),采用块连续传送的方式,传送完不自动初始化,外设的DREQ和DACK都为高电平有效。

  要编程首先要确定端口地址。地址的低4位用以区分8237的内部寄存器,高4位地址A7--A4经译码后,连至选片端#CS,假定选中时高4位为5。

  初始化程序如下:

OUT 5DH, AL ;输出主清除命令
MOV AL, 00H
OUT 50H, AL ;输出基和现行地址的低8位
MOV AL, 80H
OUT 50H, AL ;输出基和现行地址的高8位
MOV AL, 00H
OUT 51H, AL
MOV AL, 80H
OUT 51H, AL ;给基和现行字节数赋值
MOV AL, 84H
OUT 5BH, AL ;输出模式字
MOV AL, 00H
OUT 5AH, AL ;输出屏蔽字
MOV AL, 0A0H
OUT 58H, AL ;输出命令字

分享

时间: 2024-10-06 15:09:05

DMA直接内存存取原理的相关文章

DMA (Direct Memory Access,直接内存存取)

对DMA内存的使用有3种方式: 1,一致DMA映射 通过dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)来直接得到一块用于dma的内存,同时得到这一段内存的虚拟地址和总线地址,分别用于CPU和device的访问. 通过这种方式得到的dma内存,开发者不用担心cache的问题,但是要注意在执行DMA操作之前flush write buffer. 2.DMA池 DMA池是一个

转 Linux内存管理原理

Linux内存管理原理 在用户态,内核态逻辑地址专指下文说的线性偏移前的地址Linux内核虚拟3.伙伴算法和slab分配器 16个页面RAM因为最大连续内存大小为16个页面 页面最多16个页面,所以16/2order(0)bimap有8个bit位两个页框page1 与page2组成与两个页框page3 与page4组成,这两个块之间有一个bit位 order(1)bimap有4个bit位order(2)bimap有4个bit位的2个页面分配过程 当我们需要order(1)的空闲页面块时,orde

[转]JVM 堆内存设置原理

堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大. Heap = { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年轻代(Young Generation).年老代和年轻代的划分对垃圾收集影响比较大. 年轻代 所有新生

bootloader功能介绍/时钟初始化设置/串口工作原理/内存工作原理/NandFlash工作原理

bootloader功能介绍 初始化开发板上主要硬件(时钟,内存,硬盘), 把操作系统从硬盘拷贝到内存,然后让cpu跳转到内存中执行操作系统. boot阶段 1.关闭影响CPU正常执行的外设 -关闭看门狗(watch dog)   WTCON 0xE2700000 -关闭中断 CPSR I和F位设置为1,关闭,不响应任何中断. 2.初始化时钟 -倍频到1Ghz,为外设分频 *串口驱动 3.初始化内存控制器,DDRAM -验证内存,往里面写一个值,然后再读出来 4.初始化硬盘,nand Flash

JVM 堆内存设置原理(转)

堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大. Heap = { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年轻代(Young Generation).年老代和年轻代的划分对垃圾收集影响比较大. 年轻代 所有新生

【转】JVM 堆内存设置原理

堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大. Heap = { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年轻代(Young Generation).年老代和年轻代的划分对垃圾收集影响比较大. 年轻代 所有新生

内存分配原理 -进程分配内存的两种方式,分别有系统调用完成brk() 和mmap()(不设计共享内存)

如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误.           这两个数值表示一个进程自启动以来所发生的缺页中断的次数. 发成缺页中断后,执行了那些操作? 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查找/分配一个物理页 3.填充物理页内容(读取磁盘,或者直接置0

Gexmul虚拟机内存空间原理简述

Gxemul将内存空间分为两部分管理,一部分是物理内存,地址分配到0x00000000,另一部分是device的地址,注册device的时候由device自己指定空间 1 创建物理内存 memory.cc memory_new {     初始化物理内存参数     mem->physical_max = physical_max;     mem->dev_dyntrans_alignment = 4095;     创建物理内存     mem->pagetable = (unsig

HashMap原理(二) 扩容机制及存取原理

我们在上一个章节<HashMap原理(一) 概念和底层架构>中讲解了HashMap的存储数据结构以及常用的概念及变量,包括capacity容量,threshold变量和loadFactor变量等.本章主要讲解HashMap的扩容机制及存取原理. 先回顾一下基本概念: table变量:HashMap的底层数据结构,是Node类的实体数组,用于保存key-value对: capacity:并不是一个成员变量,但却是一个必须要知道的概念,表示容量: size变量:表示已存储的HashMap的key-