大家好!
我最近的项目用am335x同fpga通信,最后初始化GPMC的CS2片选bank同fpga通信,初始化使用16bit位宽,AD multi,Read single ASynchronous和Write single ASynchronous的方式。最后使用linux的read、write同fpga通信,最后测试用read或者write往fpga某个地址读和写没有任何问题,用示波器测试也看到波形正确。但是由于应用的原因,fpga那边定义了一些列的结构体来标注地址结构的功能。为了方便我在linux上使用mmap映射,将同fpga cs2的bank映射为Qt中能使用的一个指针(pFPGA),但是我用这个指针去读和写就出现问题了。
比如:我unsigned int id=pFPGA->id;这样读一个32bit的数据,读的数据是正确的,但是使用示波器抓取波形发现am335x的gpmc竟然发送了32次读的时序(实际上是连续读取了16个32bit,两次16bit的读取合成一个32bit)。
写的时候多次写,pFPGA->id=0x55aa;pFPGA->id1=0xaa55;只有最后一次pFPGA->id1=0xaa55才是有效的写,前面pFPGA->id=0x55aa时序上根本就没有
如果改为pFPGA->id=0x55aa;msync((void*)pFPGA, 4, MS_SYNC);
pFPGA->id1=0xaa55;msync((void*)pFPGA, 4, MS_SYNC);
的时候示波器抓取可以看到两次写数据,并且写的时序没有问题。
为什么会这样,写可能要使用msync来同步这个还好理解,但是读为什么要连续读取32次。我确定我时序寄存器配置没有问题,用文件read和write的方式没有任何问题。为什么使用mmap就有问题。到底是我配置有疏忽的地方,还是mmap的方式linux操作系统有缓存的机制还是怎么的?麻烦有知道的朋友出个主意,谢谢了。
Jian Zhou:
我看你有个描述,QT应用,FPGA的读写应该是驱动完成的,怎么会和QT相关呢?
shi shu1:
回复 Jian Zhou:
问题描述可能有问题,我不用QT也会有这个问题。主要是我如果不适用mmap映射使用普通的char设备驱动的read和write读写fpga,一切都正常。但是使用mmap映射的方式去读写fpga会出现,读一个字节(32bit)会在总线时序上读取32次16bit(fpga的总线是16bit)也就是连续读取16个字。并且mmap方式写必须在最后使用sync方式,才能将最后一个字写进去(如果连续的写两个字,sync后只是最后一个字实际写了进去)。但是使用char设备驱动的读和写都正常。不知道是linux下的mmap驱动自己缓存IO操作还是到底我驱动初始化的时序有问题。
Denny%20Yang99373:
回复 shi shu1:
看看是不是CACHE的原因
shi shu1:
回复 Denny%20Yang99373:
我也在想是不是linux cache的原因,但是mmap映射的时候页映射都是带缓冲的,不知道怎么申请不带缓冲的IO内存映射的申请。望linux高人能够解答,谢谢。
还有自己目前是用char设备read和write方式实现了驱动,暂时没有问题。但是感觉用mmap映射才是最完美的方式。还是感谢论坛的各位。
Denny%20Yang99373:
回复 shi shu1:
http://blog.csdn.net/g_salamander/article/details/8097703
Jian Zhou:
回复 Denny%20Yang99373:
GPMC的空间访问,一般都是驱动初始化时将地址空间mmap出来,然后直接进行读写。