在 Linux 中禁用 USB 大容量存储设备的读取缓冲
Disabling read buffering in Linux for USB mass storage device
场景:
- 树莓派 3 B 型
- 通过USB连接的自适应模块化ECU(将自己呈现为大容量存储设备,实际上是2,在这种情况下为SDA和SDB)
我只是使用 fopen() 打开/dev/sda 进行读取,我寻找我想读取的位置,我读取了 2048 字节。然后,我重新寻找我之前寻求的位置并再次阅读该数据。
在我第一次阅读时,我得到了新鲜、正确的数据。在每次后续读取时,我都会一遍又一遍地获得相同的数据。在第一次读取后,它不会尝试再次轮询设备(因为它有一个活动指示灯),但是当我杀死我的应用程序 (ctrl+c) 时,我看到活动指示灯疯狂闪烁,然后停止。
我认为这是我的代码的缓冲问题(我从 ifstream 开始,并尝试了 fopen() 和 open(),都一样)并尝试了各种不同的方法来禁用增益(即 setvbuf()),但我仍然没有得到新数据。
如果我再次关闭并打开文件,那么我会得到新数据,但这是一个非常缓慢的过程(我只得到大约 10-12 个样本/秒)。
请记住,这不是一个挂载的设备,它只是作为一个存储设备呈现,我直接从它的块设备读取。
我将相同的代码移植到Windows并且它可以工作,所以我不相信这是我的代码,而是Linux中的东西。
任何帮助将不胜感激。
这在stackexchange网站上的问题中得到了解决:unix.stackexchange.com/questions/372452/disable-read-cache-buffer-for-usb-mass-storage-device-in-linux
总而言之,问题是我需要使用O_DIRECT
但要确保我正在读取(和寻找)完整的数据块。就我而言,该设备在 512 字节块中,所以我需要获取该数量。
#define NUM_VARS 1024
#define PAGE 4096
#define STARTBYTE (272384/PAGE*PAGE) // must align
#define OFFSET (272384-STARTBYTE)
#define ITEMSIZE (sizeof(*liveBuffer))
#define LIVEBUFSIZE ((OFFSET+NUM_VARS*ITEMSIZE+PAGE-1)/PAGE*PAGE)
signed short *liveBuffer;
FILE *input = fopen("/dev/sda", "r+");
if(posix_memalign((void**)&liveBuffer, PAGE, LIVEBUFSIZE)!=0)
exit(5);
if (fcntl(fileno(input), F_SETFL, O_DIRECT) == -1)
exit(6);
fseek(input, OFFSET, SEEK_SET);
fread(liveBuffer, ITEMSIZE, LIVEBUFSIZE, input);
fclose(input);
相关文章:
- 如何在 MAC OS c/c++ 中阻止 USB 存储设备
- 用于创建/注册虚拟存储设备的 IOKit 驱动程序
- 是防止原子存储部分读取所必需的"memory_order_relaxed"
- cudaMemcpy 在从设备读取到主机时返回 cudaErrorInvalidArgument,不清楚原因
- 在 Linux 中禁用 USB 大容量存储设备的读取缓冲
- 从存储库读取单个文件时出现问题
- 是否可以使用IDiaDataSource::LoadDataFromPdb从符号存储中读取pdb
- 为什么Qt(4.8)串口(qextserialport)分两部分从设备读取数据
- C++ - 如何在向量中使用pcap_next_ex存储脱机读取数据包
- 如何从USB设备读取证书并将其发送到Firefox等浏览器
- C++从外部设备读取数据 - 连接:光电USB
- 如何通过OpenCV存储和读取整数矩阵
- 如何以编程方式阻止 Linux 操作系统用户空间中的 USB 存储设备
- 如何在C++中从串行设备读取
- 在像素GLSL中存储(并读取)大量数据
- 从串行设备读取字节(并理解它们??)
- 如何在Linux中使用libudev编程地列出USB大容量存储设备
- 使用Openstore挂载存储设备
- 如何获取物理存储设备列表
- 如何使用Visual c++从USB大容量存储设备读取文件