我已将0x40000000
的基地址映射到虚拟内存地址。但是,当我尝试读取0x40100000
位置上的寄存器值时,出现了分段错误。 mmap()
函数中使用的页面大小为4K
,其中文件描述符的值为3
。
从主调用init()
函数以初始化内存:
这里的UWord8
是unsigned char
,UWord32
是unsigned int
。
UWord8 init()
{
UWord8 error;
printf("Initializing Devices in Zynq...\n\r\n\r");
error = initMemory();
if(error)
{
printf("PL:\tAccess Denied\n\r");
return 1;
}
if(!error)
{
error = initFpga();
if(error)
{
printf("Access Denied to mmap...\n\r");
return 1;
}
}
}
UWord8 initMemory(void)
{
UWord8 error = 0;
//Initializing /dev/mem
fd = open(MEMORY_ACCESS, READ_WRITE);
if(fd < 1)
{
error = 1;
#if DEBUG_MODE
printf("Could not open /dev/mem for access\n");
#endif
}
else
{
printf("Value of fd is %u\n", fd);
page_size = sysconf(_SC_PAGESIZE);
printf("The page size is %u\n", page_size);
#if DEBUG_MODE
printf("Successfully opened /dev/mem for access\n");
#endif
}
//Opening text file for writing pointer data
fp = fopen("/home/pointer_data.txt", "a");
if(fp == NULL)
{
error = 1;
#if DEBUG_MODE
printf("Could not open text file for writing.\n\r");
#endif
}
else
{
#if DEBUG_MODE
printf("Successfully opened text file for writing.\n\r");
#endif
}
return error;
}
UWord8 initFpga(void)
{
UWord8 error = 0;
unsigned page_addr, device_addr;
device_addr = BASE_ADDRESS;
page_addr = (device_addr & (~(page_size-1)));
fpga_pageOffset = device_addr - page_addr;
fpga_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); //mmap the device into memory
if(fpga_ptr == NULL)
{
printf("Memory mapping to Base address 0x%08x failed...\n\r",BASE_ADDRESS);
error = 1;
}
return error;
}
以下是该函数在特定地址处读取的值,发送给该函数的地址是相对于基地址的偏移量:
UWord32 _getWord(UWord32 address)
{
UWord32 data = *((unsigned *)(fpga_ptr + fpga_pageOffset + address));
printf("peek 0x%08x =0x%08x\n\r", BASE_ADDRESS + address, data);
return data;
}
此行没有错误:
_getWord(0x000ffff8)
但是我在以下方面遇到了细分错误:
_getWord(0x00100000)
答案 0 :(得分:1)
创建内存映射时,将其大小设置为等于页面大小-4kb。
fpga_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); //mmap the device into memory
这转换为0x1000
个字节,但是您尝试在映射开始之后访问数据0x100000
个字节,这会引起分段错误。要解决此问题,请映射更大的内存区域。例如:
fpga_ptr = mmap(NULL, 0x1000 * page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr);
这将使您可以访问内存映射开始之后的下一个0x1000000
字节。