fpga下面开启BAR0和BAR1,用xilinx官方测试代码只能读写BAR0寄存器数据,现在想读BAR1的寄存器;用windriver是可以正常读BAR1的;用MmMapIoPlace函数映射,程序就崩掉;去看了下驱动,读写control对应的通道写的0,不知道是不是对应的BAR0,如果是这样,要读取BAR1,是不是就要把control对应通道改成1。大家有没有什么好的意见,在此多谢了
1条回答 默认 最新
关注【以下回答由 GPT 生成】
问题分析:
- 在Windows下使用Xilinx PCIe板卡来读写BAR1区域寄存器时遇到问题。
- 使用Xilinx官方测试代码可以成功读写BAR0寄存器,但无法成功读取BAR1的寄存器内容。
- 尝试使用Windriver来读取BAR1时程序崩溃,查看驱动程序发现对应的通道写了0,不确定是否对应BAR0,以及是否需要将对应通道改成1。
解决方案:
首先,需要确保驱动程序正确配置和加载,并且系统能够正确识别和初始化Xilinx PCIe板卡。
接下来,为了读写BAR1区域寄存器,可以按照以下步骤进行操作:
- 使用Windriver进行驱动开发时,确认当前驱动正在操作的是Xilinx PCIe板卡,而不是其他设备。可以通过设备的Vendor ID和Device ID来判断,具体代码如下:
// 获取设备的Vendor ID和Device ID USHORT vendorID = GetDeviceVendorID(deviceHandle); USHORT deviceID = GetDeviceDeviceID(deviceHandle); // 判断是否为Xilinx PCIe板卡 if (vendorID == XILINX_VENDOR_ID && deviceID == XILINX_DEVICE_ID) { // 进行BAR1区域寄存器操作 ... } else { // 不是Xilinx PCIe板卡,进行其他处理 ... }其中,
GetDeviceVendorID()和GetDeviceDeviceID()函数可以通过Windows驱动开发相关API获取设备的Vendor ID和Device ID。- 确定在驱动程序中操作的是正确的BAR区域。BAR0和BAR1都是寄存器区域,但对应的硬件地址不同。可以通过以下代码来读取BAR1对应的基地址:
// 读取BAR1对应的基地址 ULONG bar1BaseAddress = GetBARBaseAddress(deviceHandle, BAR1_INDEX);其中,
GetBARBaseAddress()函数可以通过Windows驱动开发相关API获取指定BAR区域的基地址。- 使用MmMapIoSpace函数将BAR1区域的基地址映射为用户空间的虚拟地址。具体代码如下:
// 将BAR1区域的基地址映射为用户空间的虚拟地址 PVOID bar1VirtualAddress = MmMapIoSpace(bar1BaseAddress, BAR1_SIZE, MmNonCached); if (bar1VirtualAddress != NULL) { // 成功映射BAR1区域的基地址,进行读写操作 ... } else { // 映射失败,进行错误处理 ... }其中,
bar1BaseAddress为前一步获取的BAR1基地址,BAR1_SIZE为BAR1区域的大小,MmMapIoSpace()函数是Windows驱动开发提供的API,用于将硬件地址映射为用户空间的虚拟地址。- 成功映射BAR1区域的基地址后,即可通过虚拟地址进行寄存器的读写操作。具体代码如下:
// 读取BAR1寄存器的值 ULONG bar1Value = *((PULONG)bar1VirtualAddress); // 写入BAR1寄存器的值 *((PULONG)bar1VirtualAddress) = bar1Value;其中,
PULONG为指向ULONG类型数据的指针,可以根据具体的寄存器类型进行修改。总结:
通过以上步骤,可以在Windows下使用Xilinx PCIe板卡成功读写BAR1区域寄存器。但需要注意的是,具体的实现可能还需要根据驱动开发的相关文档和硬件设备的规格进行进一步调整和优化。
回答完毕。
如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^解决 无用评论 打赏 举报