① DMA方式的工作过程
实现DMA传送的基本操作如下:
1、外设可通过DMA控制器向CPU发出DMA请求;
2、CPU响应DMA请求,系统转变为DMA工作方式,并把总线控制权交给DMA控制器;
3、由DMA控制器发送存储器地址,并决定传送数据块的长度;
4、执行DMA传送;
5、DMA操作结束,并把总线控制权交还CPU。
(1)dma传输数据已完毕怎么查扩展阅读
DMA方式下,为了控制外设和主存直接交换数据,需要有专门的数据传送控制电路,通常把这样的控制逻辑称为DMA控制器。整个过程分以下三个阶段:
(1)DMA控制器初始化
首先,对DMA控制器和设备接口中的参数寄存器进行初始化,以设定主存首地址、传送数据个数、传送方向(读出/写入)、设备地址(如磁头号、磁道号、起始扇区号)等,这些初始化工作由CPU执行指令完成。初始化工作的最后是向外设接口发送启动读或写的命令。
(2)DMA传送
外设接口接受到CPU送来的启动命令后,就开始控制设备进行读或写操作,当外设准备好数据以后,外设接口就会向DMA控制器发送相应的“DMA请求”信号。
DMA控制器接受到该信号后,就会向CPU发送“总线请求”信号,要求CPU释放总线,请求由DMA控制器控制总线以进行外设和主存之间的数据交换。CPU总是在一个总线事务结束后让出总线。
DMA控制器每传送一个数据,就使数据个数计数器减1。当该计数器为0时,表示传送过程结束。此结束信号被送到外设接口,引起外设接口向CPU发送一个“DMA传送结束”中断请求。
(3)DMA结束处理。当CPU接收到“DAM传送结束”中断请求后,就调出相应的中断服务程序进行DMA结束处理。
② 什么是DMA传输
什么是DMA?
当我们向计算机中加入了一块新的声卡或其它适配卡时,安装程序可能会提醒我们应该选择一个DMA通道。那DMA是什么呢? DMA(Direct Memory Access),即直接存储器存取,是一种快速传送数据的机制。数据传递可以从适配卡到内存,从内存到适配卡或从一段内存到另一段内存。DMA技术的重要 性在于,利用它进行数据传送时不需要CPU的参与。每台电脑主机板上都有DMA控制器,通常计算机对其编程,并用一个适配器上的ROM(如软盘驱动控制器 上的ROM)来储存程序,这些程序控制DMA传送数据。一旦控制器初始化完成,数据开始传送,DMA就可以脱离CPU,独立完成数据传送。
在DMA传送开始的短暂时间内,基本上有两个处理器为它工作,一个执行程序代码,一个传送数据。利用DMA传送数据的另一个好处是,数据直接在源地址和目 的地址之间传送,不需要中间媒介。如果通过CPU把一个字节从适配卡传送至内存,需要两步操作。首先,CPU把这个字节从适配卡读到内部寄存器中,然后再 从寄存器传送到内存的适当地址。DMA控制器将这些操作简化为一步,它操作总线上的控制信号,使写字节一次完成。这样大大提高了计算机运行速度和工作效 率。
计算机发展到今天,DMA已不再用于内存到内存的数据传送,因为CPU速度非常快,做这件事,比用DMA控制还要快,但要在适配卡和内存之间传送数据,仍 然是非DMA莫属。要从适配卡到内存传送数据,DMA同时触发从适配卡读数据总线(即I/O读操作)和向内存写数据的总线。激活I/O读操作就是让适配卡 把一个数据单位(通常是一个字节或一个字)放到PC数据总线上,因为此时内存写总线也被激活,数据就被同时从PC总线上拷贝到内存中。
对于每一次写操作,DMA控制器都控制地址总线,通知应将数据写到哪段内存中去。 DMA控制数据从内存传送到适配卡的方法与上面类似。对每一个要传送的单位数据,DMA控制器激活读内存和I/O写操作的总线。内存地址被放到地址总线 上,像从适配卡到内存传送数据一样,以数据总线为通道,数据从源地址直接传送到目的地址。 DMA从DMA请求线(DREQ)上接收DMA请求,正像中断控制器从中断请求线(IRQ)上接收中断请求一样。
一个典型的从适配卡到内存的数据传送是这样进行的,首先,对DMA控制器编程,写入数据要到达的内存地址和要传送的字节数。适配器可以开始传送数据时,它 将激活DREQ线,与DMA控制器连通。DMA控制器在与CPU取得总线控制权后,输出内存地址,发送控制信号,使得一个字节或一个字从适配器读出并写入 相应内存中,然后更新内存地址,指向下一个字节(或字)要写入的地址,重复上面的操作,直至数据传送完毕。对控制器进行不同编程,就可以实现单字节传送 (即每传送一个字节都要求一个DREQ信号)或块数据传送(即全部数据传送只需要一个DREQ信号)。
如果你要往计算机中插一块适配卡,而且适配卡使用DMA,通常安装程序会让你选择一个DMA通道,设定DIP开关或跳线,来为相应适配器设置DMA通道。 尽管从理论上讲,只要不是同时使用DREQ线,不同的适配卡可以共享这条线的,但是按常规,我们最好为每个适配卡单独安排一个DMA通道,这样就可以保证 不会发生DMA冲突。附表是DMA的缺省分配情况。通道 功能通道 功能 O 空闲 4 用于级联DMA控制器 1 空闲 5 空闲 2 软盘 6 空闲 3 空闲 7 空闲从中可以看出,DMA通道2和4已被占用,在大多数微机上,通道1、3、5、6和7可由你任意分配。我们平时最好对自己的计算机上DMA通道的分配情 况记录下来,以免我们向计算机增加新硬件时出现两个适配卡共用一个通道,导致冲突。 DMA---Direct Memory Access,直接内存访问,是一种数据传输模式。DMA方式下由于不直接访问计算机的CPU,而直接在RAM与设备之间传输,因而大大提高了数据传输速度。 呵呵,看过上面的DMA的含义及用途了,所以我们只需要打开DMA传输方式就可以了~~~操作方法: Windows 98/Me 启用内存直接存取DMA 右击Windows桌面上的“我的电脑” 图标并从弹出菜单选择“属性”。系统属性窗口出现。单击“设备管理”标签。双击“CDROM驱动器”,查看硬盘驱动器列表。右击IDE DISK(可能会有其他名称,例如 GENERIC IDE DISK)并从弹出菜单选择 “属性”。该硬盘属性窗口出现。单击“设置”标签。选择“DMA”如果该项未选,然后单击“确认”。Windows问您是否要重新启动,单击是。 在Windows 2000启用内存直接存取DMA 作为管理员(或具管理员特权的用户)登录进入Windos。右击Windows 桌面上的“我的电脑”图标并从弹出菜单选择属性。系统属性窗口出现。单击硬件标签, 然后单击设备管理器。设备管理员窗口出现。双击 IDE ATA/ATAPI 控制器来查看控制器列表。双击主IDE 通道。主IDE信道属性窗口出现。单击高级设置标签。选择DMA,如果该项可从设备0的传输模式列表中找到的话。单击确认。Windows问您是否要重新 启动, 单击是。 在Windows XP启用内存直接存取DMA 作为管理员(或具管理员特权的用户)登录进入Windows。单击“开始”按钮,,然后右击“我的电脑”并从弹出菜单选择属性。系统属性窗口出现。单击 “硬件” 标签,,然后单击“设备管理员”。设备管理员窗口出现。双击“IDE ATA/ATAPI”控制器来查看控制器列表。双击“从IDE 通道”。从IDE通道属性窗口出现。单击“高级设置”标签。选择DMA,如果该项可从装置0(或1,视您的刻录机的跳线设置而定)的传输模式列表中找到的 话。单击确认。您不必重新启动 Windows。 ================================================
附录:DMA精读 /********************************************************************************\
* Copyright (C) 2000 Texas Instruments Incorporated.
* All Rights Reserved
*------------------------------------------------------------------------------
* FILENAME...... dma1.c
* DATE CREATED.. 01/11/2000
* LAST MODIFIED. 01/04/2001
\******************************************************************************/
#include <std.h>
#include <log.h> /* Include DSPBIOS/CSL GUI configuration header file */
#include "dma1cfg.h" #include <csl.h>
#include <csl_irq.h>
#include <csl_dma.h> /* Constant defines transfer length */
#define N 128 /* Place src and dst of DMA transfer in seperate memory section */
/* to better control placement in user specified memory range */
#pragma DATA_SECTION(src,"dmaMem")
Uint16 src[N]; #pragma DATA_SECTION(dst, "dmaMem")
Uint16 dst[N];
/* This example effects a single-frame transfer of 128 */
/* elements from DARAM to DARAM, via DMA */
/* The macro invocation reflect the settings required in */
/* DMA control registers to make this happen. */ /* DMACSDP dstben == 0 */
/* dstpack == 0 */
/* dst == 0 */
/* srcben == 0 */
/* srcpack == 0 */
/* src == 0 */
/* datatype == 1 */
/* */
/* DMACCR dstamode == 1 */
/* srcamode == 1 */
/* endprog == 0 */
/* fifoflush == 0 */
/* repeat == 0 */
/* autoinit == 0 */
/* en == 0 */
/* prio == 0 */
/* fs == 0 */
/* sync == 0 */
/* */
/* DMACICR blockie == 1 */
/* lastie == 1 */
/* frameie == 1 */
/* firsthalfie == 1 */
/* dropie == 1 */
/* timeoutie == 1 */ DMA_Config myconfig = {
DMA_DMACSDP_RMK(
DMA_DMACSDP_DSTBEN_NOBURST,
DMA_DMACSDP_DSTPACK_OFF,
DMA_DMACSDP_DST_DARAM,
DMA_DMACSDP_SRCBEN_NOBURST,
DMA_DMACSDP_SRCPACK_OFF,
DMA_DMACSDP_SRC_DARAM,
DMA_DMACSDP_DATATYPE_16BIT
), /* DMACSDP */
DMA_DMACCR_RMK(
DMA_DMACCR_DSTAMODE_POSTINC,
DMA_DMACCR_SRCAMODE_POSTINC,
DMA_DMACCR_ENDPROG_OFF,
DMA_DMACCR_FIFOFLUSH_OFF,
DMA_DMACCR_REPEAT_OFF,
DMA_DMACCR_AUTOINIT_OFF,
DMA_DMACCR_EN_STOP,
DMA_DMACCR_PRIO_HI,
DMA_DMACCR_FS_ENABLE,
DMA_DMACCR_SYNC_NONE
), /* DMACCR */
DMA_DMACICR_RMK(
DMA_DMACICR_BLOCKIE_OFF,
DMA_DMACICR_LASTIE_OFF,
DMA_DMACICR_FRAMEIE_ON,
DMA_DMACICR_FIRSTHALFIE_OFF,
DMA_DMACICR_DROPIE_OFF,
DMA_DMACICR_TIMEOUTIE_OFF
), /* DMACICR */
(DMA_AdrPtr) &src, /* DMACSSAL */
0, /* DMACSSAU */
(DMA_AdrPtr) &dst, /* DMACDSAL */
0, /* DMACDSAU */
N, /* DMACEN */
1, /* DMACFN */
0, /* DMACFI */
0 /* DMACEI */
}; /* Define a DMA_Handle object */
DMA_Handle myhDma;
int i, j;
Uint16 err = 0;
volatile Bool WaitForTransfer = TRUE; void main(void)
{
/* Initialize source and destination buffers */
for (i = 0; i <= (N - 1); i++) {
dst[i] = 0;
src[i] = i + 1;
}
} void taskFxn(void)
{
/* Open DMA Channel 0 */
myhDma = DMA_open(DMA_CHA0, 0); /* By default, the TMS320C55xx compiler assigns all data symbols word */
/* addresses. The DMA however, expects all addresses to be byte */
/* addresses. Therefore, we must shift the address by 2 in order to */
/* change the word address to a byte address for the DMA transfer. */
myconfig.dmacssal =
(DMA_AdrPtr)(((Uint16)(myconfig.dmacssal))<<1);
myconfig.dmacdsal =
(DMA_AdrPtr)(((Uint16)(myconfig.dmacdsal))<<1); /* Write configuration structure values to DMA control registers */
DMA_config(myhDma, &myconfig); /* Enable DMA channel for to begin transfer */
DMA_FSETH(myhDma,DMACCR,EN,1); /* Wait for FRAME status bit in DMA status register to signal */
/* transfer is complete. */
while (!DMA_FGETH(myhDma,DMACSR,FRAME)) {
;
} /* Check dta values to make sure transfer happened correctly */
for (i = 0; i <= (N - 1); i++) {
if (dst[i] != src[i]) {
++err;
}
} if (err) {
LOG_printf(&trace, ">>> Warning, DMA Example 1 Failed");
}
else {
LOG_printf(&trace, "...DMA Example 1 Complete");
} /* We are through with DMA, so close it */
DMA_close(myhDma);
} DMA Functions Function Purpose
DMA_close() Closes the DMA and its corresponding handler
DMA_config() Sets up DMA using configuration structure (DMA_Config)
DMA_configArgs() Sets up DMA using register values passed to the function
DMA_getConfig() Reads the DMA configuration
DMA_getEventId() Returns the IRQ Event ID for the DMA completion interrupt
DMA_open() Opens the DMA and assigns a handler to it
DMA_pause() Interrupts the transfer in the corresponding DMA channel
DMA_reset() Resets the DMA registers with default values
DMA_start() Enables transfers in the corresponding DMA channel
DMA_stop() Disables the transfer in the corresponding DMA channel
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1568514 本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/zhongrg/archive/2007/11/18/1891323.aspx