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. 【Spark】Spark Streaming 动态更新filter关注的内容

    Spark Streaming 动态更新filter关注的内容 spark streaming new thread on driver_百度搜索 (1 封私信)Spark Streaming 动态更 ...

  2. 如何给USB移动硬盘格式化分区

    硬盘盒装好后,插在电脑USB接口上,电脑正常识别到移动硬盘后,但因为全新硬盘没有分区,在"我的电脑"里是看不到盘符的.下面以40G移动硬盘分区讲一下硬盘如何分区.1.操作系统最好是 ...

  3. esUtil.h中的m变量报错

    引用了OpenGL ES自带的esUtil.h, 编译的时候报错:     typedef struct     {         GLfloat m[4][4];     } ESMatrix; ...

  4. angular.element()的用法

    1.引用jQuery的前提下,和$用法基本相同:angular.element('#').html() 例如: angular.element('#test').html() angular.elem ...

  5. 微软BI 之SSRS 系列 - 如何实现报表标签的本地化 - 中文和英文的互换

    SSRS 中并没有直接提供本地化的配置方式,因此在 SSRS 中实现本地化,比如有英文标题还有可选的中文标题,就需要通过其它的方式来解决. 比如默认是这样的英文标题 - 但是本地中方用户可能比较喜欢看 ...

  6. 转:nginx模块开发——handler(一)

    handler模块简介 相信大家在看了前一章的模块概述以后,都对nginx的模块有了一个基本的认识.基本上作为第三方开发者最可能开发的就是三种类型的模块,即handler,filter和load-ba ...

  7. ng-class ng-style

    https://docs.angularjs.org/api/ng/directive/ngClass 翻译 表达式生成一个空格饭分隔的class字符串 一个对象,它的每一个key在其值为true的时 ...

  8. Spark GraphX实例(1)

    Spark GraphX是一个分布式的图处理框架.社交网络中,用户与用户之间会存在错综复杂的联系,如微信.QQ.微博的用户之间的好友.关注等关系,构成了一张巨大的图,单机无法处理,只能使用分布式图处理 ...

  9. 转 VB ListView控件各种操作详解

    Private Sub Form_Load() ListView1.ListItems.Clear '清空列表 ListView1.ColumnHeaders.Clear '清空列表头 ListVie ...

  10. tcp线程聊天

    .ServerThread package serverclient; import java.io.BufferedReader; import java.io.InputStreamReader; ...