禁用特定文件(Linux)上的缓存/缓冲区

时间:2015-04-28 21:14:35

标签: python linux file hardware-programming fat16

我目前正在使用Yocto Linux构建,并尝试与FPGA上的硬件块进行交互。该模块正在模仿带有FAT16文件系统的SD卡;包含单个文件(cam.raw)。该文件表示FPGA和Linux系统之间的共享内存空间。因此,我希望能够将来自linux系统的数据写入该存储器并获取FPGA可能做出的任何更改(目前,FPGA只是从存储空间中获取部分数据并将其添加到数据库的LSB中。 32位字,就像我写0x40302010,如果我读回数据,应该返回0x40302016)。但是,由于某些地方的缓存,虽然我可以将数据写入FPGA,但我无法立即取回结果。

我目前正在做这样的事情(使用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'

我可以用dd确认数据是否已更改(虽然我经常遇到缓冲问题)并使用FPGA工具(SignalTap / ChipScope),我确实得到了正确答案(即前32位)这种情况下的位字是0x03020106)。然而,有人,无论是python还是linux或两者都在缓冲文件而不是从" SD卡中读取" (FPGA)再次将文件数据存储在存储器中。我需要完全关闭它,所以所有读取都会导致FPGA读取;但我不知道缓冲发生在哪里或者怎么做。

任何见解都将不胜感激! (注意,我可以使用mmap.flush()来获取我从python写入的任何数据以将其转储到FPGA中,但是我需要像反向刷新或其他东西让它将文件数据重新读入mmap!)

更新

正如评论中所建议的那样,mmap方法可能不是实现我需要的最佳方法。但是,我现在已经在python和C中尝试过,但是使用O_DIRECT标志使用基本的I / O函数(python中的os.read/write,C中的读/写)。对于大多数这些操作,我最终得到了错误22.仍在调查....

1 个答案:

答案 0 :(得分:0)

在挖掘之后,我发现了我在O_DIRECT标志上做错了什么。在我的C和Python版本中,我没有使用memalign来创建缓冲区而且没有进行块读/写。这篇文章有一个很好的解释:

How can I read a file with read() and O_DIRECT in C++ on Linux?

所以,为了实现我的目标,这个C程序就是一个基本的例子:

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

#define BLKSIZE 512

int main() {
  int fd;
  int x;
  char* buf;

  fd = open("/home/root/sd/fpga/cam.raw", O_RDWR | O_SYNC | O_DIRECT);
  if (!fd) {
    printf("Oh noes, no file!\n");
    return -1;
  }

  printf("%d %d\n", fd, errno);

  buf = (char*) memalign(BLKSIZE, BLKSIZE*2);

  if (!buf) {
    printf("Oh noes, no buf!\n");
    return -1;
  }

  x = read(fd, buf, BLKSIZE);
  printf("%d %d %x %x %x %x\n", x, errno, buf[0], buf[1], buf[2], buf[3]);

  lseek(fd, 0, 0);

  buf[0] = '1';
  buf[1] = '2';
  buf[2] = '3';
  buf[3] = '4';
  x = write(fd, buf, BLKSIZE);

  printf("%d %d\n", fd, errno);

  lseek(fd, 0, 0);

  x = read(fd, buf, BLKSIZE);
  printf("%d %d %x %x %x %x\n", x,errno, buf[0], buf[1], buf[2], buf[3]);

  return 0;
}

这可以用于我的目的,我不知道如何以类似的方式使用Python的os.read/os.write函数进行正确的内存对齐。