我已经能够在Zynq 7000板上使用Xilinx SDK创建一个裸机应用程序来访问ARM全局计时器。但是,我正在尝试使用mmap在Xilinx Linux中映射ARM全局定时器并访问它。我使用以下代码:
game[2][le]
每当我尝试访问此虚拟地址时,都会出现分段错误。我发现我的mmap返回的是errno = 22,表示无效参数。我使用mmap来映射相同用户空间中的axi空间,除了地址和它们有效之外,它们具有相同的参数。
我怀疑这个地区有点特别。与ARM infopage一样,它将此区域定义为私有区域。我不明白这究竟是什么意思以及我访问arm全局计时器的解决方案是什么。
P.S我已经知道新的Xilinx Linux内核具有内置驱动程序来访问此全局计时器。但是我无法构建最新的内核并使用它,因为没有关于如何使用计时器的明确帮助。我现在正在寻求两种解决方案。
答案 0 :(得分:0)
您必须创建一个函数来从内核获取虚拟地址。 观看此视频,您将找到解决方案 https://www.youtube.com/watch?v=XtvVfjIm9Xw&feature=youtu.be
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
void *getvaddr(int phys_addr)
{
void *mapped_base;
int memfd;
void *mapped_dev_base;
off_t dev_base = phys_addr;
memfd = open("/dev/mem", O_RDWR | O_SYNC); // to open this, the program needs to be run as root
if (memfd == -1)
{
printf("Can't open /dev/mem.\n");
exit(0);
}
// Map one page of memory into user space such that the device is in that page, but it may not
// be at the start of the page
mapped_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd,
dev_base & ~MAP_MASK);
if (mapped_base == (void *)-1)
{
printf("Can't map the memory to user space.\n");
exit(0);
}
// get the address of the device in user space which will be an offset from the base
// that was mapped as memory is mapped at the start of the page
mapped_dev_base = mapped_base + (dev_base & MAP_MASK);
return mapped_dev_base;
}