目录
一、DMA的介绍
DMA作为一种CPU与外设传输数据的技术,现在广泛用于各种计算机架构中,它最大的优点就是无需CPU干涉下,完成数据从内存到外设的传递。本文讲解一下S5PC100中的DMA控制器的操作方法。文中例举的代码都是在FS_S5PC100平台上经过验证的。在华清远见的FS_S5PC100平台上通过PL330 DMA控制器实现了内存到内存、内存到串口、串口到串口等多种DMA传输方式。
首先简单介绍下什么是DMAC,DMAC 是一个自适应先进的微控制器总线体系的控制器,它由ARM公司设计并基于PrimeCell技术标准,DMAC提供了一个AXI接口用来执行DMA传输,以及两个APB接口用来控制这个操作,DMAC在安全模式技术下用一个APB接口执行TrustZone技术,其他操作则在非安全模式下执行。DMAC包括了一个小型的指令集,用来提供一些灵活便捷的操作,为了缩小内存需求,DMAC则使用了变长指令。
不同于ARM11以及以前系列的芯片,Exnos 4412使用了基于PrimeCell技术标准的PL330(DMA控制器核心)有了很大的变化,从编程方式上看,它提供了灵活的指令集,使得你有更多的组合方式用来操作DMA,从硬件上看,它实现了硬件上的多线程管理,一次编写代码即可让它正常的完成所需的工作,因此这个DMA的开发是有一定困难的。
由图可以看出,Exnos 4412的DMA模块又分为两个子模块,DMA mem和DMA_ peri。 其中,DMA_ mem用于内存之间的数据传输; DMA_ peri用于内存与外设之间进行数据传输。DMA mem包括-个PL330模块,而DMA _peri包括两个1330模块(分别为DMAO和DMA1)。每个PL330模共有32个中断源,但是每次只能发送 一个中断请求到中断控制器。
二、PL330简述
DMAC包含了一个执行指令的模块,并且控制了数据的传输,DMAC通过AXI接口来存取这些存储在了内存中的指令,DMAC还可以将一些临时的指令存放在Cache中,我们能够配置行宽度以及深度。当然,DMAC的8个通道都是可配置的,且每个都可支持单个并发线程的操作,除此之外,还有一个管理线程专门用来初始化DMA通道的线程。它是用来确保每个线程都在正常工作,它使用了round-robin来处理当选择执行下一个活动期的DMA通道。
DMAC使用了变长指令集,范围在1到6字节之间,并还为每个通道提供了单独的PC寄存器,当一个线程需要执行一条指令时,将先从Cache中搜索,如果匹配上则立刻供给数据,另外,线程停止的话,DMAC将使用AXI接口来执行一次Cache线填充。
当一个DMA通道线程执行一次load/store指令,DMAC将添加指令到有关的读队列和写队列中,DMAC使用这些队列作为一个指令存储区,它用来优先执行存储在其中的指令,DMAC还有包含了一个MFIFO数据缓存区,它用来存储DMA传输中读/写的数据。DMAC还提供多个中断输出,在微处理器的不干扰下,外设的request接口还有内存到外设和外设到内存的传输能力,双APB接口支持安全以及非安全两种模式,编程时,可通过APB接口来访问状态寄存器和直接执行DMAC指令。
三、工作原理
3.1 工作过程
(1)当外设准备就绪,向DMA控制器(DMAC)发出DMA清求信号(DREQ)。DMAC收到此信号后,向CPU发出总线请求信号(HOLD)。
(2)CPU在完成当前总线操作后立即对DMA请求信号做出响应。DMAC获得总线的控制权。
(3)DMAC获得总线的控制权后,向地址总线发出地址信号,指出传送过程需使用的内存地址。向外设发出DMA应答信号(DACK),实现该外设与内存之间的DMA传送。
(4)在DMA传送期间,DMAC发出内存和外设的读/写信号。
(5)为了决定数据块传输的字节数,在DMAC内部必须有一个“字节计数器”。在开始时,由软件设置数据块的长度,在DMA传送过程中,每传送一个字节,字节计数器减1,减为0时,该次DMA传输结束。
(6)DMAC过程结束时,DMAC向CPU发出结束信号(撤消HOLD请求),将总线控制权交还CPU。
3.2 传送的方式
(1)I/O接口到存储器方式
I/O接口的数据利用DMAC送出控制信号,将数据输送到数据总线D0~D7上,同时DMAC送出存储器单元地址及控制信号,将存于DO~D7上的数据写入选中的存储单元中。这样就完成了I/O接口到存储器的一个字节的传送。
(2)存储器到I/O接口方式
在进行传送时,DMAC送出存储器地址和控制信号,将选中的存储器单元的内容读入数据总线的D0~D7,然后DMAC送出控制信号,将数据写到指定的端口中。DMAC再修改“地址寄存器”和“字节计数器”的内容。
(3)存储器到存储器方式
这种方式的DMA数据传送是用“数据块”方式传送。首先,送出存储器源的地址和控制信号,将选中内存单元的数据暂存,然后修改“地址寄存器”和“字节计数器 ”的值,接着,送出存储器目标的地址和控制信号,将暂存的数据通过数据总线写入存储器的目标区域中,最后修改“地址寄存器”和“字节计数器”的内容,当“字节计数器”的值减少到零时便结束次DMA传送。
四、PL330指令集
4.1 DMAMOV
指令格式:DMAMOV <destination_register>, <32-bit_immediate>
功能描述:这是一条数据转移指令,它可以移动一个立即数到以下3种类型的寄存器中。
参数:
<destination_register> :可以是源地址寄存器、目标地址寄存器、通道控制寄存器。
源地址寄存器(SAR):该寄存器提供了DMA通道的数据源的地址,DMAC从该地址取得数据,每个通道都有自己的数据源地址寄存器,因此需要单独配置。Rd[2:0] = 0b000。
通道控制寄存器(CCR):该寄存器可以控制DMA 在AXI中的传输,并且该寄存器记录了一些关于目标与源寄存器的基本配置。Rd[2:0] = 0b001。
目标地址寄存器(DAR):该寄存器提供了DMA的目标数据存放地址,和数据源地址寄存器是相互对应的。Rd[2:0] = 0b010。
<32-bit_immediate> :该32位立即数可被传到指定的寄存器中。
指令编码:
4.2 DMALD
指令格式:DMALD[S|B]
功能描述:这是一条DMAC装载指令,它可以从源数据地址中读取数序到MFIFO中,如果src_int位被设置,则DMAC会自动增加源地址的值。
[S] 如果S位被指定,则bs位被置0,且x转换为0。Request_flag将被下列情况所影响:
Request_flag=Single,,DMAC将执行DMA装载。
Request_flag=Burst ,DMAC将执行控制另DMANOP。
[B] 如果B位被指定,则bs会置0,且x转换为1,Request_flag将被下列情况所影响:
Request_flag=Single,,DMAC将执行控制另DMANOP。
Request_flag=Burst , DMAC将执行DMA装载
注意 :如果不指定S,B位的话,则DMAC默认是执行DMA装载的。
指令编码:
4.3 DMAST
指令格式:DMAST[S|B]
功能描述:该指令与DMALD相互对应,它是一条DMA存储指令,是将MFIFO中的数据转移到目的地址中。目的地址是由目的地址寄存器所指定的,如果dst_inc被置位,则DMAC会自动增加目的地址的值。
[S] 如果S位被指定,则bs位被置0,且x转换为1。Request_flag将被下列情况所影响:
Request_flag=Single,DMAC执行单个DMA存储。
Request_flag=Burst ,DMAC执行空指令。
[B] 如果B位被指定,则bs被设置为1,且x转位1,Request_flag将被下列情况所影响:
Request_flag=Single, DMAC执行空指令。
Request_flag=Burst , DMAC将执行DMA存储。
指令编码:
4.4 DMARMB
指令格式:DMARMB
功能描述:读内存栅栏指令,该指令可以使得当前所有读处理全部被强制取消。
指令编码:
4.5 DMAWMB
指令格式:DMAWMB
功能描述:写内存栅栏指令,该指令可以使得当前所有写处理全部被强制取消。
指令编码:
4.6 DMALP
指令格式:DMALP <loop_iterations>
功能描述:循环操作时,将一个指定的8bit数字填入循环计数寄存器,该指令用来指定某个指令段的开始位置,需要DMALPEND指定该指令段的结束位置,一旦指定后,DMAC会循环执行介于DMALP于DMALPEND之间的指令,直到循环次数为0结束。
参数:
<loop_iterations> :这是一个8位表示的循环次数。
lc设置为0时,DMAC每写一次值,loop_iterations则减少1,直到循环计数为0结束。
lc设置为1时,DMAC每写一次值,loop_iterations则减少1,直到循环计数为1结束。
指令编码:
4.7 DMALPEND
指令格式:DMALPEND[S|B]
功能描述:该指令每次执行一遍以后查看循环计数寄存器的值,如果是 0,DMAC则执行DMANOP指令。如果不为0,DMAC则更新一次循环计数器的值,并跳转到循环指令段的第一条指令执。
[S] 如果S位被指定,则bs位被置0,且x转换为1。Request_flag将被下列情况所影响:
Request_flag=Single,DMAC则执行循环。
Request_flag=Burst ,DMAC执行空指令。
[B] 如果B位被指定,则bs被设置为1,且x转位1,Request_flag将被下列情况所影响:
Request_flag=Single, DMAC执行空指令。
Request_flag=Burst , DMAC将执行循环。
指令编码:
4.8 DMASEV
指令格式:DMASEV <event_num>
功能描述:使用该命令可以产生一个事件信号。可以有以下两种模式:产生一个事件<event_num>;产生一个中断信号,irq<event_num>。
参数:
<event_num> :5位立即数。
指令编码:
4.9 DMAEND
指令格式:DMAEND
功能描述:该指令用来通知DMAC结束一次操作集合,换句话说就是,告诉DMAC某个线程停止一切的动作,使其为停止态,这时DMAC会刷新MFIFO,并且清空所有相关的Cache。
指令编码:
五、其他寄存器
5.1 DBGINST0
此寄存器可控制调试指令,通道,DMAC线程信息。
5.2 DBGINST1
该寄存器控制内存中设置的指令段首地址,也就是DMAC第一次取指令的地址。
5.3 DBGCMD
该寄存器控制调试命令的执行,通过配置它,可以控制DMAC去执行一些指定的工作。