Сценарий:
Я просто использую 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);
Других решений пока нет …