我目前在进行Yocto Linux构建,并尝试与FPGA上的硬件块进行接口。该块模拟带有FAT16文件系统的SD卡; 包含一个单一的文件(cam.raw)。该文件表示FPGA和Linux系统之间的共享内存空间。因此,我想能够从Linux系统向此内存中写入数据,并获得FPGA可能进行的任何更改(当前,FPGA仅从内存空间获取部分数据,并将32位字的LSB加6,例如我写入0x40302010,如果我读回数据,则应该得到0x40302016)。但是,由于某些缓存存在,虽然我可以将数据写入FPGA,但我无法立即获得结果。
我目前正在做类似这样的事情(使用Python因为它很容易):
我可以确认使用SignalTap/ChipScope工具对FPGA进行检测时,数据确实已更改(尽管我经常遇到缓冲问题)。在这种情况下,第一个32位字是0x03020106。然而,无论是Python还是Linux(或者两者都有)都会缓存文件并且不会从“SD卡”(FPGA)读取文件,而是将文件数据存储在内存中。我需要彻底关闭这一点,使得所有的读操作都来自于FPGA;但我不确定缓冲正在哪里发生或如何做到这一点。
非常感谢任何想法!(注意,我可以使用mmap.flush()将我从Python编写的任何数据转储到FPGA上,但我需要一种相反的刷新或某种方式来重新读取mmap中的文件数据!)
更新:
正如评论中建议的那样,mmap方法可能不是实现我所需的最佳方法。然而,我现在已经尝试了Python和C语言的基本I/O函数(在Python中使用os.read/write,在C中使用read/write),并使用了O_DIRECT标志。在大多数情况下,我最终得到了errno 22。仍在研究中...
我目前正在做类似这样的事情(使用Python因为它很容易):
% mount /dev/mmcblk1 /memstick
% python
>> import mmap
>> import os
>> f = os.open("/memstick/cam.raw", os.O_RDWR | os.O_DIRECT)
>> m = mmap.mmap(f, 0)
>> for i in xrange(1024):
... m[i] = chr(i % 256)
...
>> m.flush() # Make sure data goes from linux to FPGA
>> hex(ord(m[0])) # Should be 0x6
'0x0'
我可以确认使用SignalTap/ChipScope工具对FPGA进行检测时,数据确实已更改(尽管我经常遇到缓冲问题)。在这种情况下,第一个32位字是0x03020106。然而,无论是Python还是Linux(或者两者都有)都会缓存文件并且不会从“SD卡”(FPGA)读取文件,而是将文件数据存储在内存中。我需要彻底关闭这一点,使得所有的读操作都来自于FPGA;但我不确定缓冲正在哪里发生或如何做到这一点。
非常感谢任何想法!(注意,我可以使用mmap.flush()将我从Python编写的任何数据转储到FPGA上,但我需要一种相反的刷新或某种方式来重新读取mmap中的文件数据!)
更新:
正如评论中建议的那样,mmap方法可能不是实现我所需的最佳方法。然而,我现在已经尝试了Python和C语言的基本I/O函数(在Python中使用os.read/write,在C中使用read/write),并使用了O_DIRECT标志。在大多数情况下,我最终得到了errno 22。仍在研究中...
/dev/mmcblk1
上使用mmap()
,自己解析文件系统,或者向内核专家寻求帮助。 - Dietrich EppO_DIRECT
不能使用的原因是,O_DIRECT
基本上是一个绕过页面缓存的指令,而mmap()
是一个用于将页面缓存公开给程序的函数,因此它们在逻辑上不兼容。 - Dietrich Eppmmap.flush
方法强制将内存缓冲区与实际磁盘同步。但我不确定这对您的问题是否足够——如果任何内存页面是脏的,它们会覆盖磁盘上的任何内容,而不是相反。 - abarnert