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 ;输出命令字

分享

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

  1. DMA 内存存取原理

    DMA直接内存存取原理 DMADMA直接内存存取原理是指外部设备不通过CPU而直接与系统内存交换数据的接口技术. 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程 ...

  2. DMA直接内存存取20160525

    说一下工作中接触到的DMA1)在实现DMA传输时,是由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题.即DMA传输前,CPU要把 总线控制权交给DMA控制器,而在结束DMA传输后,DMA ...

  3. DMA(直接存储器存取)

    DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统 ...

  4. 转 Linux内存管理原理

    Linux内存管理原理 在用户态,内核态逻辑地址专指下文说的线性偏移前的地址Linux内核虚拟3.伙伴算法和slab分配器 16个页面RAM因为最大连续内存大小为16个页面 页面最多16个页面,所以1 ...

  5. 深入Java核心 Java内存分配原理精讲

    深入Java核心 Java内存分配原理精讲 栈.堆.常量池虽同属Java内存分配时操作的区域,但其适用范围和功用却大不相同.本文将深入Java核心,详细讲解Java内存分配方面的知识. Java内存分 ...

  6. JVM内存分配原理

    堆栈常量池等内存分配原理详解 存储的方式: 寄存器 栈(stack) 堆(heap) 静态域 常量池 非RAM存储 JAVA寄存器 最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.  ...

  7. 【转帖】linux内存管理原理深入理解段式页式

    linux内存管理原理深入理解段式页式 https://blog.csdn.net/h674174380/article/details/75453750 其实一直没弄明白 linux 到底是 段页式 ...

  8. 【转】JVM 堆内存设置原理

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  9. js闭包和ie内存泄露原理

    也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ...

随机推荐

  1. 【中文分词系列】 4. 基于双向LSTM的seq2seq字标注

    http://spaces.ac.cn/archives/3924/ 关于字标注法 上一篇文章谈到了分词的字标注法.要注意字标注法是很有潜力的,要不然它也不会在公开测试中取得最优的成绩了.在我看来,字 ...

  2. Web安全学习规划

    一名合格的Web安全工程师是要具备很多的知识点,不但要对网站架构熟悉,通讯协议,测试流程与测试工具使用,漏洞利用脚本编写,还有需要经验的积累等. 互联网进入下半场,竞争越发的激烈,能与人工智能比肩的热 ...

  3. [转]nodejs深入学(7)理解Buffer

    原文: https://www.jianshu.com/p/e3f14cdf78f1 --------------------------------------------------------- ...

  4. express next function

    nodejs 里面的next()这个函数调用的作用是什么呢? var express = require('express'); var app = express(); var myLogger = ...

  5. Spark:JavaRDD 转化为 Dataset<Row>的两种方案

    JavaRDD 转化为 Dataset<Row>方案一: 实体类作为schema定义规范,使用反射,实现JavaRDD转化为Dataset<Row> Student.java实 ...

  6. Java-JUC(六):创建线程的4种方式

    Java创建线程的4种方式: Java使用Thread类代表线程,所有线程对象都必须是Thread类或者其子类的实例.Java可以用以下4种方式来创建线程: 1)继承Thread类创建线程: 2)实现 ...

  7. 使用 GNU Libtool 创建库

    这篇文档向大家介绍 GNU Libtool 的用途及基本使用方法,同时描述如何结合 GNU Autoconf 和 Automake 来使用 Libtool. 3 评论: 吴 小虎, 程序员, 天用唯勤 ...

  8. SharePoint CAML Query小结

    CAML的结构. <View Type="HTML" Name="Summary"> <ViewBody ExpandXML="TR ...

  9. Andriod NDK编译的时候无法使用math.h的函数。

    编译NDK项目的时候,当用到sinf的时候,编译报错: 选中sinf函数,右键Go to declaration, 发现math.h的文件路径是: c:\ProgramData\Microsoft\A ...

  10. 准备Mahout所用的向量ApplesToVectors

    <strong><span style="font-size:18px;">/*** * @author YangXin * @info 准备Mahout所 ...