Windows操作系统:PCIE Axidma篇 2 多设备的准备及开发

简介: 在之前提到过的测试模式开启后,无须数字签名的axidma驱动就安装成功了,设备管理器中可以很开心的看到我们xilinx dma的设备,但是实际使用中,有时候并不会只用一台设备

前言

 在之前提到过的测试模式开启后,无须数字签名的axidma驱动就安装成功了,设备管理器中可以很开心的看到我们xilinx dma的设备,但是实际使用中,有时候并不会只用一台设备。当遇到了多台设备可以支持吗?以两台为例:

b7fa55edd8ca4a059b98bb4ae9c32d44.png


一.驱动层:

 点开设备属性,事件查看驱动信息,发现PCI编号是不同的,也就是区分我们代码里devpath的依据,

109d6c0c43f64dc1b6461c6849c1ae4d.png

 比如新增一个设备,同样的设备信息会看到设备号为7024,(上图7025为我们后加的设备)7024和7025由逻辑端指定分配(可改),第一步要解决的就是官方驱动里是否支持我们自定义的设备编号,打开驱动目录进行查找,

 能查到两个相关文件里对这个值进行了配置,先随便打开一个,不难看到刚好是没有7025的支持的,可以先把不用的设备号比如7028先更改为7025保存,

74230c71a43d44f1803f7e5cbd0cfac7.png

 重新安装驱动,就能出现最开始的画面了,在驱动层面上就支持了两个不同的设备,增加设备可以用同样的方法。

二.应用层:

 还是以官方的例程为例,下一篇会重点介绍官方例程怎么使用,这里只介绍一下设备的区分

 打开xdma_rw.c,这是官方用于读写寄存器或者内存空间值的demo,不论是我们后面自己开发还是怎么使用,一般都会和demo一样,有获取上面设备号的函数

官方demo里是

static int get_devices(GUID guid, char* devpath, size_t len_devpath)
static int get_devices(GUID guid, char* devpath, size_t len_devpath) {
    HDEVINFO device_info = SetupDiGetClassDevs((LPGUID)&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (device_info == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "GetDevices INVALID_HANDLE_VALUE\n");
        exit(-1);
    }
    SP_DEVICE_INTERFACE_DATA device_interface;
    device_interface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    // enumerate through devices
    DWORD index;
    for (index = 0; SetupDiEnumDeviceInterfaces(device_info, NULL, &guid, index, &device_interface); ++index) {
        // get required buffer size
        ULONG detailLength = 0;
        if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_interface, NULL, 0, &detailLength, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            fprintf(stderr, "SetupDiGetDeviceInterfaceDetail - get length failed\n");
            break;
        }
        // allocate space for device interface detail
        PSP_DEVICE_INTERFACE_DETAIL_DATA dev_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, detailLength);
        if (!dev_detail) {
            fprintf(stderr, "HeapAlloc failed\n");
            break;
        }
        dev_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        // get device interface detail
        if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_interface, dev_detail, detailLength, NULL, NULL)) {
            fprintf(stderr, "SetupDiGetDeviceInterfaceDetail - get detail failed\n");
            HeapFree(GetProcessHeap(), 0, dev_detail);
            break;
        }
        StringCchCopy(devpath, len_devpath, dev_detail->DevicePath);
        HeapFree(GetProcessHeap(), 0, dev_detail);
    }
    SetupDiDestroyDeviceInfoList(device_info);
    return index;
}

其中for (index = 0; SetupDiEnumDeviceInterfaces(device_info, NULL, &guid, index, &device_interface); ++index)做到了遍历所有设备,但是会只返回最后一个设备,也就是说比如我们在7024和7025设备同时在线时,加载成功的是7025设备,那么我们就先只让他查找一次就好了比如改成这样,在应用开发的时候比如我们会分配cpu1核2核去专门做收发那么在另一个设备里最好换成3核4核做同样的工作

static int get_devices(GUID guid, char *devpath, size_t len_devpath) {
    size_t result = 0;
    HDEVINFO device_info = SetupDiGetClassDevs((LPGUID)&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (device_info == INVALID_HANDLE_VALUE) {
        LOGE(LOG_TAG"GetDevices INVALID_HANDLE_VALUE\n");
        return -(int)GetLastError();
    }
    SP_DEVICE_INTERFACE_DATA device_interface;
    device_interface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    // enumerate through devices
    DWORD index;
    index = 1; SetupDiEnumDeviceInterfaces(device_info, NULL, &guid, index, &device_interface);
        // get required buffer size
        ULONG detailLength = 0;
        if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_interface, NULL, 0, &detailLength, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            LOGE(LOG_TAG"SetupDiGetDeviceInterfaceDetail - get length failed\n");
            //break;
        }
        // allocate space for device interface detail
        PSP_DEVICE_INTERFACE_DETAIL_DATA dev_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, detailLength);
        if (!dev_detail) {
            LOGE(LOG_TAG"HeapAlloc failed\n");
            //break;
        }
        dev_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        // get device interface detail
        if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_interface, dev_detail, detailLength, NULL, NULL)) {
            LOGE(LOG_TAG"SetupDiGetDeviceInterfaceDetail - get detail failed\n");
            HeapFree(GetProcessHeap(), 0, dev_detail);
            //break;
        }
        StringCchCopy(devpath, len_devpath, dev_detail->DevicePath);
        HeapFree(GetProcessHeap(), 0, dev_detail);
    SetupDiDestroyDeviceInfoList(device_info);
    return index;
}
相关文章
|
1天前
|
NoSQL Linux 开发工具
【linux】在linux操作系统下快速熟悉开发环境并上手开发工具——体验不一样的开发之旅
【linux】在linux操作系统下快速熟悉开发环境并上手开发工具——体验不一样的开发之旅
|
5天前
|
Dart 开发工具 Android开发
在 Windows 操作系统上安装和配置 Flutter 开发环境
在 Windows 操作系统上安装和配置 Flutter 开发环境
11 0
|
6天前
|
Java Nacos 微服务
Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册
Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册
|
6天前
|
Java 开发工具 Android开发
详细解读Android开发DNK开发将.c文件打包成os
详细解读Android开发DNK开发将.c文件打包成os
|
11天前
|
网络协议 Linux 编译器
【原创】EtherCAT主站IgH解析(二)-- 如何将Igh移植到Linux/Windows/RTOS等多操作系统移植指南
EtherCAT主站方案对比:商业的如Acontis、TwinCAT3和开源的igh、SOEM。SOEM易移植但功能和实时性不足,适合简单应用;igh功能强大,实时性能优秀,基于内核态,适合复杂场景。igh能移植到其他RTOS,但需克服多任务无调度的挑战。依赖操作系统服务如定时器、内存分配,适合Linux内核,但移植到裸机复杂。
|
15天前
|
Windows
【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)
【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)
|
15天前
|
网络安全 C++ Windows
【Windows驱动开发】(主机)VS2017+(虚拟机)win10系统------双机调试
【Windows驱动开发】(主机)VS2017+(虚拟机)win10系统------双机调试
|
16天前
|
编解码 Windows
FFmpeg开发笔记(二十九)Windows环境给FFmpeg集成libxvid
XviD是开源MPEG-4视频编码器,与DivX相似但后者非开源。早期MP4常使用XviD或DivX编码,现已被H.264取代。在Windows上集成FFmpeg的XviD编解码库libxvid,需访问<https://labs.xvid.com/source/>下载源码,解压后在MSYS环境中配置、编译和安装。之后重新配置FFmpeg,启用libxvid并编译安装。详细步骤包括configure命令、make和make install。成功后,通过`ffmpeg -version`检查是否启用libxvid。更多音视频开发技术可参考《FFmpeg开发实战:从零基础到短视频上线》。
56 0
FFmpeg开发笔记(二十九)Windows环境给FFmpeg集成libxvid
|
20天前
|
传感器 网络协议 物联网
嵌入式开发中的常用实时操作系统(RTOS)介绍
选择合适的RTOS是嵌入式开发中的关键步骤,不同的RTOS具有各自的优势和适用场景。开发者需要根据项目需求综合考虑硬件平台、实时性要求、开发资源和支持等因素,选择最合适的RTOS系统。例如,如果需要开源和灵活的解决方案,可以选择Zephyr或RT-Thread;如果需要高性能和商业支持,可以选择VxWorks或ThreadX。希望本文能帮助您更好地了解各类RTOS,并为您的嵌入式开发项目提供参考。
45 1
|
25天前
|
Web App开发 人工智能 安全
探索Windows操作系统的未来之路
【6月更文挑战第6天】本文将深入探讨Windows操作系统的发展历程,分析其面临的挑战与机遇,并展望未来可能的发展趋势。我们将从技术、市场和用户体验三个维度进行剖析,以期对Windows操作系统的未来有一个全面而深刻的理解。