Loading [MathJax]/jax/output/CommonHTML/config.js
社区首页 >问答首页 >需要为USB外围设备编写驱动程序吗?

需要为USB外围设备编写驱动程序吗?
EN

Stack Overflow用户
提问于 2016-07-22 07:01:16
回答 3查看 8.3K关注 0票数 5

我正在设计一个USB外设,它偶尔会连接到Windows,并在每个方向传输几KB的数据。将有一个自定义PC应用程序来控制数据传输,使用专有协议(即USB有效载荷)。

我在下面的链接中看到,Microsoft描述了如何为USB设备编写驱动程序。但我需要一个吗?

为USB设备开发Windows客户端驱动程序

PC应用程序是我们打算知道如何与设备通信的唯一应用程序,因此从应用程序共享的角度来看,不需要驱动程序。

我能否直接将自定义协议烘焙到应用程序中,让应用程序对设备说“原始USB”,而没有单独的驱动程序呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-22 07:11:47

“原始USB",不,你不能从一个应用程序这样做。

但是,因为您也控制了设备,所以您可以将其显示为Windows为其提供的设备驱动程序之一,该驱动程序具有足够的通用性,可以执行您想做的任何事情。

这些设备类是HID (人机界面设备)和"WinUSB“。其中,HID是跨平台的,但功能更有限,WinUSB允许高性能的数据传输以及中断端点。

关于设置设备的字符串描述符以便WinUSB自动将其绑定到论MSDN驱动程序的说明是论MSDN

WinUSB设备是一种通用串行总线(USB)设备,其固件定义了某些Microsoft操作系统(OS)特性描述符,将兼容的ID报告为"WINUSB"。 WinUSB设备的目的是使Winusb.sys能够在没有自定义INF文件的情况下作为设备的功能驱动程序加载。对于WinUSB设备,不需要为设备分发INF文件,这使得驱动程序安装过程对于最终用户来说很简单。

票数 5
EN

Stack Overflow用户

发布于 2018-02-19 12:24:48

使用的另一种方法是不需要编写驱动程序来使用WriteFile函数编写您想要的设备:WinUSB,如何这样做:

  • 包括WinUsb.h
  • 将WinUsb.lib添加到链接库列表中。
  • 在Usb100.h中有一些宏。
  • 使用设备接口GUID获取设备路径。正确的GUID是您在用于安装WinUsb.sys的INF中指定的GUID。
  • 通过将您在INF中定义的设备接口GUID传递给SetupDiGetClassDevs,获取设备信息集的句柄。函数返回一个HDEVINFO句柄。
  • 调用SetupDiEnumDeviceInterfaces来枚举系统的设备接口并获取有关设备接口的信息。
  • 调用SetupDiGetDeviceInterfaceDetail获取设备接口的详细数据。
  • 调用GetDevicePath函数以获得设备路径。
  • 将设备路径传递给CreateFile以获得设备的文件句柄。使用ReadFile和写文件与设备进行通信!
  • 将文件句柄传递给WinUsb_Initialize以初始化WinUSB并获得WinUSB句柄。在调用WinUSB API函数时,可以使用设备的WinUSB句柄来标识设备,而不是设备的文件句柄。

对于更高级的解决方案--使用函数:

  • WinUsb_QueryDeviceInformation以获得设备的速度。
  • WinUsb_QueryInterfaceSettings以获得相应的接口描述符。WinUSB句柄对应于第一个接口。
  • WinUsb_QueryPipe获取有关每个端点的信息。
  • WinUsb_WritePipe将缓冲区写入设备默认行为:零长度写入在堆栈中转发.如果传输长度大于最大传输长度,则WinUSB将请求划分为最大传输长度的较小请求,并依次提交请求。
  • 更多功能和信息:howto.docx

出于调试目的,您可能需要: winusbtrace_tool https://blogs.msdn.microsoft.com/usbcoreblog/2010/02/05/how-to-generate-and-view-a-winusb-debug-trace-log/;带有USBPcap插件的Wireshark https://www.wireshark.org

其他例子:http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html。示例模板随Visual一起提供。

您还需要掌握编写.inf文件的知识。

另一种与USB - libusb-win32 32 https://sourceforge.net/projects/libusb-win32/通信的简单方法

我的简单控制台应用程序将块发送到设备(原始数据立即写入设备,绕过堆栈):

代码语言:javascript
代码运行次数:0
复制
#include "stdafx.h"
#include <SetupAPI.h>
#include <Hidsdi.h> 
#include <devguid.h> 
#include <winusb.h>
#include <usb.h>
#pragma comment(lib, "hid.lib")
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "winusb.lib")
#include <iUString.h> 


iString<char> DevicePath;
bool                    WinusbHandle_Open=false;
bool                    DeviceHandle_Open = false;
WINUSB_INTERFACE_HANDLE WinusbHandle;
HANDLE                  DeviceHandle;
UCHAR usb_out_buffer[64];
DEFINE_GUID(GUID_DEVCLASS_WINUSB, 0x88bae032L, 0x5a81, 0x49f0, 0xbc, 0x3d, 0xa4, 0xff, 0x13, 0x82, 0x16, 0xd6);
DEFINE_GUID(GUID_DEVCLASS_STL, 0xf177724dL, 0x74d3, 0x430e, 0x86, 0xb5, 0xf0, 0x36, 0x89, 0x10, 0xeb, 0x23);
GUID winusb_guid;
GUID stl_guid;

bool connectusb();
void  disconnectusb();




int main()
{
    DWORD n;
    DWORD   numEvents;
    HANDLE rHnd;    

WinusbHandle_Open = false;
DeviceHandle_Open = false;
winusb_guid = GUID_DEVCLASS_WINUSB;
stl_guid = GUID_DEVCLASS_STL;
usb_out_buffer[0] = 0;
usb_out_buffer[1] = 1;
usb_out_buffer[2] = 2;
usb_out_buffer[3] = 3;

ULONG bytesWritten;
ULONG timeout;
timeout = 100;
rHnd = GetStdHandle(STD_INPUT_HANDLE);

WinUsb_SetPipePolicy(WinusbHandle, 0x01, PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout);

timeout = TRUE;
WinUsb_SetPipePolicy(WinusbHandle, 0x01, AUTO_CLEAR_STALL, sizeof(ULONG), &timeout);


timeout = TRUE;
WinUsb_SetPipePolicy(WinusbHandle, 0x01, RAW_IO, sizeof(ULONG), &timeout);//Bypasses queuing and error handling to boost performance for multiple read requests.


while (true)
{
if ((!WinusbHandle_Open) || (!WinusbHandle_Open)) { if (!connectusb())Sleep(2000); }
if ((!WinusbHandle_Open) || (!WinusbHandle_Open))continue;

bytesWritten = 0;
if (!WinUsb_WritePipe(WinusbHandle, 0x01, &usb_out_buffer[0], 2, &bytesWritten, NULL))
{
    n = GetLastError();
disconnectusb();
}
Sleep(2000);
}
disconnectusb();
return 0;
}




bool connectusb()
{
    BOOL                             bResult = FALSE;
    HDEVINFO                         deviceInfo;
    SP_DEVICE_INTERFACE_DATA         interfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
    DWORD n;
    SP_DEVINFO_DATA devinfo;
    BYTE devdetailbuffer[4096];
    bool found;

    deviceInfo = SetupDiGetClassDevs(&stl_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (deviceInfo == INVALID_HANDLE_VALUE) { return false; }

    found = false;
    for (n = 0;; n++)
    {

        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

        if (!SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &stl_guid, n, &interfaceData))
        {
            n = GetLastError();
            break;
        }




        detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer;
        detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        devinfo.cbSize = sizeof(devinfo);
        if (!SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, sizeof(devdetailbuffer), NULL, &devinfo)) { printf("SetupDiGetDeviceInterfaceDetail: %u\n", GetLastError()); break; }
        if (IsEqualGUID(devinfo.ClassGuid, winusb_guid))
        {
            if ((-1 != iStrPos(detailData->DevicePath, "VID_0483")) || (-1 != iStrPos(detailData->DevicePath, "vid_0483")))
            {
                if ((-1 != iStrPos(detailData->DevicePath, "PID_576B")) || (-1 != iStrPos(detailData->DevicePath, "pid_576b")))
                {

                    DevicePath = detailData->DevicePath;
                    found = true;
                    break;
                }
            }
        }
    }



SetupDiDestroyDeviceInfoList(deviceInfo);
if (!found)return false;


DeviceHandle = CreateFile(DevicePath.Buffer() ,
    GENERIC_WRITE | GENERIC_READ,
    FILE_SHARE_WRITE | FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
    NULL);

if (INVALID_HANDLE_VALUE == DeviceHandle) {
    n = GetLastError();
}

if (INVALID_HANDLE_VALUE == DeviceHandle) return false;
DeviceHandle_Open = true;



if (!WinUsb_Initialize(DeviceHandle, &WinusbHandle))
 {
     n = GetLastError();
     CloseHandle(DeviceHandle); DeviceHandle_Open = false;
     return false;
 }



WinusbHandle_Open = true;
return true;
}

void  disconnectusb()
{
    if (WinusbHandle_Open) { WinUsb_Free(WinusbHandle); WinusbHandle_Open = false; }
    if (DeviceHandle_Open) { CloseHandle(DeviceHandle); DeviceHandle_Open = false; }
}
票数 3
EN

Stack Overflow用户

发布于 2020-08-05 01:37:56

使您的固件被枚举为WINUSB (winusb通用驱动程序)设备使生活变得更容易。

我相信如果你有一个演示和代码,那就很清楚了,所以我为你做了一个:)

我的KEIL项目使用STM32F4 Discovery板与WINUSB作为USB设备一起工作。您可以看到更多信息,并让获得源代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38529675

复制
相关文章
C++11模板:如何判断类中是否有指定名称的成员变量?
版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/51113805
10km
2019/05/25
4.2K0
动态调用类中的方法(无)(有)参数
1、Type类,方法用Invoke调用的时候就 使用null:表示该方法是无参数的
静心物语313
2020/03/24
2.6K0
powershell: 判断PSObject中是否有指定property的靠谱方法
如何判断一个PSObject中是否定义指定名称的属性,下面的代码中举出了三个方法 $test=New-Object PSObject -Property @{ compiler=$null
10km
2018/01/03
1.1K0
less中的可变参数
当前我们的混合的参数都需要传递,如果都需要全部传递可以使用 @arguments,@arguments 代表着就是你传入的所有参数,less 中的 @arguments 和 js 中的 arguments 一样,可以拿到传递进来的所有形参,这个时候你就不用足一的赋值,如下
程序员 NEO
2023/09/29
2090
less中的可变参数
Sass中的可变参数
SASS 中的可变参数和 LESS 中也一样,只不过由于 SASS 不是使用 JS 实现的,所以不能直接在混合中使用 arguments,必须通过 $args... 的格式来定义可变参数,然后通过 $args 来使用,注意点:和 LESS 一样可变参数必须写在形参列表的最后:
程序员 NEO
2023/09/29
1890
Sass中的可变参数
【C++11】移动赋值 | 新的类功能 | 可变参数模板
C++98中 没有移动赋值和移动构造 ,只有参数为左值 的赋值重载(operator=)和拷贝构造
lovevivi
2023/10/17
1980
【C++11】移动赋值 | 新的类功能 | 可变参数模板
C/C++开发基础——可变参数与可变参数模板
1.如果可变参数的参数类型相同,可以使用标准库中的initializer_list。
Coder-ZZ
2023/09/04
7170
C/C++开发基础——可变参数与可变参数模板
【JavaSE】可变参数的基本使用
可变参数 1. 基本概念 Java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法 就可以通过可变参数实现 2. 基本语法 访问修饰符 返回类型 方法名(数据类型... 形参名) { } 3. 快速入门案例 VarParameter01.java 看一个案例 类 XdrMethod,方法 sum 【可以计算 2 个数的和,3 个数的和 , 4. 5, ...】 public int sum(int n1, int n2){ return n1 + n2; }
兮动人
2021/12/30
4400
Java 开发中可变参数个数的方法 原
在 J2SE 5 以前,可以使用数组来实现向一个方法中传入个数可变的参数的目的,比较典型的应用场景就是 main 方法。
LeoXu
2018/08/15
1.1K0
python中函数的可变参数
print(1,2,"hello","刘金玉编程","编程创造城市",end="$$$")
刘金玉编程
2019/07/30
2.2K0
小朋友,你是否有很多的 GC ?
GC 即 Garbage Collection,中文 意思“垃圾回收”,在有GC之前,我们手动去管理内存,如果你忘记标记某一处已经不再使用的内存,那么这块内存将永远不会被系统回收,也就是常说的 “内存泄露”。
代码宇宙
2023/02/23
4020
Logback排除指定包/类/方法日志输出
Logback排除指定包或者类或者方法的日志输出 在logback-spring.xml中添加如下代码,可以一直点下去 <!--包--> <logger name="com.newbie.dao" level="OFF"></logger> <!--类--> <logger name="com.newbie.dao.NbDdiMonitorDao" level="OFF"></logger> <!--方法--> <logger name="com.newbie.dao.NbDdiMonitorDao.upd
4xx.me
2022/06/10
4.6K0
Thymeleaf 指定多个路径作为模板目录
今天自己想在开发平台上增加一套前端的界面,突然想到自己还没有一套用来做展示用的cms系统,为了把cms的模板和后台的模板分开存放,试验了下怎么样设置多个模板路径,代码在此:
前Thoughtworks-杨焱
2021/12/07
1.6K0
可变数据类型不能作为python函数的参数
当使用列表作为参数传入函数时,实际上是引用传递。也就是传入的是实际参数的地址,而place=b也就是指向相同的地址。比如以下的:
西西嘛呦
2020/10/28
1.6K0
实例方法,类方法和静态方法的区别_python中类的所有实例方法
第一个参数是”self”,表示实例对象,通过它传递实例的属性和方法。只能由实例调用
全栈程序员站长
2022/09/20
2K0
【C++】C++11——新的类功能|default、delete|可变参数模板|emplace
在C++98中,如果要限制某些函数的生成,把该函数设置成private,并且只声明不实现
平凡的人1
2023/10/15
3480
【C++】C++11——新的类功能|default、delete|可变参数模板|emplace
可变参数的函数
C语言允许定义参数数量可变的函数,这称为可变参数函数(variadic function)。这种函数需要固定数量的强制参数,后面是数量可变的可选参数。其中,强制参数必须至少一个,可选参数数量可变,类型可变,可选参数的数量由强制参数的值决定。 C 语言中最常用的可变参数函数例子是 printf()和 scanf()。这两个函数都有一个强制参数,即格式化字符串。格式化字符串中的转换修饰符决定了可选参数的数量和类型。 可变参数函数格式:int fun(int a,...)
用户7272142
2023/10/11
2300
IDEA使用模板自动生成类注释和方法,解决方法注释在接口中或普通类的方法外使用模板注释不带参数的情况
参考: idea 自动生成类注释和方法注释的实现步骤-脚本之家 使用groovy脚本生成idea方法注释参数格式对齐
全栈程序员站长
2022/09/27
1.4K0
IDEA使用模板自动生成类注释和方法,解决方法注释在接口中或普通类的方法外使用模板注释不带参数的情况
【Go 语言社区】Golang 可变参数的使用
func main() { Func1(1,2,3,4) } func Func1(args ...int) { for _, res := range args { fmt.Println(res) } Func2(args...) Func3(args[2:]...) } func Func2(args ...int) { fmt.Println("----")
李海彬
2018/03/19
8090
点击加载更多

相似问题

是否有一种使用可变模板作为参数的方法?

25

是否有一种方法可以部分匹配可变模板参数包?

21

模板类的朋友operator<<,带有附加的默认模板参数

13

使用可变模板作为类和方法的参数

15

重载模板类的朋友operator<<

59
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文