张为;胡晓楠;王晔
【摘 要】Aim at the serial communication with a large amount of data, the UART serial port send and received packets which is controlled by DMA controller, based on the conventional UART serial data communication and the DMA controller in the Cortex-M3 microcontroller is realized. The page realized the data transmission process in DMA scatter- gather mode ultimately by designing the list item cache, and emphasized the sending process.it improved the independence and the efficiency of the MCU in serial communication.%针对大数据量的串口问通信,在常规的UART串行数据通信的基础上,结合Cortex-M3微控制器中DMA控制器的作用,实现DMA控制的UART串口数据包收发。设计链表项缓存,最终实现DMA的分散,聚集模式的数据传输过程,主要是发送过程。提高了串行数据通信过程的MCU独立性和MCU利用的效率。
【期刊名称】《电子设计工程》 【年(卷),期】2012(020)006 【总页数】3页(P138-140)
【关键词】DMA;UART;链表项;分散,聚集 【作 者】张为;胡晓楠;王晔
【作者单位】华北计算机系统工程研究所,北京100083;华北计算机系统工程研究所,北京100083;华北计算机系统工程研究所,北京100083
【正文语种】中 文 【中图分类】TP302
常规下,UART的数据收发可由MCU控制UART的内部FIFO来完成。但具体不论是以中断还是以查询的形式,过程中总是会占用到MCU的时间,即便在其FIFO的最大有效利用时。这样,在实际应用中,当串口数据包量较大时,UART的发送过程会占用MCU很长时间,其中大多数时间可能是在一次等待数据传输的完成。为了节省这段时间,提高MCU的使用效率,以完成更多的数据处理,将会用到DMA控制器。DMA意思是直接内存访问,是指不经由CPU而直接从内存中存取数据的数据交换模式。当UART的使用DMA控制器控制发送过程时,MCU会将发送的控制权交给DMA硬件控制器,从而在数据发送的时间中去处理其它的事务。
本文将结合ARM的Cortex-M3内核处理器来设计UART的DMA控制过程。Cortex-M3内核的处理器,是ARM公司最新一代的ARMv7架构的32位处理器。其LPC176X系列的MCU处理器内部带有8通道的DMA控制器。下面将使用这些DMA控制器通道来实现UART的数据收发过程。 1 系统结构及原理 1.1 UART控制器
LPC176X有4路UART控制器,通过设置其波特率、停止位、数据长度等参数来完成2个UART串行口的通信,当然外部通过电平转换可实现为RS232或RS485等接口类型,这里只系统地用内的部UART接口。
硬件的连线上采用交叉互连,即一个UART接口的TX接到另一个接口的RX。软件上传输的数据报文格式可由不同应用不同设定,这里只笼统的称做数据包。
1.2DMA控制器
LPC176X的DMA控制器允许外设到存储器,存储器到外设,外设到外设和存储器到存储器之间的传输。每个DMA流都可以为单个源和目的提供单向串行DMA传输[1]。
1.3 链表项及其标识
DMA控制器使用链表项(LLI)来支持分散/聚集(Scattergather),分散/聚集是指DMA单次传输可以使用不必连续的内存空间,它的效果相当于若干个简单DMA过程的串连[2]。在分散/聚集模式下,源和目标数据区由一连串的链表来定义,每个链表项控制着一个数据块的传输,将这个数据块传输完毕后,选择并装载另一个链表项来继续DMA操作或停止DMA流。第一个链表项需要被编程到DMA控制器的对应通道。链表项所描述的传输数据包通常需要进行一次或多次DMA突发传输到设定的源或目标。如不需要链表项分散/聚集,那么链表地址寄存器须设置为零。一个链表的最后一个链表项也须设置为零。
一个链表项的内容由4个字组成,依次为源地址、目标地址、下个链表项地址及控制字。为了方便记录DMA链表内容,设计并定义一个链表内容结构体标识,标识名称记作stDMALinkListInfor[3],定义如下:
2 缓存区的设计
2.1 串行数据缓存区的设计
建立UARTn的接口数据缓存区,记作UARTn_BUF(n),用来存储UART串口数据包。为数据缓存区设置空缓存地址的FIFO队列UARTn_BUF_FREE_TABLE,用来存放未被数据填充占用的空数据缓存分区地址;设置已占用缓存地址的FIFO队列UARTn_BUF_FILL_TABLE,用来存放已经被数据填充占用的数据缓存分区地址[4]。
2.2 链表项缓存区的设计
建立N个DMAx的链表内容结构体的缓存区DMAx_LINK_LIST_INFOR_INDEX(i) (i=1,2,3,..N-1),称作 DMAx_LINK_LIST_INFOR_CACHE(i) (i=1,2,3,..N-1)。 其中 DMAx_LINK_LIST_INFOR_CACHE(i)的地址为4字节对齐,必须为最低2位是0的位置。 2.3 空链表项地址队列的设计
建立DMAx的可用空缓存FIFO队列,称作DMAx_LINK_LIST_FREE_TABLE,用于存储N个链表中的空缓存区地址。当执行出队操作时,返回一个非NULL空缓存区地址,若取回值为NULL则说明没有可用缓存区;而执行入队操作时,会将一个非NULL空缓存区的地址加入FIFO队列中,执行读取队列长度操作时,返回队列中可用空缓存地址的数量。 2.4 已占用链表项地址队列的设计
建立DMAx的链表地址FIFO队列,记作DMAx_LINK_LIST_FILL_TABLE,用来放置占用并填充了链表内容的结构体缓存区地址。当执行出队操作时,返回一个非NULL已占用缓存区地址,若取回值为NULL则说明没有可用的已占用缓存区地址;而执行入队操作时,会将一个非NULL已占用缓存区的地址加入FIFO队列中,执行读取队列长度操作时,返回队列中可用的已占用缓存地址数量。 2.5 发送用缓存地址保存队列的设计
建立UARTnTX的地址保存FIFO队列UART_LINK_LIST_STORE_TABLE,用于保存一次DMA发送的时所用到的DMAx_LINK_LIST_INFOR_CACHE地址。队列容量可与DMAx_LINK_LIST_FILL_TABLE的容量相同,或根据需求设置成更小。 3 串行通信程实现 3.1 关键寄存器设置
1)使能外设时钟,将PCONP寄存器中的PCGPDAM位置1。此位在复位时为0,
即默认DMA被禁止,所以在应用DMA前须先将其使能。
2)使能UnFCR中的第3位。该位为UART的DMA功能使能位,置1时使能DMA,清0后禁用DMA功能;只有在该位使能后,UART的发送和接收过程才能由DMA控制完成。
3)将寄存器DMAReqSel的相应位清零。比如第0位,因为DMA的UART0 TX与定时器0匹配0复用,所以需先选择到UART0 TX上。第0位为0时DMA选择UART0 TX,为1时DMA选择MAT0.0;其它串口也需做类似选择。 3.2 串行数据发送过程实现
UARTn的DMA数据发送过程如下:
1)轮询检测是否有数据需要UARTn的发送,如果有则从
UARTn_BUF_FREE_TABLE队列中取出一个UARTn_BUF缓存,填充欲发送的数据,然后从DMAx_LINK_LIST_FREE_TABLE队列中取出一个DMAx_LINK_LIST_INFOR_CACHE,将UARTn_BUF的地址赋给DMAx_LINK_LIST_INFOR_CACHE的LinkList_SrcAddress, 并 设 置 其LinkList_DstAddress为UnTHR的地址,LinkList_NextListAddress暂为 0、LinkList_Control Value为UARTn_BUF中数据大小、源和目的BURST SIZE为0、源和目的传输宽度的1字节、源地址自增、目标地址不自增和Terminal Count中断使能。最后将该DMAx_LINK_LIST_INFOR_CACHE值入队到DMAx_LINK_LIST_FILL_TABLE队列中[5-6]。 流程如图1所示。 图1 轮询检测过程Fig.1 Polling detection process
2)设置定时器UART_DMA_TX_TIMER,定时值为Ts,即每T秒定时器UART_DMA_TX_TIMER发生一次中断。中断服务为检查
DMAx_LINK_LIST_FILL_TABLE的队列长度L,判断是否有可用的链表地址。如果有,则执行出队操作取出一个缓存地址 FILL_CACHE_0,将 其入队到
UART_LINK_LIST_STORE_TABLE中。然后利用其中的源地址、目标地址和ControlValue值,将其分配给DMA通道x的相应寄存器。 若L>1, 则再取出一个地址, 入队到UART_LINK_LIST_STORE_TABLE,将其值赋给 DMAx的LLI寄存器。如果仍有可用链表地址,则取出,入队到
UART_LINK_LIST_STORE_TABLE,将其值赋给上一个链表地址中的LinkList_NextListAddress,然后依次类似操作,直到最一个取出后,将其LinkList_Next-ListAddress赋为0。若L=1,则将DMAx的LLI寄存器的值置为0。最后设置DMAx的Config寄存器,设置内容有目标外设为UART_TX、传送类型为MEMORY TO PERIPHERAL、不屏避Terminal Count中断、DMAx通道使能,启动DMAx传输。流程如图2所示。 图2 定时器发送过程Fig.2 Timer sending process
3)DMAx传输完成产生Terminal Count中断,在其中断服务程序中取出FIFO队列UART_LINK_LIST_STORE_TABLE中保存的地址ADDR,将ADDR中的源地址入队到UARTn空缓存队列,然后将ADDR值填充到DMAx的可用空缓存FIFO队列DMAx_LINK_LIST_FREE_TABLE中。流程如图3所示。 3.3 串行数据接收过程实现
图3 DMA结束过程Fig.3 DMA finishing process
UARTn的DMA数据发送过程相对于必送过程较为间单,在配置好相应的寄存器和目标缓存地址后,使能相应DMA通道。当UART接收数据达到触发点后,会触发DMA相应通道的突发请求进行传输。传输结束后,在Terminal Count中断服务中更换目标缓存地址,使能一轮即可。当然在配置中,DMA通道的突发个数应设置与UART接收FIFO触发点数相同。 4 结束语
在DMA发送进行的过程中,UART_LINK_LIST_STORE_TABLE保存的地址值序
列ADDRs中的地址所指空间不能被释放或被其它程序占用,同样的ADDRs中地址的源地址所指的UART缓存空间也不能被释放或被其它程序占用。如果在这个过程中出现了不满足上述要求的情况,则会出现不可预测的错误。 参考文献:
【相关文献】
[1]宋岩.ARM Cortex-M3权威指南[M].北京:北京航空航天大学出版社,2009.
[2]NXP Semiconductors.LPC17XX User manual[EB/OL].[2010-08].http://www.nxp.com. [3]谭浩强.C程序设计[M].北京:清华大学出版社,1991. [4]Reek K A.C和指针[M].北京:人民邮电出版社,2008.
[5]沈建华.ARM嵌入式系统开发-软件设计与优化[M].北京:北京航空航天大学出版社,2005. [6]赵亮,候国锐.单片机C语言编程与实例[M].北京:人民邮电出版社,2003.
因篇幅问题不能全部显示,请点此查看更多更全内容