您的位置: OpenADSP社区论坛 -> Blackfin专区 -> 技术讨论区 -> [讨论]Blackfin DMA方式读取外部8位大容量N... 
本帖共有528个阅读者
发表帖子 发表投票 回复主题
[讨论]Blackfin DMA方式读取外部8位大容量Nandflash疑问 请问andy前辈
lvben5d(论坛新手)
lvben5d
头衔:社区公民
帮派:无帮无派
帖数:61
金钱:672
积分:89
注册时间:2014/3/24
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
[讨论]Blackfin DMA方式读取外部8位大容量Nandflash疑问 请问andy前辈
参考手册Blackfin 访问外部NandFlash 有2种基本方式:1.直接读取,适合非整页,速度大概只有DMA一半,且占用CPU时间很多,也就是会阻塞线程。
2. DMA方式,最小读取单位为page。 我在实际使用中,比如读取1个BLOCK代码如下
  aNFDAddress.callbackparamter = NULL; //这里必须为空,前63次读取不会进入回调~~!!
  for(n=0; n<64; n++)
  {  
     if(n==63) aNFDAddress.callbackparamter = XX;//这里一定要把回调参数设置非空,最后1次DMA请求后,才会进去回调函数!!!
     adi_dev_Control(nfc_handle, ADI_NFC_CMD_NFD_ACCESS_REQUEST, (void *) aNFDAddress);//输入block page 地址的结构体
     adi_dev_Read   (nfc_handle, ADI_DEV_1D,  (ADI_DEV_BUFFER*)&buf); //输入接收缓冲区 并启动DMA转换
     aNFDAddress的页地址++;//访问下一page
     buf +=  Page_Size;     //1维数组指针指推移1page 用于接收下一page的数据
   }
/***********/
回调函数
callback()... //只有1个判断语句  而且前63次的回调参数都是NULL 不会进回调(由API内部机制实现)。

   如上所述,由于访问外部Nandflash是需要时间的,而我的adi_dev_Read 后面的代码只有几条,for循环不断的在 REQUEST 和 READ 每执行完1次DMA 就会进回调。我们要求DMA去从Nandflash 速度远大于代码执行,因为page为2K,而我访问外部Nandflash的速度为 4MB/S 2K字节大约需要万分之5秒 就是0.5ms = 500ns ,CPU的主频是533MHZ。假设执行1条++指令 需要1个时钟周期,大约也就是 2ns 。
2个++指令和进入回调函数执行的代码条数 小于20条 那么就会出现前1次DMA没有结束,新的DMA请求就可能触发了,请问andy帅哥 这个Blackfin的 Nandflash 是否有FIFO机制 ,因为对于我们用户来说,我们在API手册只看到例子是 Control 接着 Read ...

推断: 我觉得Blackfin的Nandflash的这两个函数已经做了各种考虑,用户在进入回调函数里,做标记即可。这样NANDFLASH 也出于可再次访问状态。


「该帖子被 lvben5d 在 2014-04-04 11:45:28 编辑过」

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2014/3/28 8:32:53
lvben5d(论坛新手)
lvben5d
头衔:社区公民
帮派:无帮无派
帖数:61
金钱:672
积分:89
注册时间:2014/3/24
1信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
刚才回去看了下NANDFLASH的API手册,发现有一个ADI_NFC_MDA_FRAME_BUFFER ,不强制使用,但是使用的话会提高DMA访问NANDFLASH 3到5倍的性能,这个ADI_NFC_MDA_FRAME_BUFFER 为2个成员变量的结构体,
typedef struct  ADI_NFC_MDA_FRAME_BUFFER
{
   void *pDMAFrameMemory;
   u8   NumDMAFrame;       // == PageSize/8
}
莫非这个就是提供给API库调用的FIFO ?

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2014/3/28 10:18:30
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
2信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
通常每个数据接口都有FIFO,但容量都不大,实际就是你看到的他的数据传输或者接受的寄存器的容量。在你使用DMA访问时,这个FIFO不再使用,而是使用DMA的fifo。
硬件读取nand的时间,用理论值计算也不一定准确,通常都是大于理论值,因为硬件访问时会遇到一些状态判断,可能在读取数据时,会等待这个标志位。建议你加个判断DMA传输完成,完成传输后再进行第二次传输。

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2014/3/30 10:11:07
lvben5d(论坛新手)
lvben5d
头衔:社区公民
帮派:无帮无派
帖数:61
金钱:672
积分:89
注册时间:2014/3/24
3信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
ANDY说的对,我们可以自己加个标志去判断传输完成标志,如果没有完成,就一直等待。
读最后一页的时候,我们可以把回调参数赋为非NULL,然后再回调函数里判断是否为NULL来处理最后一页读完的确定。

但按照我目前实际使用的情况,for循环64次访问外部64page of NANDFLASH 没有出现丢页问题。 推断这样的速度应该是最快的:for循环里处理计数器叠加,DMA在传输数据,当我们下一次启动DMA访问请求的时候,API函数adi_dev_Control(nfc_handle, ADI_NFC_CMD_NFD_ACCESS_REQUEST, (void *) aNFDAddress)的内部可能会判断前一次DMA是否完成,如果没有完成,会一直等待完成标记。或是当adi_dev_Read的时候,才去判断前一次DMA传输是否完成,以便启动新一次的DMA传输。
AD的API函数装了太多内部信息,也没找到指导手册告知我们,说不定内部就有这种DMA传输是否完成的标记以及访问超时处理(毕竟外部NANDFLASH要是挂了,不就没有时序应答了^_^)。

由于提供了 ADI_NFC_MDA_FRAME_BUFFER 这个结构体,里面有个 u8   NumDMAFrame; // == PageSize/8
DMA帧数。这个就值得去推敲了,手册告诉我们DMA必须以一页为单位进行访问,这里为何分成8帧?
可能 NANDFLASH的数据流配置为 CHAINED时,只有当我们回调参数非空,API函数才认为这个是最后1次调用!目前我的结果是这样。


「该帖子被 lvben5d 在 2014-04-09 19:28:49 编辑过」

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2014/3/31 14:26:25
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
4信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
不清楚,没研究过。

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2014/4/4 10:34:13
Powered by OpenADSP Copyright © 2010 www.Openadsp.com. All rights reserved.154207 Call, 1 Queries, Processed in 0.031250 second(s),