长时间连续dma传输的缓冲区管理的软件实现方法

文档序号:6385426阅读:234来源:国知局
专利名称:长时间连续dma传输的缓冲区管理的软件实现方法
技术领域
本发明属于数据采集领域,特别涉及一种长时间连续的DMA传输的缓冲区管理的软件实现方法。
背景技术
DMA (Direct Memory Access,直接内存存取)是现代计算机的重要特色,被广泛用于数据采集领域。DMA是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用DMA传输机制可以大大提高与设备通信的吞吐量。缓冲区是计算机内存中用于存放采样数据的临时存储区,缓冲区从计算机内存中分配出来,对于连续的DMA传输过程中,仪器设备可能一直连续工作,需传输的数据量不断增加,一次性开辟缓冲区是不可能满足需求的。而且重复循环读写一块缓冲区,还有可能会因为读写速率的不一致产生数据覆盖的或使用效率不高的问题。

发明内容
有鉴于此,本发明提出了一种长时间连续DMA传输的缓冲区管理方法,一次性开辟缓冲区大小,缓冲区的读方和写方循环且长时间使用该缓冲区,长时间读写不会产生数据覆盖或使用效率不高问题,以满足用户长时间DMA使用的需求。为了解决上述技术问题,本发明是这样实现的一种长时间连续DMA传输的缓冲区管理方法,包括如下步骤首先定义如下参数preDMA_sta为DMA传输过程中上一次写到的数据量,初始值为O ;curDMA_sta为DMA传输过程中实际已写的数据量,初始值为O ; curDMA_sta和preDMA_sta采用相同位数的无符号整形;DMAtemp为中间变量,初始值为O ;LsLoop为缓冲区被循环的次数,初始值为O ;当curDMA_sta溢出后,LsLoop被清零;Rtime为缓冲区被Size大小分块读的次数,初始值为O;当读操作跨越了缓冲区的首尾时,Rtime被清零;Max为curDMA_sta在不溢出情况下的最大值;Rtemp为中间变量,记录数据类型溢出时,缓冲区已被块读过的次数,初始值为O ;Datatemp为中间变量,初始值为O,记录读操作跨越缓冲区首尾时,从缓冲区首部读取的数据量;flag2表示每次从缓冲区中读数据的起始位置;flag4为缓冲区的初始地址;设定缓冲区的大小为LSize,每次读数据的个数为Size, Size<LSize ;读缓冲区方处理流程包括如下步骤f 14 ;
步骤1、DMA传输开始后,读缓冲区方查询当前缓冲区已写数据量curDMA_sta ;该curDMA_sta从写缓冲区方的硬件获得;步骤2、判断上次写到的数据量preDMA_Sta是否大于实际已写数据量curDMA_sta ;如果是,则执行步骤3,否则,执行步骤Γ8 ;步骤3、判定curDMA_Sta数据类型溢出,计算当前缓冲区中未被读取的数据量DMAtemp=Max+curDMA_sta-preDMA_sta ;并且更新 LsLoop=O, Rtemp=Rtime ;执行步骤 9。步骤4、判定curDMA_Sta数据类型未溢出,计算当前缓冲区中已写的数据量DMAtemp=curDMA_sta,执行步骤 5 ;步骤5、判断是否Rtemp=O,如果是,则执行步骤9,否则执行步骤6 ;步骤6、判断是否Rtime=O,如果是,则执行步骤7,否则执行步骤8 ;步骤7、令Rtemp=O,转入步骤9 ;步骤8、令Rtemp值不变,转入步骤9 ;步骤9、判断是否满足(DMAtemp-LsizeXLsLoop) ^ (Rtime-Rtemp+1) XSize,如果是,则确定缓冲区中的数据达到Size,则执行步骤10 ;否则,返回步骤I ;步骤10、令 preDMA_sta=curDMA_sta,且令 Rtime 自加 I ;步骤11、计算下一次读的起始地址flag2+Size是否大于LSize ;如果是,则执行步骤12;否则,执行步骤13;
步骤12、先从flag2开始读Lsize-Datatemp-RtimeXSize个数据,再从缓冲区初始地址 flag4 读取 Size- (Lsize-Datatemp-RtimeX Size)个数据,将 Datatemp 赋值为 Size- (Lsize-Datatemp-RtimeX Size);然后令 LsLoop 自加 I,更新 Rtime=O, flag2=flag4+[Size- (Lsize-Datatemp-RtimeX Size)],转至步骤 14 ;第一次读取时,flag2=flag4 ;步骤13、从flag2开始读Size个数据,flag2自增Size ;转至步骤14。步骤14、判断DMA传输是否结束,如果是,则退出本流程,否则,返回步骤I继续循环;写缓冲区方处理流程写缓冲方从flag4开始不断向缓冲区写入数据,并根据读缓冲方发来的flag2的位置,确保写缓冲位置不超过flag2。综上,本发明提出了一种长时间连续采集的DMA缓冲区管理方法。该方法的有益效果是,具有通用性,适用任意数据量的DMA传输应用;具有灵活性,降低DMA传输应用对计算机配置的依赖;缓冲区循环使用,可满足用户长时间DMA使用的需求。此外,本发明还考虑到了溢出问题,采用绝对位置计算读写位置,提高了整个连续传输过程的稳定性。


图1为DMA传输缓冲区读写示意图。图2为本发明缓冲区读操作流程图。
具体实施例方式本发明为实现上述目的,采用如下技术方案本发明有三个技术点
1、连续传输过程中缓冲区大小的确定由于DMA数据传输过程中,若写缓冲区的速度很快,缓冲区开辟不够大,则容易造成写缓冲区方中用于存储数据的FIFO溢出,使写缓冲区方仪器工作异常;若缓冲区开辟过大,在内存和硬盘之间产生过量的读写操作时,会对系统性能造成影响。为了保证写缓冲区方FIFO中存储的数据能够在溢出前被传输到DMA缓冲区内,本发明以写缓冲区方完成一次数据采集和处理操作周期Tl为基础,将该时间乘以10,将10XT1假定为写缓冲区方向缓冲区进行写操作的周期的上限,则开辟的缓冲区大小为10XTl,单位为系统数据位宽。例如系统读写数据位宽为32位字节,则这里单位为32位字节。通过合理的缓冲区大小,在不同的写缓冲区速率的情况下,能保证向缓冲区内读数据速度比写速度快,而且不造成内存空间的浪费。2、保证缓冲区循环使用对于长时间连续运行的DMA传输,需要实现缓冲区的循环使用,即不断的写、读同一块缓冲区。若写和读之间没有约束,有可能写的速度过快,还没有来得及把缓冲区中的数据读走,写就将先前的写数据覆盖了 ;若读的过快,缓冲区中写数据未来得及更新,读走的可能是以往的数据;同时,在缓冲区循环使用时,若读、写完设定大小的缓冲区后,不能重新读、写缓冲区,也会造成错误。这三种情况下,数据传输的结果都是不可靠的。因此应当制定合理的缓冲区循环使用的方法,以确保长时间连续的DMA传输的正确性、可靠性。参见图1,设计的方法如下设定缓冲区的大小为LSize,每次读数据的个数为Size, Size<LSize,并在缓冲区中设置3个标志位flagl、flag2、flag4,其中,flagl表示写数据的当前位置,flag2表示读数据的当前位置,flag4表示缓冲区的开始位置。为了提高缓冲区利用率,写缓冲区方和读缓冲区方均根据上述标识位进行读写操作写缓冲区方从flag4开始持续写缓冲区;在写过程中,flagl不断变化,但不能超过flag2,否则将覆盖未读数据。读缓冲区方每Size个数据块读缓冲区一次。在读过程中,读缓冲区方定期查询缓冲区内当前可读的数据量,当根据flagl和flag2之间的差距判定缓冲区内未读数据已经达到Size,则读缓冲区方便可从缓冲区中连续读取Size个数据。在写缓冲区过程中,当达到缓冲区的最大地址时,将调过头来从初始地址flag4重新写缓冲区,在读缓冲区过程中,读数据地址达到最大地址时,也会调过头来从初始地址flag4开始读,依次反复实现连续的DMA传输,缓冲区实现循环利用。3、保证长时间连续传输能够保证在循环过程中flagl、flag2的位置相应位置关系可靠是非常重要的。但是这三个量均在缓冲区中的相对位置量,容易产生计算失误。因此如果能采用绝对位置去实时更新相对位置,将会提高整个连续传输过程的稳定性。在这2个位置中,flag2可以从flag4开始起算,每读一次增加Size,但是flagl的更新需要依赖实际向缓冲区写了多少数,也就是DMA传输过程中已写的数据量curDMA_sta,该数据量可以由写缓冲区方的硬件告知的,每次通过这个数判定flagl的真实位置。但是,在记录数据量的过程中,由于定义数据量的数据类型可能是16位整形,也可能是32位整形,由于长时间传输,数据量很大(可能趋向正无穷),因此需要记录的数据量达到溢出边沿时,需重新记录。curDMA_sta也就会出现同样的问题,假设curDMA_sta为32位无符号整形,最大可记录4294967296个数,当传输的数据个数超过4294967296时,就会溢出。此时,当判断curDMA_sta达到4294967296时,需要重零开始记录数据,此时根据curDMA_sta确flagl的位置时,需要特殊考虑。基于上述3点,下面针对读缓冲区方和写缓冲区方的具体流程进行描述。首先定义如下参数preDMA_sta为DMA传输过程中上一次写到的数据量,初始值为O ;curDMA_sta为DMA传输过程中实际已写的数据量,初始值为O ; curDMA_sta和preDMA_sta采用相同位数的无符号整形,本实施例中,被定义为32位无符号整型;DMAtemp为中间变量,初始值为O ;LsLoop为缓冲区被循环的次数,初始值为O ;当curDMA_sta溢出后,LsLoop应当
被清零;Rtime为缓冲区被Size大小分块读的次数,初始值为O;当读操作跨越了缓冲区的首尾时,Rtime被清零;4294967295为curDMA_sta被定义为32位无符号整型的最大值;Rtemp为中间变量,记录数据类型溢出时,缓冲区已被块读过的次数,初始值为O。Datatemp为中间变量,初始值为O,记录读操作跨越缓冲区首尾时,从缓冲区首部读取的数据量。读缓冲区方处理流程,参见图2 :步骤1、DMA传输开始后,读缓冲区方查询当前缓冲区已写数据量curDMA_sta。curDMA_sta从写缓冲区方的硬件获得,是一个准确的数据。步骤2、判断上次写到的数据量preDMA_Sta是否大于实际已写数据量curDMA_sta ;如果是,则执行步骤3,否则,执行步骤4 8。上次写到的数据量preDMA_sta是在每次读操作时被更新的,由于DMA读写操作是同时的,而且很快,因此所述更新是将curDMA_sta的值赋给preDMA_sta。因此,在正常情况下,preDMA_sta=curDMA_sta,但是当curDMA_sta溢出时,而preDMA_sta还未被更新时,就会出现preDMA_sta较大的情况,此时由于curDMA_sta的溢出,将导致后续计算上需要特殊处理,因此这里分情况讨论。当preDMA_sta被再次赋予curDMA_sta的值后,preDMA_sta又会恢复与curDMA_sta相等了。步骤3、判定curDMA_sta数据类型溢出,计算当前缓冲区中未被读取的数据量DMAtemp=4294967295+curDMA_sta-preDMA_sta ;并且更新 LsLoop=O, Rtemp=Rtime ;执行步骤9。从本步骤可以看出,该分支中DMAtemp记载的是缓冲区中未被读取的数据量,不是一个数据所在位置的相对量,而是未被读取数据的绝对量,不考虑其位置。Rtemp记载的是数据溢出时Rtime的值。步骤4、判定curDMA_Sta数据类型未溢出,计算当前缓冲区中已写的数据量DMAtemp=curDMA_sta,执行步骤 5 ;本步骤中DMAtemp的含义与步骤3不同,其记载的是溢出之前,共写入了多少数据,是一个绝对量,其包含了已读和未读的数据部分。
步骤5、判断是否Rtemp=O,如果是,则执行步骤9,否则执行步骤6。步骤6、判断是否Rtime=O,如果是,则执行步骤7,否则执行步骤8。步骤7、令Rtemp=O,转入步骤9。步骤8、令Rtemp值不变,转入步骤9。以上步骤5 8表明了几种情况①从步骤5直接到步骤9,在缓冲区的循环读取过程中,还未出现溢出,此时保持Rtemp=O,进入步骤9 ;②从步骤5经历步骤6、7到步骤9,在缓冲区的循环读取过程中,刚刚出现了溢出,而且上一次读取操作跨越了缓冲区首尾,因此Rtemp应该被更新为0,进入步骤9 ;③从步骤5经历步骤6、8到步骤9,在缓冲区的循环读取过程中,刚刚出现了溢出,而且上一次读取操作还未从缓冲区尾部循环到缓冲区首部,因此Rtemp值应保持为溢出时的Rtime值,进入步骤9 ;步骤9、判断是否满足(DMAtemp-LsizeXLsLoop) ^ (Rtime-Rtemp+1) XSize,如果是,则确定缓冲区中的数据达到Size,则执行步骤10 ;否则,返回步骤1,以等待写数据量的增加。 本步骤的判断公式适用于curDMA_sta溢出和未溢出两种情况当curDMA_sta 溢出时,(DMAtemp-LsizeXLsLoop)中的 LsLoop 被清零,因此其计算的是未被读取的数据量;而(Rtime-Rtemp+1) X Size中的Rtime=Rtemp,则(Rtime-Rtemp+1) XSize=Size,因此其计算出的是一个Size的量,那么本步骤是判断当前未被读取的数据量是否达到Size。当curDMA_sta未溢出时,不等式左侧(DMAtemp-Lsize X LsLoop)计算的是写数据实际到达缓冲区哪个位置,不等式右侧计算的是之前读取到的最后位置加上一个Size。那么本步骤也是判断当前未被读取的数据量是否达到Size。步骤10、令 preDMA_sta=curDMA_sta,且令 Rtime 自加 I。Rtime 的值是从 O 开始的,因此在真正读之前将Rtime加I。步骤11、计算下一次读的起始地址flag2+Size是否大于LSize ;如果是,则说明当前待读数据块跨越了缓冲区的首尾,属于图1 (d)的情况,执行步骤12 ;否则,执行步骤13。步骤12、先从flag2开始读Lsize-Datatemp-RtimeXSize个数据,再从缓冲区初始地址 flag4 读取 Size- (Lsize-Datatemp-RtimeX Size)个数据,将 Datatemp 赋值为 Size-(Lsize-Datatemp-RtimeXSize),从而实现了整个数据块的读取;然后令LsLoop自加I,更新 Rtime=O, flag2=flag4+[Size- (Lsize-Datatemp-RtimeXSize)],转至步骤 14 ;第一次读取时,flag2=flag4。步骤13、从flag2开始读Size个数据,flag2自增Size ;转至步骤14。步骤14、判断DMA传输是否结束,如果是,则退出本流程,否则,返回步骤I。写缓冲区方处理流程写缓冲方不断向缓冲区写入数据,并根据读缓冲方发来的flag2的位置,确保写缓冲位置不超过flag2。综上所述,以上仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
权利要求
1.一种长时间连续DMA传输的缓冲区管理方法,其特征在于,包括 首先定义如下参数 preDMA_sta为DMA传输过程中上一次写到的数据量,初始值为O ;curDMA_sta为DMA传输过程中实际已写的数据量,初始值为O ;curDMA_sta和preDMA_sta采用相同位数的无符号整形; DMAtemp为中间变量,初始值为O ; LsLoop为缓冲区被循环的次数,初始值为O ;当curDMA_sta溢出后,LsLoop被清零;Rtime为缓冲区被Size大小分块读的次数,初始值为O ;当读操作跨越了缓冲区的首尾时,Rtime被清零; Max为curDMA_sta在不溢出情况下的最大值; Rtemp为中间变量,记录数据类型溢出时,缓冲区已被块读过的次数,初始值为O ;Datatemp为中间变量,初始值为0,记录读操作跨越缓冲区首尾时,从缓冲区首部读取的数据量; flag2表示每次从缓冲区中读数据的起始位置; flag4为缓冲区的初始地址; 设定缓冲区的大小为LSize,每次读数据的个数为Size, Size<LSize ; 读缓冲区方处理流程包括如下步骤广14 ; 步骤1、0祖传输开始后,读缓冲区方查询当前缓冲区已写数据量(311^)祖_^&;该curDMA_sta从写缓冲区方的硬件获得; 步骤2、判断上次写到的数据量preDMA_Sta是否大于实际已写数据量CurDMA_Sta ;如果是,则执行步骤3,否则,执行步骤Γ8 ; 步骤3、判定curDMA_sta数据类型溢出,计算当前缓冲区中未被读取的数据量DMAtemp=Max+curDMA_sta-preDMA_sta ;并且更新 LsLoop=O, Rtemp=Rtime ;执行步骤 9。
步骤4、判定curDMA_Sta数据类型未溢出,计算当前缓冲区中已写的数据量DMAtemp=curDMA_sta,执行步骤 5 ; 步骤5、判断是否Rtemp=O,如果是,则执行步骤9,否则执行步骤6 ; 步骤6、判断是否Rtime=O,如果是,则执行步骤7,否则执行步骤8 ; 步骤7、令Rtemp=O,转入步骤9 ; 步骤8、令Rtemp值不变,转入步骤9 ; 步骤 9、判断是否满足(DMAtemp-Lsize X LsLoop) ^ (Rtime-Rtemp+1) X Size,如果是,则确定缓冲区中的数据达到Size,则执行步骤10 ;否则,返回步骤I ; 步骤 10、令 preDMA_sta=curDMA_sta,且令 Rtime 自加 I ; 步骤11、计算下一次读的起始地址flag2+Size是否大于LSize ;如果是,则执行步骤12;否则,执行步骤13; 步骤12、先从flag2开始读Lsize-Datatemp-RtimeXSize个数据,再从缓冲区初始地址 flag4 读取 Size- (Lsize-Datatemp-Rtime X Size)个数据,将 Datatemp 赋值为 Size-(Lsize-Datatemp-RtimeX Size);然后令 LsLoop 自加 I,更新 Rtime=O, flag2=flag4+[Size-(Lsize-Datatemp-RtimeX Size)],转至步骤 14 ;第一次读取时,flag2=flag4 ; 步骤13、从flag2开始读Size个数据,flag2自增Size ;转至步骤14。步骤14、判断DMA传输是否结束,如果是,则退出本流程,否则,返回步骤I继续循环; 写缓冲区方处理流程 写缓冲方从flag4开始不断向缓冲区写入数据,并根据读缓冲方发来的flag2的位置,确保写缓冲位置不超过flag2。
2.如权利要求1所述的方法,其特征在于,该方法进一步包括确定连续传输过程中缓冲区的大小为以写缓冲区方完成一次数据采集和处理操作周期T1为基础,开辟的缓冲区大小为10 X T1,单位为系统的数据位宽。
全文摘要
本发明公开了一种长时间连续DMA传输的缓冲区管理方法,该方法支持缓冲区的读方和写方循环且长时间使用该缓冲区,不会产生数据覆盖或使用效率不高问题。将以写缓冲区方完成一次数据采集和处理操作周期T1为基础,开辟的缓冲区大小为10×T1;定义缓冲区的3个标志位,flag1为写数据的当前位置,flag2为读数据的当前位置,flag4为缓冲区的开始位置。写缓冲区方从flag4开始持续写缓冲区,写位置不能超过flag2;在读过程中,读缓冲区方定期查询缓冲区内当前可读的数据量,当根据flag1和flag2之间的差距判定缓冲区内未读数据已经达到Size,便从缓冲区中连续读取Size个数据。
文档编号G06F9/44GK103064679SQ201210572379
公开日2013年4月24日 申请日期2012年12月25日 优先权日2012年12月25日
发明者张伟楠, 许崴稚, 邹璞, 储艳丽, 杨立杰, 史雄伟 申请人:北京航天测控技术有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1