精华内容
下载资源
问答
  • 本文是参考两篇CSDN和自己做修改笔记整理: 作者:lm_y 原文:https://blog.csdn.net/Com_ma/article/details/78145333 作者:dadalan 原文:https://blog.csdn.net/dadalan/article/details/2802979 一、...

    本文是参考几篇CSDN和自己做的修改笔记整理:
    cache、内存、虚拟内存:
    原文:https://blog.csdn.net/Com_ma/article/details/78145333

    DMA:
    原文:https://blog.csdn.net/dadalan/article/details/2802979
    原文:http://www.cnblogs.com/TaigaCon/archive/2012/12/03/2799407.html

    TBL和MMU:
    原文:https://www.baidu.com/link?url=FtIgOsEXqNyq0Q_JHOYwmr0GeaFyyTwMdYI1K8_4YwDkK2olMbTIe4r4ZMTW2l7eWoUZ_JpYUgjjvcF9XBYCRq&wd=&eqid=ec7ab12700001b44000000035c93172a
    https://www.cnblogs.com/findumars/p/4068418.html



    一、内存

    内存就是RAM
    RAMROM是相对的,RAM在断电后会丢失其中的信息,而ROM在断电后信息还会被保存。,

    RAM 分为 静态RAM动态RAM
    静态RAMSRAM,是仅次于CPU访问速度的RAM,L1 cache就是SRAM。
    而我们用的物理内存是动态RAM,即DRAM,DRAM的访问速度比SRAM要慢很多,但是体积小,价格便宜。


    二、cache

    cache就是高速缓存,是为了调和CPU得过快访问速度和内存过慢的速度的一个硬件,现代计算机一般都有三级高速缓存L1L2L3,访问速度依次递减。
    因为CPU要从内存中读取数据的时候会很慢,大部分时间会浪费在等待上,所以引入cache,把预计将要读取的数据先存放到cache中,这样CPU就可以先到cache中读取,从而节约了等待时间,如果cache中没有要读取的数据,那么继续往下到内存中读取,读到后再写入cache。


    三、虚拟内存

    虚拟内存是为了防止内存不够用,从硬盘上分割出一些空间,给内存扩展使用,这样程序就认为运行内存还够用。
    实际上呢,是把内存中一些不常用的数据或指令放到虚拟内存中,等到使用的时候再存放到内存中,因为内存的读取速度虽然比CPU和cache低,但是比硬盘要高很多,从而就加快了程序的运行速度。在内存为4G以上的计算机中,一般这个大小足够用了,虚拟内存就一般无用武之地了。


    四、过程小总结

    CPU首先得到的是虚拟地址,虚拟地址要翻译成物理地址后才能进行数据访问,这个过程要检查TLB(翻译后备缓冲器)1,如果命中,会得到其物理地址,之后会访问cache,如果cache中有要访问的数据,那么本次访问就结束,如果没有,就到内存中寻找,并更新cache;如果TLB不命中,那么那么系统内核会调用缺页异常处理程序去处理,这个过程中会进行页替换等操作,最终取得要访问的数据。


    五、虚拟内存和cache区别?

    那么我们来看下cache和虚拟内存的区别。

    (1)侧重点不同:cache主要解决主存与CPU的速度差异问题,而虚存主要是解决存储容量问题。

    (2)数据通路不同:CPU与cache和主存之间均有直接访问通路,cache不命中时可直接访问主存;而虚拟内存与CPU之间不存在直接的数据通路,当主存不命中时只能通过调页解决,CPU最终还是通过访问主内存。

    (3)透明性不同:cache的管理完全由硬件完成,对系统程序员和应用程序员均透明2;而虚存管理由软件(操作系统)和硬件共同完成,由于软件的介入,虚存对实现存储管理的系统程序员不透明,而只对应用程序员透明(段式和段页式管理对应用程序员“半透明”)。

    (4)未命中时的损失不同:由于主存的存取时间是cache的存取时间的5~10倍,而主存的存取速度通常比辅存的存取速度快上千倍,故主存未命中时系统的性能损失要远大于cache未命中时的损失。


    六、DMA

    1.如果没有DMA?

    一般来说,计算机进行数据处理时,需要把数据从内存读进CPU的寄存器,再进行进一步的操作(比如运算处理)。

    但有些数据并不需要运算处理这一类型的操作,只是单纯的移动数据——把数据从内存读进寄存器,然后再把数据从寄存器写进内存。这以过程会消耗cpu资源,当需要读写大量数据的时候便更是如此,DMA技术就很好地解决了这一问题。

    2.什么是DMA?

    DMA(Direct Memory Access,直接内存存取) ,顾名思义,就是不占用cpu资源,是一种快速传送数据的机制。数据传递可以从一个硬件存储区域把一部分连续的数据复制到另一个硬件存储区域,不经过CPU处理。其中硬件包括系统总线上的硬件(内存、磁盘3),和外部总线上的硬件(移动硬盘等)4

    3.DMA是怎么操作的?

    每台电脑主机板上都有DMA控制器,计算机会对其编程;相应的,适配器上也有ROM(如软盘驱动控制器上的ROM)来储存控制DMA传送数据的程序。

    开始是有CPU的介入的,但一旦控制器初始化完成,数据开始传送了,DMA就可以脱离CPU,独立完成数据传送,之后,在传送完成了,DMA的程序再利用中断通知CPU。

    在DMA传送开始的短暂时间内,基本上有两个处理器为它工作,一个执行程序代码,一个传送数据。

    传送中,数据直接在源地址和目的地址之间传送,没有中间媒介——DMA控制器将操作总线上的控制信号,使写字节一次完成。这样大大提高了计算机运行速度和工作效率。(如果没有DMA,过程是这样的,通过CPU把一个字节从适配卡传送至内存,需要两步操作:首先,CPU把这个字节从适配卡读到内部寄存器中,然后再从寄存器传送到内存的适当地址。)

    要从适配卡到内存传送数据,DMA同时触发从适配卡读数据总线(即I/O读操作)和向内存写数据的总线。激活I/O读操作就是让适配卡把一个数据单位(通常是一个字节或一个字)放到PC数据总线上,因为此时内存写总线也被激活,数据就被同时从PC总线上拷贝到内存中。

    直接内存访问(DMA)方式是一种完全由硬件执行I/O交换的工作方式。DMA控制器从CPU完全接管对总线的控制。数据交换不经过CPU,而直接在内存和I/O设备之间进行。DMA控制器采用以下三种方式:
    ①停止CPU访问内存:当外设要求传送一批数据时,由DMA控制器发一个信号给CPU。DMA控制器获得总线控制权后,开始进行数据传送。一批数据传送完毕后,DMA控制器通知CPU可以使用内存,并把总线控制权交还给CPU。
    ②周期挪用:当I/O设备没有 DMA请求时,CPU按程序要求访问内存:一旦 I/O设备有DMA请求,则I/O设备挪用一个或几个周期。
    ③DMA与CPU交替访内:一个CPU周期可分为2个周期,一个专供DMA控制器访内,另一个专供CPU访内。不需要总线使用权的申请、建立和归还过程。

    4.DMA传输会占用系统总线资源

    DMA虽然不会占用cpu资源,但是如果DMA的源DMA的目的都为内存的时候,由于内存位于系统总线上,DMA会占用总线资源,此时由于系统总线忙,cpu会由于得不到总线资源而无法进行跟外部的交流操作。

    如果DMA的源或目的为内存的时候,我们需要为其分配一块在物理上连续的内存。如果用kmalloc等函数分配的内存,虽然在虚拟地址看起来是连续的,但是物理上可能不连续,因此需要用到分配物理上连续的内存的函数(dma_alloc_writecombine)。

    为什么要分配连续的内存空间呢,因为平时cpu使用的时候,寻址会经过mmu内存管理单元1进行虚拟地址到物理地址的转换,而DMA是不经过mmu直接对内存进行读写的,直接对物理地址进行操作。

    4.使用DMA

    当我们要使用到DMA的时候,需要把传输的源(物理地址)、目的(物理地址)、大小告诉DMA,然后启动DMA,就能进行数据移动了。

    那么什么时候DMA会结束呢,当DMA传输结束的时候会发出一个中断,我们可以在该中断处理程序内部做进一步的操作(如打印消息等)。


    1. MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统。
      TLB(Translation Lookaside Buffer)传输后备缓冲器是一个内存管理单元用于改进虚拟地址到物理地址转换速度的缓存。TLB是一个小的,虚拟寻址的缓存,其中每一行都保存着一个由单个PTE组成的块。如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据。 ↩︎ ↩︎

    2. 什么叫透明性?透明是指什么都能看见吗?
      在计算机领域中,站在某一类用户的角度,如果感觉不到某个事物或属性的存在,即“看”不到某个事物或属性,则称为“对该用户而言,某个事物或属性是透明的”。这与日常生活中的“透明”概念(公开,看得见)正好相反 ↩︎

    3. 硬盘(外部存储器)是不是外设?
      计算机系统包括:软件系统硬件系统
      其中硬件系统包括:主机外设,外设就是外部设备的简称。
      主机包括:Cpu存储器。其中Cpu主要包含运算器和控制器。存储器包含内存储器和外存储器。
      外设包括:输入设备输出设备
      所以,如果说硬件系统由哪两大部分组成,那就是主机和外设
      如果说硬件系统由哪五大部件组成,就是 运算器、控制器、存储器、输入设备、输出设备
      硬盘是外部存储器,归于主机当中,不属于外部设备。
      只有在说磁盘驱动器的时候,磁盘驱动器才是外部设备,既可以读又可以写,即是输入设备又是输出设备。 ↩︎

    4. 计算机发展到今天,DMA已不再用于内存到内存的数据传送,因为CPU速度非常快,做这件事,效率更高,但要在适配卡和内存之间传送数据,仍然是非DMA莫属。 ↩︎

    展开全文
  • 1、基本概念 DMA即Direct Memory Access(直接存储器存取),那么为什么要引入这么个东东呢?它的作用又是什么呢?...于是 引入了DMA的概念,所谓DMA就是直接存储器访问,可以不通过CPU而在DMA控制

    1、基本概念

    DMA即Direct Memory Access(直接存储器存取),那么为什么要引入这么个东东呢?它的作用又是什么呢?我们通过一个例子来说明:
    比 如当我们要往内存里面拷贝一块很大的数据时,由于CPU同一时间只能做一件事情,这样在一段很长的时间里就不能再处理其它事情了,这样就造成了浪费。于是 引入了DMA的概念,所谓DMA就是直接存储器访问,可以不通过CPU而在DMA控制器的控制下,高速地与I/O设备和存储器交换数据。CPU除了在数据 传输开始和结束时做一些处理外,在传输过程中,CPU可以进行其它工作。这样,在大部分的时间里,CPU和输入/输出都处于并行操作状态,大大提高了效 率。
    我们需要做的就是将源、目的、长度告诉DMA,然后设置DMA参数,并启动DMA就可以了。
    2、DMA工作过程
    那么DMA的具体工作过程是怎样的呢?我们也有必要来说一下:
    (1)外设向DMA发出请求
    (2)DMA通过HOLD向CPU发出总线请求
    (3)CPU响应释放三总线,并且发应答HLDA
    (4)DMA向外设发DMA应答
    (5)DMA发出地址、控制信号,为外设传输数据
    (6)传送完规定的数据后,DMA撤销HOLD信号,CPU也撤销HOLD信号,并且恢复对三总线的控制
    3、s3c2440的DMA

    s3c2440支持4个DMA通道,每个DMA通道支持多个请求源,详见下表:


    每个DMA通道能处理下面四种情况的数据传输:
    (1)源器件和目的器件都在系统总线
    (2)源器件在系统总线,目的器件在外设总线
    (3)源器件在外设总线,目的器件在系统总线
    (4)源器件和目的器件都在外设总线
    1、驱动程序编写

    在本驱动程序中,我们打算在内存中开辟两个空间,分别作为源和目的。我们用两个方法将源中的数据写到目的中,一种方法是让cpu去做,另外一种发放是让DMA去做!好的,闲话少说,直接分析代码:

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/fs.h>
    #include <linux/init.h>
    #include <linux/delay.h>
    #include <linux/irq.h>
    #include <asm/uaccess.h>
    #include <asm/irq.h>
    #include <asm/io.h>
    #include <asm/arch/regs-gpio.h>
    #include <asm/hardware.h>
    #include <linux/poll.h>
    #include <linux/dma-mapping.h>
    
    #define MEM_CPY_NO_DMA  0
    #define MEM_CPY_DMA     1
    
    #define BUF_SIZE  (512*1024)
    
    #define DMA0_BASE_ADDR  0x4B000000
    #define DMA1_BASE_ADDR  0x4B000040
    #define DMA2_BASE_ADDR  0x4B000080
    #define DMA3_BASE_ADDR  0x4B0000C0
    
    struct s3c_dma_regs {
    unsigned long disrc;
    unsigned long disrcc;
    unsigned long didst;
    unsigned long didstc;
    unsigned long dcon;
    unsigned long dstat;
    unsigned long dcsrc;
    unsigned long dcdst;
    unsigned long dmasktrig;
    };
    
    
    static int major = 0;
    
    static char *src;
    static u32 src_phys;
    
    static char *dst;
    static u32 dst_phys;
    
    static struct class *cls;
    
    static volatile struct s3c_dma_regs *dma_regs;
    
    static DECLARE_WAIT_QUEUE_HEAD(dma_waitq);
    /* 中断事件标志, 中断服务程序将它置1,ioctl将它清0 */
    static volatile int ev_dma = 0;
    
    static int s3c_dma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
    {
    int i;
    
    memset(src, 0xAA, BUF_SIZE);
    memset(dst, 0x55, BUF_SIZE);
    switch (cmd)
    {
                    //这是非DMA模式
    case MEM_CPY_NO_DMA :
    {
    for (i = 0; i < BUF_SIZE; i++)
    dst[i] = src[i];  //CPU直接将源拷贝到目的
    if (memcmp(src, dst, BUF_SIZE) == 0)//这个函数见注释2
    {
    printk("MEM_CPY_NO_DMA OK\n");
    }
    else
    {
    printk("MEM_CPY_DMA ERROR\n");
    }
    break;
    }
    
                    //这是DMA模式
    case MEM_CPY_DMA :
    {
    ev_dma = 0;
    /* 把源,目的,长度告诉DMA */
                            /* 关于下面寄存器的具体情况,我们在注释3里面来详细讲一下 */
    dma_regs->disrc      = src_phys;        /* 源的物理地址 */
    dma_regs->disrcc     = (0<<1) | (0<<0); /* 源位于AHB总线, 源地址递增 */
    dma_regs->didst      = dst_phys;        /* 目的的物理地址 */
    dma_regs->didstc     = (0<<2) | (0<<1) | (0<<0); /* 目的位于AHB总线, 目的地址递增 */
    dma_regs->dcon       = (1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(0<<20)|(BUF_SIZE<<0);  /* 使能中断,单个传输,软件触发, */
    
    /* 启动DMA */
    dma_regs->dmasktrig  = (1<<1) | (1<<0);
    
    /* 如何知道DMA什么时候完成? */
    /* 休眠 */
    wait_event_interruptible(dma_waitq, ev_dma);
    
    if (memcmp(src, dst, BUF_SIZE) == 0)
    {
    printk("MEM_CPY_DMA OK\n");
    }
    else
    {
    printk("MEM_CPY_DMA ERROR\n");
    }
    break;
    }
    }
    
    return 0;
    }
    
    static struct file_operations dma_fops = {
    .owner  = THIS_MODULE,
    .ioctl  = s3c_dma_ioctl,
    };
    
    static irqreturn_t s3c_dma_irq(int irq, void *devid)
    {
    /* 唤醒 */
    ev_dma = 1;
        wake_up_interruptible(&dma_waitq);   /* 唤醒休眠的进程 */
    return IRQ_HANDLED;
    }
    
    static int s3c_dma_init(void)
    {
             /* 这里注册一个中断,当DMA数据传输完毕之后会发生此中断 */
    if (request_irq(IRQ_DMA3, s3c_dma_irq, 0, "s3c_dma", 1))
    {
    printk("can't request_irq for DMA\n");
    return -EBUSY;
    }
    /* 分配SRC, DST对应的缓冲区,关于此函数详见注释1 */
    src = dma_alloc_writecombine(NULL, BUF_SIZE, &src_phys, GFP_KERNEL);//源
    if (NULL == src)
    {
    printk("can't alloc buffer for src\n");
    free_irq(IRQ_DMA3, 1);
    return -ENOMEM;
    }
    dst = dma_alloc_writecombine(NULL, BUF_SIZE, &dst_phys, GFP_KERNEL);//目的
    if (NULL == dst)
    {
    free_irq(IRQ_DMA3, 1);
    dma_free_writecombine(NULL, BUF_SIZE, src, src_phys);
    printk("can't alloc buffer for dst\n");
    return -ENOMEM;
    }
    
    major = register_chrdev(0, "s3c_dma", &dma_fops);//注册字符设备
    
    /* 为了自动创建设备节点 */
    cls = class_create(THIS_MODULE, "s3c_dma");
    class_device_create(cls, NULL, MKDEV(major, 0), NULL, "dma"); /* /dev/dma */
    
    dma_regs = ioremap(DMA3_BASE_ADDR, sizeof(struct s3c_dma_regs));//这边是将DMA控制寄存器映射到内核空间
    return 0;
    }
    
    static void s3c_dma_exit(void)
    {
    iounmap(dma_regs);
    class_device_destroy(cls, MKDEV(major, 0));
    class_destroy(cls);
    unregister_chrdev(major, "s3c_dma");
    dma_free_writecombine(NULL, BUF_SIZE, src, src_phys);
    dma_free_writecombine(NULL, BUF_SIZE, dst, dst_phys);
    free_irq(IRQ_DMA3, 1);
    }
    
    module_init(s3c_dma_init);
    module_exit(s3c_dma_exit);
    
    MODULE_LICENSE("GPL");
    注释1:
    之前我们知道在内核中开辟空间可以用kmalloc函数,这里却用了dma_alloc_writecombine,这是为什么呢?这是因为kmalloc开辟的空间其逻辑地址虽然是连续的,但是其实际的物理地址可能不是连续的。而DMA传输数据时,要求物理地址是连续的,dma_alloc_writecombine就满足这一点,这个函数的原型是:
    dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
    其中size代表开辟的空间的大小,handle代表开辟的空间的物理地址,返回值是开辟的空间的逻辑地址。

    注释2:
    int memcmp(const void *cs, const void *ct, size_t count)
    {
    const unsigned char *su1, *su2;
    int res = 0;
    for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
    if ((res = *su1 - *su2) != 0)
    break;
    return res;
    }
    我们看到这个函数的作用就是将第一个参数和第二个参数一位一位地比较,一旦不相等就返回,此时返回值为非零。比较的位数为第三个参数,如果前两个参数的前count为都是相等的,那么就会返回0
    注释3:
    我们先来解析一下上面几个寄存器:

     DISRCn  bit  Description  Initial State
     S_ADDR  [30:0]  源起始地址  0x00000000
     DISRCCn  bit  Description Initial State
     LOC  [1]  用于选择源的位置
    0:源在系统总线上
    1:源在外设总线上
     0
     INC  [0]  用于选择地址是否自动增加
    0:地址自动增加
    1:地址固定不变(此时即便是burst 模式下,传输过程中地址自动增加,  但是一旦传输完这一次数据,地址又变为初值)
     0
     DIDSTn  bit  Description  Initial State
     D_ADDR  [30:0]  目的起始地址  0x00000000
     DIDSTCn  Bit  Description  Initial State
     CHK_INT  [2]  当设置为自动加载时,用来选择中断发生的时间
    0:TC为0是产生中断
    1:自动加载完成的时候产生中断
     0
     LOC  [1]  用于选择目的设备的位置
    0:目的设备在系统总线上
    1:目的设备在外设总线上
     0
     INC  [0]  用于选择地址是否自动增加
    0:地址自动增加
    1:地址固定不变(此时即便是burst模式下,传输过程中地址自动增加,但是一旦传输完这一次数据,地址又重新变为初值)
     0
     DCONn  Bit  Description  Initial State
     DMD_HS  [31]  选择为Demand模式或者是握手模式
    0:选择为Demand模式
    1:选择为握手模式
    这 两种模式下都是当发生请求时,DMA控制器开始传输数据并且发出  应  答信号,不同点是握手模式下,当DMA控制器收到请求撤销信号,并且自  身发出应答撤销信号之后才能接收下一次请求。而在Demand模式下,并  不需要等待请求撤销信号,他只需要撤销自身的应答信号,然后等待下一  次的请求。
     0
     SYNC  [30]  选择DREQ/DACK的同步
    0:DREQ and DACK 与PCLK同步
    1:DREQ and DACK 与HCLK同步
    因此当设备在AHB系统总线时,这一位必须为1,而当设备在APB系统  时,它应该被设为0。当设备位于外部系统时,应根据具体情况而定。
     0
     INT  [29]  是否使能中断
    0:禁止中断,用户需要查看状态寄存器来判断传输是否完成
    1:使能中断,所有的传输完成之后产生中断信号
     0
     TSZ  [28]  选择一个原子传输的大小
    0:单元传输(一次传输一个单元)
    1:突发传输(一次传输四个单元)
     0
     SERVMODE  [27]  选择是单服务模式还是整体服务模式
    0:单服务模式,当一次原子传输完成后需要等待下一个DMA请求
    1:整体服务模式,进行多次原子传输,知道传输计数值到达0
     0
     HWSRCSEL  [26:24]  为每一个DMA选择DMA请求源
    具体参见芯片手册
     000
     SWHW_SEL  [23]  选择DMA源为软件请求模式还是硬件请求模式
    0:软件请求模式,需要将寄存器DMASKTRIG的SW_TRIG置位
    1:硬件请求模式
     0
     RELOAD  [22]  是否自动重新装载
    0:自动重装,当目前的传输计数值变为0时,自动重装
    1:不自动重装
    RELOAD[1]被设置为0以防无意识地进行新的DMA传输
     0
     DSZ  [21:20]  要被传输的数据的大小
    00 = Byte    01 = Half word
    10 = Word   11 = reserved
     00
     TC  [19:0]  初始化传输计数 0000
    这里我们需要注意了,里面有三个东东要分清楚:
    DSZ   :代表数据的大小
    TSZ   :一次传输多少个数据
    TC     :一共传输多少次
    所以实际传输的数据的大小为:DSZ * TSZ * TC   
    我们本程序里面由于设置为数据大小为1个字节,一次传输1个数据,所以传输次数直接就是实际数据的大小了。
     DSTATn  Bit  Description  Initial State
     STAT  [21:20]  DMA控制器的状态
    00:DMA控制器已经准备好接收下一个DMA请求
    01:DMA控制器正在处理DMA请求
     00
     CURR_TC  [19:0]  传输计数的当前值
    每个原子传输减1
     
     DCSRCn  Bit  Description  Initial State
     CURR_SRC  [30:0]  当前的源地址  0x00000000
     DCDSTn  Bit  Description  Initial State
     CURR_DST  [30:0]  当前的目的地址  0x00000000
     DMASKTRIGn  Bit  Description  Initial State
     STOP  [2]  停止DMA操作
    1:当前的原子传输完成之后,就停止DMA操作。如果当前没有原子  传输正在进行,就立即结束。
     
     ON_OFF  [1]  DMA通道的开/闭
    0:DMA通道关闭
    1:DMA通道打开,并且处理DMA请求
     
     SW_TRIG  [0]  1:在软件请求模式时触发DMA通道  
    OK!寄存器分析完毕,具体设置就不在写出来了!
    在此我们在来总结一下DMA的操作流程:
    我们首先设置DMA的工作方式,然后打开DMA通道,紧接着我们使进程休眠,进入等待队列。与此同时,在DMA控制器的作用下,从源向目的拷贝数据。一旦数据拷贝完成,就会触发中断,在中断函数里面,唤醒进程,从而程序继续运行,打印相关信息。
    2、应用程序编写(测试用)
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <string.h>
    
    /* ./dma_test nodma
     * ./dma_test dma
     */
    #define MEM_CPY_NO_DMA  0
    #define MEM_CPY_DMA     1
    
    void print_usage(char *name)
    {
    printf("Usage:\n");
    printf("%s <nodma | dma>\n", name);
    }
    
    
    int main(int argc, char **argv)
    {
    int fd;
      if (argc != 2)
    {
    print_usage(argv[0]);
    return -1;
    }
    
    fd = open("/dev/dma", O_RDWR);
    if (fd < 0)
    {
    printf("can't open /dev/dma\n");
    return -1;
    }
    
    if (strcmp(argv[1], "nodma") == 0)
    {
    while (1)
    {
    ioctl(fd, MEM_CPY_NO_DMA);
    }
    }
    else if (strcmp(argv[1], "dma") == 0)
    {
    while (1)
    {
    ioctl(fd, MEM_CPY_DMA);
    }
    }
    else
    {
    print_usage(argv[0]);
    return -1;
    }
    return 0;
    }
    应用程序过于简单,不在分析!
    3、测试
    # insmod dma.ko      //加载驱动
    # cat /proc/interrupts //查看中断
               CPU0
     30:      52318         s3c  S3C2410 Timer Tick
     33:          0         s3c  s3c-mci
     34:          0         s3c  I2SSDI
     35:          0         s3c  I2SSDO
     36:          0         s3c  s3c_dma
     37:         12         s3c  s3c-mci
     42:          0         s3c  ohci_hcd:usb1
     43:          0         s3c  s3c2440-i2c
     51:       2725     s3c-ext  eth0
     60:          0     s3c-ext  s3c-mci
     70:         97   s3c-uart0  s3c2440-uart
     71:        100   s3c-uart0  s3c2440-uart
     83:          0           -  s3c2410-wdt
    Err:          0

    # ls /dev/dma     //查看设备
    /dev/dma

    # ./dmatest       //如此就会打印用法
    Usage:
    ./dmatest <nodma | dma>

    # ./dmatest dma     //以DMA方式拷贝,CPU可以做其他事情
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK

    # ./dmatest nodma     //CPU拷贝,各种竞争CPU
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    MEM_CPY_DMA OK
    小结:DMA简单操作步骤:

    (1)申请DMA中断,配置中断处理函数

    (2)申请DMA的I/O内存,并将相应的物理内存映射成虚拟地址(ioremap)

    (3)配置DMA相应寄存器,然后启动DMA传送,传送完启动DMA中断。


    展开全文
  • DMA的基本概念

    千次阅读 2015-11-25 22:26:39
    8.3.1 DMA的基本概念 直接内存访问(DMA)是一种完全由硬件执行I/O交换的工作方式。在这种方式中,DMA控制器从CPU完全接管对总线的控制,数据交换不经过CPU,而直接在内存和I/O设备之间进行 。DMA方式一般用于...

    8.3.1 DMA的基本概念    

    直接内存访问(DMA)是一种完全由硬件执行I/O交换的工作方式。在这种方式中,DMA控制器从CPU完全接管对总线的控制,数据交换不经过CPU,而直接在内存和I/O设备之间进行 。DMA方式一般用于高速传送成组数据。DMA控制器将向内存发出地址和控制信号,修改地址,对传送的字的个数计数,并且以中断方式向CPU报告传送操作的结束。

      DMA方式的主要优点是速度快。由于CPU根本不参加传送操作,因此就省去了CPU取指令、取数、送数等操作。在数据传送过程中,没有保存现场、恢复现场之类的工作。内存地址修改、传送字个数的计数等等,也不是由软件实现,而是用硬件线路直接实现的。所以DMA方式能满足高速I/O设备的要求,也有利于CPU效率的发挥。

    多种DMA至少能执行以下一些基本操作:

    (1)从外围设备发出DMA请求;

    (2)CPU响应请求,把CPU工作改成DMA操作方式,DMA控制器从CPU接管总线的控制;

    (3)由DMA控制器对内存寻址,即决定数据传送的内存单元地址及数据传送个数的计数,并执行数据传送的操作;

    (4)向CPU报告DMA操作的结束

    注意 在DMA方式中,一批数据传送前的准备工作,以及传送结束后的处理工作,均由管理程序承担,而DMA控制器仅负责数据传送的工作。

     

    8.3.2 DMA传送方式         

      DMA技术的出现,使得外围设备可以通过DMA控制器直接访问内存,与此同时,CPU可以继续执行程序。DMA控制器与CPU分时使用内存通常采用以下三种方法:

    1.停止CPU访问内存

    当外围设备要求传送一批数据时,由DMA控制器发一个停止信号给CPU,要求CPU放弃对地址总线、数据总线和有关控制总线的使用权。DMA控制器获得总线控制权以后,开始进行数据传送。在一批数据传送完毕后,DMA控制器通知CPU可以使用内存,并把总线控制权交还给CPU。在这种DMA传送过程中,CPU基本处于不工作状态或者说保持状态。这种传送方式的时间图如下:

      优点: 控制简单,它适用于数据传输率很高的设备进行成组传送。

      缺点: 在DMA控制器访内阶段,内存的效能没有充分发挥,相当一部分内存工作周期是空闲的。这是因为,外围设备传送两个数据之间的间隔一般总是大于内存存储周期,即使高速I/O设备也是如此。

    2.周期挪用:

    当I/O设备没有DMA请求时,CPU按程序要求访问内存;一旦I/O设备有DMA请求,则由I/O设备挪用一个或几个内存周期。

    I/O设备要求DMA传送时可能遇到两种情况

    (1)此时CPU不需要访内,如CPU正在执行乘法指令。由于乘法指令执行时间较长,此时I/O访内与CPU访内没有冲突,即I/O设备挪用一二个内存周期对CPU执行程序没有任何影响。

    (2)I/O设备要求访内时CPU也要求访内,这就产生了访内冲突,在这种情况下I/O设备访内优先,因为I/O访内有时间要求,前一个I/O数据必须在下一个访内请求到来之前存取完毕。显然,在这种情况下I/O 设备挪用一二个内存周期,意味着CPU延缓了对指令的执行,或者更明确地说,在CPU执行访内指令的过程中插入DMA请求,挪用了一二个内存周期。

    这种传送方式的时间图如下:

    与停止CPU访内的DMA方法比较,周期挪用的方法既实现了I/O传送,又较好地发挥了内存和CPU的效率,是一种广泛采用的方法。但是I/O设备每一次周期挪用都有申请总线控制权、建立总线控制权和归还总线控制权的过程,所以传送一个字对内存来说要占用一个周期,但对DMA控制器来说一般要2—5个内存周期(视逻辑线路的延迟而定)。因此,周期挪用的方法适用于I/O设备读写周期大于内存存储周期的情况。

    3.DMA与CPU交替访内:

    如果CPU的工作周期比内存存取周期长很多,此时采用交替访内的方法可以使DMA传送和CPU同时发挥最高的效率。假设CPU工作周期为 1.2μs,内存存取周期小于0.6μs,那么一个CPU周期可分为C1和C2两个分周期,其中C1供DMA控制器访内,C2专供CPU访内。这种传送方式的时间图如下:

      这种方式不需要总线使用权的申请、建立和归还过程,总线使用权是通过C1和C2分时进行的。CPU和DMA控制器各自有自己的访内地址寄存器、数据寄存器和读/写信号等控制寄存器。在C1周期中,如果DMA控制器有访内请求,可将地址、数据等信号送到总线上。在C2周期中,如CPU有访内请求,同样传送地址、数据等信号。事实上,对于总线,这是用C1,C2控制的一个多路转换器,这种总线控制权的转移几乎不需要什么时间,所以对DMA传送来讲效率是很高的。

      这种传送方式又称为“透明的DMA”方式,其来由是这种DMA传送对CPU来说,如同透明的玻璃一般,没有任何感觉或影响。在透明的DMA方式下工作,CPU既不停止主程序的运行,也不进入等待状态,是一种高效率的工作方式。当然,相应的硬件逻辑也就更加复杂。

     

     

    8.3.3 基本的DMA控制器      

    1.DMA控制器的基本组成

      一个DMA控制器,实际上是采用DMA方式的外围设备与系统总线之间的接口电路。这个接口电路是在中断接口的基础上再加DMA机构组成。其逻辑示意图见文字教材图8.12。

    一个最简单的DMA控制器由以下逻辑部件组成:

    (1)内存地址计数器 用于存放内存中要交换的数据的地址。在DMA传送前,须通过程序将数据在内存中的起始位置(首地址)送到内存地址计数器。而当DMA传送时,每交换一次数据,将地址计数器加“1”,从而以增量方式给出内存中要交换的一批数据的地址。

    (2)字计数器用于记录传送数据块的长度(多少字数)。其内容也是在数据传送之前由程序预置,交换的字数通常以补码形式表示。在DMA传送时,每传送一个字,字计数器就加“1” ,当计数器溢出即最高位产生进位时,表示这批数据传送完毕,于是引起DMA控制器向CPU发中断信号。

    (3)数据缓冲寄存器 用于暂存每次传送的数据(一个字)。当输入时,由设备(如磁盘)送往数据缓冲寄存器,再由缓冲寄存器通过数据总线送到内存。反之,输出时,由内存通过数据总线送到数据缓冲寄存器,然后再送到设备。

    (4)“DMA请求”标志每当设备准备好一个数据字后给出一个控制信号,使“DMA请求” 标志置“1”。该标志置位后向“控制/状态”逻辑发出DMA请求,后者又向CPU发出总线使用权的请求(HOLD),CPU响应此请求后发回响应信号HLDA,“控制/状态”逻辑接收此信号后发出DMA响应信号,使“DMA请求”标志复位,为交换下一个字做好准备。

    (5)“控制/状态”逻辑 由控制和时序电路以及状态标志等组成,用于修改内存地址计数器和字计数器,指定传送类型(输入或输出),并对“DMA请求”信号和CPU响应信号进行协调和同步。

    (6)中断机构 当字计数器溢出时(全0),意味着一组数据交换完毕,由溢出信号触发中断机构,向CPU提出中断报告。这里的中断与上一节介绍的I/O中断所采用的技术相同,但中断的目的不同,前面是为了数据的输入或输出,而这里是为了报告一组数据传送结束。因此它们是I/O系统中不同的中断事件。

    2.DMA数据传送过程

      DMA的数据块传送过程可分为三个阶段:传送前预处理;正式传送;传送后处理。

      预处理 由CPU执行几条输入输出指令,测试设备状态,向DMA控制器的设备地址寄存器中送入设备号并启动设备,向内存地址计数器中送入起始地址,向字计数器中送入交换的数据字个数。在这些工作完成后,CPU继续执行原来的主程序。

      正式传送当外设准备好发送数据(输入)或接受数据(输出)时,它发出DMA请求,由DMA控制器向CPU发出总线使用权的请求(HOLD)。下图示出了停止CPU访内方式的DMA传送数据的流程图。

    图8.13 DMA传送数据的流程图

      DMA的数据传送是以数据块为基本单位进行的,因此,每次DMA控制器占用总线后,无论是数据输入操作,还是输出操作,都是通过循环来实现的。当进行输入操作时,外围设备的数据(一次一个字或一个字节)传向内存;当进行输出操作时,内存的数据传向外围设备。

      后处理 一旦DMA的中断请求得到响应,CPU停止主程序的执行,转去执行中断服务程序做一些DMA的结束处理工作。这些工作包括校验送入内存的数据是否正确;决定继续用DMA方式传送下去,还是结束传送;测试在传送过程中是否发生了错误等等。

    基本DMA控制器与系统的连接方式:

     

    (1)公用的DMA请求方式;(2)独立的DMA请求方式,这与中断方式类似。

    8.3.4 选择型和多路型DMA控制器:

    1.选择型DMA控制器

      选择型DMA控制器在物理上可以连接多个设备,而在逻辑上只允许连接一个设备。换句话说,在某一段时间内只能为一个设备服务。

      选择型DMA控制器的逻辑框图请见CAI演示。 

    选择型DMA控制器的工作原理

      与前面的简单DMA控制器基本相同。除了前面讲到的基本逻辑部件外,还有一个设备号寄存器。数据传送是以数据块为单位进行的,在每个数据块传送之前的预置阶段,除了用程序中I/O指令给出数据块的传送个数、起始地址、操作命令外,还要给出所选择的设备号。从预置开始,一直到这个数据块传送结束,DMA控制器只为所选设备服务。下一次预置再根据I/O指令指出的设备号,为另一选择的设备服务。显然,选择型DMA控制器相当于一个逻辑开关,根据I/O指令来控制此开关与某个设备连接。

      选择型DMA控制器只增加少量硬件达到了为多个外围设备服务的目的,它特别适合数据传输率很高以至接近内存存取速度的设备。在很快地传送完一个数据块后,控制器又可为其他设备服务。

    2.多路型DMA控制器

      选择型DMA控制器不适用于慢速设备。但多路型DMA控制器适合于同时为多个慢速外围设备服务。

      链式多路型DMA控制器独立请求方式多路型DMA控制器请见CAI演示。

      多路型DMA不仅在物理上可以连接多个外围设备,而且在逻辑上也允许这些外围设备同时工作,各设备以字节交叉方式通过DMA控制器进行数据传送。

    【例3】下图中假设有磁盘、磁带、打印机三个设备同时工作。磁盘以30μs的间隔向控制器发DMA请求,磁带以45μs的间隔发DMA请求,打印机以150μs间隔发DMA请求。根据传输速率,磁盘优先权最高,磁带次之,打印机最低,图中假设DMA控制器每完成一次DMA传送所需的时间是5μs。若采用多路型DMA控制器,请画出DMA控制器服务三个设备的工作时间图。

    图8.16 多路DMA控制器工作时间图

    【解】

    由图看出,T1间隔中控制器首先为打印机服务,因为此时只有打印机有请求。T2间隔前沿磁盘、磁带同时有请求,首先为优先权高的磁盘服务,然后为磁带服务,每次服务传送一个字节。在150μs时间阶段中,为打印机服务只有一次(T1),为磁盘服务四次(T2,T4,T6,T7),为磁带服务三次(T3,T5,T8)。从图上看到,在这种情况下DMA尚有空闲时间,说明控制器还可以容纳更多设备。

      由于多路型DMA同时要为多个设备服务,因此对应多少个DMA通路(设备),在控制器内部就有多少组寄存器用于存放各自的传送参数。

      多路型DMA控制器的逻辑结构请见文字教材图8.17。通过配合使用I/O通用接口片子,多路型DMA控制器可以对8个独立的DMA通路(CH)进行控制,使外围设备以周期挪用方式对内存进行存取。

      8条独立的DMA请求线或响应线能在外围设备与DMA控制器之间进行双向通信。一条线上进行双向通信是通过分时和脉冲编码技术实现的。也可以分别设立DMA请求线和响应线实现双向通信。每条DMA线在优先权结构中具有固定位置,一般DMA0线具有最高优先权,DMA7线具有最低优先权。

      控制器中有8个8位的控制传送长度的寄存器,8个16位的地址寄存器。每个长度寄存器和地 址寄存器对应一个设备。每个寄存器都可以用程序中的I/O指令从CPU送入控制数据。每一寄 存器组各有一个计数器,用于修改内存地址和传送长度。

    当某个外围设备请求DMA服务时,操作过程如下:

    (1)DMA控制器接到设备发出的DMA请求时,将请求转送到CPU。

    (2)CPU在适当的时刻响应DMA请求。若CPU不需要占用总线则继续执行指令;若CPU需要占用 总线,则CPU进入等待状态。

    (3)DMA控制器接到CPU的响应信号后,进行以下工作:①对现有DMA请求中优先权最高的请求 给予DMA响应;②选择相应的地址寄存器的内容驱动地址总线;③根据所选设备操作寄存器 的内容,向总线发读、写信号;④外围设备向数据总线传送数据,或从数据总线接收数据; ⑤每个字节传送完毕后,DMA控制器使相应的地址寄存器和长度寄存器加“1”或减“1”。 

      以上是一个DMA请求的过程,在一批数据传送过程中,要多次重复上述过程,直到外围设备表示一个数据块已传送完毕,或该设备的长度控制器判定传送长度已满。 

    【例4】教材图8.18所示为微型机中软盘控制器的系统接口电路,请进行分析说明。

     

     

                                        

    展开全文
  • STM32-DMA基本概念

    2020-10-21 18:05:47
    STM32-DMA基本概念 工作原理 DMA即直接存储器访问,无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,他是通过硬件为RAM与I/O设备开辟一条直接传送数据通路,可以使得CPU效率大大提高。 ...

    STM32-DMA基本概念

    工作原理

    DMA即直接存储器访问,无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,他是通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,可以使得CPU的效率大大提高。

    STM32F103有两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。为了保证每个通道协调有序,还有一个仲裁器来协调各个DMA请求的优先权。

    如图为STM32F103的12个通道DMA请求预览表
    在这里插入图片描述
    在这里插入图片描述

    通道优先级

    这些通道的优先级可以通过软件和硬件配合设定,软件方面可以通过编程配置寄存器,当配置的优先权相等时,由硬件决定。

    软件:每个通道的优先权可以在DMA_CCRx寄存器中设置,有4个等级:

    • ─ 最高优先级
    • ─ 高优先级
    • ─ 中等优先级
    • ─ 低优先级

    硬件:如果2个请求有相同的软件优先级,则拥有较低编号的通道比拥有较高编号的通道有较高的优先权。举个例子,通道2优先于通道4。

    DMA的传输

    DMA有4种传输模式

    • 存储器和存储器间的传输
    • 外设和外设间的传输
    • 存储器到外设间的传输
    • 外设到存储器间的传输

    想要使用DMA传输还需要确定这么几点内容:DMA传输的源、目的和长度。可以通过配置如下寄存器,以实现目的。

    • DMA_CPARx寄存器(DMA_CPARx)(x = 1…7) 设置外设地址,作为数据传输的源或目标。
    • DMA_CMARx寄存器(DMA_CMARx)(x = 1…7)设置存储器地址,作为数据传输的源或目标。
    • DMA_CNDTRx寄存器 设置写入要传输的数据量,即长度。数据传输数量为0至65535。
    • DMA_CCRx寄存器 设置数据传输的方向。
      如果要配置存储器到存储器模式。MEM2MEM这一位需要置1
      配置源和目的的数据宽度,两边尽量保持一致
      MSIZE:存储器数据宽度;PSIZE:外设数据宽度

    DMA中断

    可以在DMA传输过半、传输完成和传输错误时产生中断。为应用的灵活性考虑,通过设置寄存器DMA_ISR(DMA中断状态寄存器)的不同位来打开这些中断
    在这里插入图片描述

    展开全文
  • 8.3.1 DMA的基本概念

    2015-06-07 15:52:52
    DMA的基本概念  直接内存访问(DMA)是一种完全由硬件执行I/O交换的工作方式。在这种方式中,DMA控制器从CPU完全接管对总线的控制,数据交换不经过CPU,而直接在内存和I/O设备之间进行 。DMA方式一般用于高速...
  • DMA的触发方式   1. 每块拥有DMA功能的芯片基本可以通过特定的通道来触发DMA。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。(如stm32、2440等芯片)   2. 每个通道对应以下四种模式:    ...
  • DMA中burst的概念

    2014-03-24 18:41:23
    DMA和burst不是一个概念DMA传送不经过CPU控制,假如硬盘数据不能经过DMA控制器读到内存,那么每完成一次将硬盘数据读出来,再存放到内存操作,都要通过CPU运行几条读写指令来完成,这时CPU就做不了别...
  • 本文是基于操作系统linux下的利用DMA的方式将
  • DMA burst 基本概念

    千次阅读 2018-01-18 10:04:01
     DMA传送不经过CPU控制,假如硬盘数据不能经过DMA控制器读到内存,那么每完成一次将硬盘数据读出来,再存放到内存操作,都要通过CPU运行几条读写指令来完成,这时CPU就做不了别事了,如果有DMA控制器,则...
  • DMA即Direct Memory Access(直接存储器存取),那么为什么要引入这么个东东呢?它作用又是什么呢?我们通过一个例子来说明: 比 如当我们要往内存里面拷贝一块很大数据时,由于CPU同一时间只能做一件事情,...
  • WDF DMA一些概念(2)

    千次阅读 2016-05-10 18:06:03
    SG list 原来是框架 使用系统提供物理地址 建立。   以前第一次接触这个表还以为要由驱动开发者提供呢。 Each element of the list thus represents the physical memory address of either a data buffer ...
  • DMA使用几个概念,burst

    千次阅读 2016-11-21 13:49:16
    一般芯片的dma有基本功能。 1、普通的内存、外设间互传数据,...dma有burst、burst size、transfer的概念:   burst: dma实际上是一次一次的申请总线,把要传的数据总量分成一个一个小的数据块。比如要传
  • 在Windows上使用磁盘设备进行DMA的概念验证。 ddma一种小概念证明,用于在Windows上将磁盘设备用于DMA。 为什么某些本地虚拟机管理程序(即Hyper-V)允许来宾虚拟化设备访问权限,这意味着可以绕过SLAT。 演示在...
  • DMA

    千次阅读 2011-01-12 10:47:00
    解释一 <br /> Direct Memory Access(存储器直接访问)。这是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,既不通过CPU,也不需要CPU干预。...DMA的概念:DMA是在专门的硬件( DMA)控
  • DMA传送不经过CPU控制,假如硬盘数据不能经过DMA控制器读到内存,那么每完成一次将硬盘数据读出来,再存放到内存操作,都要通过CPU运行几条读写指令来完成,这时CPU就做不了别事了,如果有DMA控制器,则这...
  • DMA的简单介绍

    2021-04-08 14:14:25
    一、DMA基本概念 二、DMA burst 基本概念 三、DMA缓存cache一致性原则 3.1 先理解cache作用 3.2 Cache一致性 3.3 一致性DMA映射和流式DMA映射 四、链表传输 五、参考文章 一、DMA基本概念 DMA英文全称...
  • linux驱动之DMA

    2020-12-29 13:55:35
    一、前言 ...那么本文就从头到尾,简单地说一下 DMA 吧注意:本文对DMA的概念不做讲述,请各位读者自行了解DMA的概念。 二、正文 2.1 高端内存 2.1.1 内核虚拟内存 在了解 DMA 之前,我们需要先了解
  • 一般芯片的dma有基本功能。...说一下注意点: dma有burst、burst size、transfer的概念: burst:dma实际上是一次一次的申请总线,把要传的数据总量分成一个一个小的数据块。比如要传64个字节,那么dma内部可能分
  • dma

    千次阅读 2014-01-03 18:35:25
    DMA的英文拼写是“Direct Memory Access”,汉语的意思就是直接内存访问。DMA既可以指内存和外设直接存取数据这种内存访问的计算机技术,又可以指实现该技术的硬件模块(对于通用计算机PC而言,DMA控制逻辑由CPU和...
  • Nios II中DMA设备使用

    千次阅读 2007-01-10 09:42:00
    Nios II的标准设备软IP中有一个DMA设备,在... DMA的概念其实挺简单,无非就是把一定长度的数据从源地址传送到目标地址。其中有一点比较重要的是对于地址的操作方式,一种是地址自增,另一种是地址固定。就是说DMA控
  • STM32之DMA学习

    2020-08-16 17:32:02
    传统的DMA的概念是用于大批量数据的传输,但是我理解,在STM32中,它的概念被扩展了,也许更多的时候快速是其应用的重点。数据可以从1~65535个。 直接存储器存取(Direct Memory Access,DMA)是计算机科学中的一种...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 611
精华内容 244
关键字:

dma的概念