Linux версия: 4.19
Платформа: Xilinx Ultrascale + Zynq
В программируемой логике c я создал устройство с отображением памяти, расположенное по физическому адресу 0xA0001000. Я использую uio_pdrv_genirq в качестве драйвера устройства. Устройство отображается как uio0, и я готов читать и писать на него, используя mmap. Я хочу быть в состоянии гарантировать, что любые записи, которые я произвожу, будут записаны на устройство сразу, вместо того, чтобы ждать, пока Linux покажет sh грязные страницы. Для этого я должен использовать msyn c согласно всем моим исследованиям. Но я продолжаю получать ошибку, когда я делаю это. Вот моя тестовая программа:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
void main() {
int fid;
int rval;
char *data;
int idx;
printf("Open UIO Device \n");
fid= open("/dev/uio0", O_RDWR | O_SYNC);
data= mmap(NULL, 0x1000, PROT_WRITE|PROT_READ, MAP_SHARED, fid, 0);
if(MAP_FAILED == data) {
printf("Error code when mapping! %s", strerror(errno));
}
printf("addr= 0x%8X\n", data);
printf("pagesize= 0x%4X\n", getpagesize());
printf("Write some data\n");
data[11]= 0xDE;
data[10]= 0xC0;
data[ 9]= 0xDE;
data[ 8]= 0xAD;
rval= msync(data, 0x1000, MS_SYNC);
if(-1 == rval) {
printf("Error on msync! %s\n", strerror(errno));
}
if(munmap(data, 0x1000) < 0) {
printf("munmap error! %s\n", strerror(errno));
}
printf("Close UIO device\n");
rval= close(fid);
if(rval != 0) {
printf("UIO device close Error!\n");
}
}
А вот и вывод программы:
mylinux:~/test-apps$ ./a.out
Open UIO Device
addr= 0xABA05000
pagesize= 0x1000
Write some data
Error on msync! Invalid argument
Close UIO device
Я не понимаю источник этой ошибки. Справочные страницы msyn c утверждают, что эта ошибка может возникнуть, если адрес не кратен PAGESIZE. Но, как видно из приведенного выше примера, это кратное число. Даже физический адрес кратен PAGESIZE.
Несколько других примечаний:
- Я получаю ту же ошибку, даже если удаляю O_SYN C из флагов функции open ,
- Шина AXI4 в FPGA fabri c составляет 128 бит, которая затем преобразуется в 32 бита IP-блоками Xilinx. Я не думаю, что это как-то связано с моей проблемой.
Спасибо за любые идеи, которые могут дать люди.