【blog.csdn.net/lanmanck】

曾几何时我们找工作还发现有个驱动工程师职位,月薪也不低,没接触过的人代码压根看不懂。

今天可好了,如果不太追求差异化,不用驱动也能让系统与USB设备通信了,Linux就不说了,libusb很好用,现在说下windows的。

Winusb是从XP-SP2起微软提供的一个类似libusb与usb设备通信的中间件,通过它我们就不需要再费奏折的研究和编写USB驱动了。这是几篇资源,先列出来,后面会专门转载一篇详细的blog文,以便有个彻底的认识,不过是E文的,要看仔细点。

资源:

1、libusb介绍:http://www.libusb.org/wiki/windows_backend

2、Jan的使用博客:http://www.lvr.com/winusb.htm,以及它的详细介绍:http://www.lvr.com/winusb_article.htm

3、微软教你如何安装inf:http://blogs.msdn.com/b/usbcoreblog/archive/2012/09/26/how-to-install-winusb-sys-without-a-custom-inf.aspx

4、另一个哥们写的.net-winusb控件和源码:http://www.asyncop.com/MTnPDirEnum.aspx?treeviewPath=[o]+Open-Source\WinUSB+Component

5、微软官方描述:http://msdn.microsoft.com/zh-cn/library/ff540196.aspx

6、微软教你如何通信:http://msdn.microsoft.com/library/windows/hardware/gg487341

7、一个哥们做的stm32通信,要翻墙:http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html

好了,转帖一个winusb的e文介绍,还是老外写的专业点:

Explore USB with WinUSB
This article originally appeared in Nuts & Volts.

If you’re developing a device that needs to talk to a PC, the chances are good that USB will be involved. For each USB device, the PC assigns a software driver. Windows provides drivers for devices that fit into defined USB classes such as human interface, printer, or mass storage. If your device doesn’t fit a defined class, Microsoft’s WinUSB driver is an option.

In this article, I'll show how to program and access WinUSB devices. The WinUSB driver requires a PC with Windows XP SP2 or later, including Windows Vista and Windows 7.

A Transfer Type for Every Purpose
Every USB data transfer is between a PC or other USB host computer and a device endpoint. A device endpoint is a buffer that stores received data or data to transmit. Every device must support endpoint zero, which is bidirectional. Additional, optional endpoint addresses each have a number (1-15) and a direction (IN or OUT).

Even though endpoints reside on devices, the USB specification defines endpoint direction from the view of the host PC. An IN endpoint sends data to the PC, and an OUT endpoint receives data from the PC. This naming convention can be confusing when writing code for the device side!

One reason why USB is so versatile is its support for four transfer types, each with different strengths. WinUSB supports control, bulk, and interrupt transfers. Control transfers use endpoint zero. The other transfer types can use endpoints one and higher.

Control transfers provide a structured way to send requests and data and receive responses. Control transfers are the only type that can pass information in both directions in a single transfer. After device attachment, in a process called enumeration, the host computer uses control transfers to learn about the device.

WinUSB devices can also use control transfers to send and receive data in vendor-defined requests. For example, you can define a request to set or read a switch, send data to configure device operation, or receive a sensor reading.

A control transfer has two or three stages. To learn about a newly attached device, the host computer uses control transfers to request data structures called descriptors from the device. In the Setup stage, the host sends the request. In the Data stage, the device sends the requested descriptor. In the Status stage, the host acknowledges receiving the descriptor. A host can also use control transfers to send information to a device in the Data stage, with the device acknowledging in the Status stage. Some requests have no Data stage.

A USB host reserves a portion of the bus bandwidth for control transfers: 10% for low- and full-speed endpoints and 20% for high-speed endpoints. If the bus isn’t busy, control transfers can use more than the reserved bandwidth. But all devices must share the bus, so on a busy bus, a control transfer may have to wait.

The other transfer types don’t have multiple stages and can transfer data for any purpose. On an otherwise idle bus, bulk transfers are the fastest. But bulk transfers have no guaranteed bandwidth, so on a busy bus, bulk transfers must wait. Common uses for bulk transfers are printers and scanners, where quick transfers are nice but not essential.

For interrupt transfers, the host guarantees a maximum interval between requests for data from IN endpoints or sending data to OUT endpoints. Common uses for interrupt transfers are mice and keyboards, which need to transfer user input quickly to the host computer.

Isochronous transfers have a guaranteed transfer rate but unlike the other transfer types, isochronous transfers don’t use acknowledgements, and the receiver has no defined way to request re-transmitting corrupted data. Common uses for isochronous transfers are streaming audio and video, where users won’t notice or will tolerate a few corrupted or missing packets. WinUSB doesn’t support isochronous transfers.

Using the USB Framework
My example code is for Microchip Technology’s PIC18F4550 microcontroller and MPLAB C18 compiler. I tested the code on Microchip’s PICDEM FS-USB development board. A complete WinUSB project for the PIC along with companion Visual Basic and Visual C# applications are available from my website.

My PIC code uses Microchip’s free USB Framework, which is a set of source-code modules that handle low-level USB communications. Using the Framework can save much time and trouble.

For each endpoint besides endpoint zero, the device provides an endpoint descriptor. This listing shows endpoint descriptors for bulk and interrupt endpoints in each direction:

// Endpoint descriptors
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP01_OUT,               //  Endpoint number and direction
_BULK,                   //  Transfer type
0x40, 0x00,              //  Endpoint size in bytes
0x00,                    //  Ignored for bulk endpoint
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP01_IN,                //  Endpoint number and direction
_BULK,                   //  Transfer type
0x40, 0x00,              //  Endpoint size in bytes
0x00,                    //  Ignored for bulk endpoint
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP02_OUT,               //  Endpoint number and direction
_INT,                    //  Transfer type
0x08, 0x00,              //  Endpoint size in bytes
0x0A,                    //  Endpoint interval
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP02_IN,                //  Endpoint number and direction
_INT,                    //  Transfer type
0x08, 0x00,              //  Endpoint size in bytes
0x0A                     //  Endpoint interval
The USB Framework defines constants that help make the code more readable and easier to maintain. For example, in Listing 1, USB_DESCRIPTOR_ENDPOINT is the constant 0x05, which the USB specification defines as the value that identifies an endpoint descriptor.

Other descriptors include the device descriptor, which contains the device’s Vendor ID (VID) and Product ID (PID) and one or more interface descriptors that specify an interface number and how many endpoints belong to the interface. The USB 2.0 specification defines the fields in the descriptors.

Bulk and Interrupt Transfers
To read and write to endpoints, program code accesses an endpoint’s buffer descriptor (BD).  To program USB Framework communications on PICs, you need to understand BDs.

A BD consists of four byte-wide registers that hold information about an endpoint’s most recent data transfer or the next data transfer. The microcontroller core and the USB module share ownership of the BD. The microcontroller core is the CPU that executes the code, or firmware, that you program into the device. The USB module, also called the serial interface engine (SIE), provides hardware support for USB communications. A USB_HANDLE is a pointer to an endpoint’s BD.

The key to accessing a BD is its UOWN bit. When UOWN = 0, the microcontroller core owns the buffer, and firmware can read and write to the BD. When UOWN = 1, the USB module owns the BD, and firmware can read UOWN but should not read or write to other locations in the BD.

This listing shows code for reading received data on a bulk OUT endpoint.

#define WINUSB_BULK_EP 1
#define WINUSB_BULK_IN_EP_SIZE 64
#define WINUSB_BULK_OUT_EP_SIZE 64
WORD bulk_bytes = 0; 
USB_HANDLE USBWinUsbBulkOutHandle;
unsigned char winusb_bulk_in_buffer[WINUSB_BULK_IN_EP_SIZE];
unsigned char winusb_bulk_out_buffer[WINUSB_BULK_OUT_EP_SIZE];
// Set up the endpoint to enable receiving data.
USBWinUsbBulkOutHandle = USBGenRead(WINUSB_BULK_EP,
     (BYTE*)&winusb_bulk_out_buffer, WINUSB_BULK_OUT_EP_SIZE);
if(!USBHandleBusy(USBWinUsbBulkOutHandle))
{
   // The microcontroller  core owns the endpoint. 
   // Check for received  data.
   bulk_bytes =  USBHandleGetLength(USBWinUsbBulkOutHandle); 
   if (bulk_bytes > 0)
   {
      // Data was received. 
      // Copy it to for  sending back to the host.
      for (count; count <=  bulk_bytes - 1; count++)
      {
         winusb_bulk_in_buffer[count] = 
         winusb_bulk_out_buffer[count];
      }
   }
}
(Remember that an OUT endpoint receives data from the host.) The USB Framework’s USBGenRead function handles many details of preparing the endpoint to receive data. The function accepts an endpoint number, a pointer to a buffer to hold received data, and the maximum number of bytes to receive. The function sets up the transfer, sets UOWN = 1 to transfer BD ownership to the USB module, and returns a pointer to the BD.

The USB module then manages the data transfer without further intervention by firmware. When the endpoint receives an OUT token packet followed by data, the USB module stores the data in the passed buffer and sets UOWN = 0 to transfer BD ownership back to the microcontroller core.

To check for received data, the Framework’s USBHandleBusy macro first checks to see if UOWN = 0. If so, the USBHandleGetLength macro returns the number of bytes received. Firmware can retrieve and use the received data in any way. Listing 2 copies the data into winusb_bulk_in_buffer for sending back to the host in a basic loopback test. After retrieving the data, firmware can call USBGenRead again to prepare the endpoint to receive new data.

This listing shows code for sending data to the host from a bulk IN endpoint:

USB_HANDLE USBWinUsbBulkInHandle;
if (!USBHandleBusy(USBWinUsbBulkInHandle)) 
{
  // The microcontroller core owns the endpoint. 
  // Prepare to send data to the host.
  USBWinUsbBulkInHandle = USBGenWrite(WINUSB_BULK_EP, 
    (BYTE*)&winusb_bulk_in_buffer, bulk_bytes);
To send data, USBHandleBusy first checks to see if UOWN = 0. If so, a call to USBGenWrite prepares to send the data.

The function accepts an endpoint number, a pointer to a buffer that holds the data to send, and the number of bytes to send. The function sets up the transfer, sets UOWN = 1 to transfer BD ownership to the USB module, and returns a pointer to the BD.

The USB module then manages the data transfer without further intervention by firmware. On receiving an IN token packet at the endpoint, the USB module sends the data and sets UOWN = 0 to pass ownership back to the microcontroller core. Firmware can then prepare for another transfer.

At the device, bulk and interrupt transfers are identical except for the endpoint type. The only difference is in scheduling by the host. So to convert listings 2 and 3 for use with interrupt transfers, just replace every instance of bulk with interrupt and set WINUSB_INTERRUPT_EP = 2 (or whatever endpoint number the interrupt endpoint addresses are using) and set WINUSB_INTERRUPT_IN_EP_SIZE and WINUSB_INTERRUPT_OUT_EP_SIZE to match the endpoint sizes in the endpoint descriptors.

Control Transfers
Because of their multiple stages, control transfers are more complicated to program than bulk and interrupt transfers. The first step in responding to a control transfer is to detect the received request. From information received in the Setup stage, firmware can learn whether the request is directed to the whole device or to a specific interface in the device.

This listing checks values received in the Setup stage to find out if the request is directed to the WinUSB interface and if the firmware has defined the request. If so, the function examines the Setup data to determine whether the host or device sends data in the Data stage and calls a function to handle the request:

// Check the Setup packet to find out if the request is  
// directed to an interface, names the WinUSB interface ID,
// and is a Vendor request.
if(SetupPkt.Recipient != RCPT_INTF) return;
if(SetupPkt.bIntfID != WINUSB_INTF_ID) return;
if(SetupPkt.RequestType != VENDOR) return;
// It’s a vendor-specific request to the WinUSB interface.
// Decode the request and call a routine to handle it.
switch(SetupPkt.bRequest)
{
  case WINUSB_REQUEST_1:
    // The Data stage is  host-to-device.
    WinusbControlWriteTransferHandler();
    break;
  case WINUSB_REQUEST_2:
    // The Data stage is  device-to-host.
    WinusbControlReadTransferHandler();            
    break;    
}   
The example handles two requests. Request 1 has a host-to-device Data stage, and request 2 has a device-to-host Data stage.

I patterned my code to handle the control-transfer requests after similar code in the USB Framework. For requests where the device sends data to the host, I used the Get_Descriptor request as a model. Code for requests where the host sends data to the device is less common, but I found an example in the Framework’s virtual COM port example in the SET_LINE_CODING request.

Installing a Device
The other side of WinUSB communications is the PC software that detects the device, assigns a driver, and exchanges data with the device.

An INF file is a text file that Windows uses to match a driver to a device. The INF file for a WinUSB device includes the VID and PID from the device descriptor and a 128-bit value called a GUID, which applications use to identify a specific WinUSB device. The GUID’s length and the method used to generate the GUID make it highly unlikely that multiple devices will have the same GUID.

You can generate a GUID in several ways. In Microsoft’s Visual Studio Standard edition and higher, select Tools > Create GUID. Other options are Microsoft’s GUID generator, guidgen.exe, or an online GUID generator, both easily found via a web search.

To customize my project’s WinUSB INF file for your device, replace the GUID and the VID and PID with your values. The GUID is in the [Version] section’s ClassGUID item:

ClassGUID = {36FC9E60-C465-11CF-8056-444553540000}
Replace the value between the curly brackets with your GUID.

The device’s VID and PID are in the INF file’s [Manufacturer] section in this item:

%USB\MyDevice.DeviceDesc% = USB_Install,  USB\VID_0925&PID_1456
Replace the VID (0925h) and PID (1456h) with the idVendor and idProduct values in the device descriptor for your device.

To install a WinUSB device on Windows XP, the PC must have three co-installer DLLs. Microsoft’s free Windows Driver Kit (WDK) contains the files, which you can distribute with your software. You don’t need to provide the files for Windows Vista systems.

On first attachment, Windows searches for an INF file with a matching VID and PID. If needed, point the Found New Hardware Wizard to the location of the INF file and the co-installer files.

When the device is installed and ready for use, Windows Device Manager shows the device under Universal Serial Bus Controllers. To view the Device Manager, right-click My Computer and select Manage, then Device Manager.

Writing Applications
You can access WinUSB devices with Visual Basic or Visual C#, including the free Express editions. But Microsoft’s .NET Framework doesn’t provide a class for accessing WinUSB devices. Instead, applications use Windows API functions and the WinUSB API to detect and communicate with devices.

For each API function used, Visual Basic and Visual C# applications must provide a declaration. Writing a declaration requires translating Microsoft’s declaration, written in C, to the syntax and data types supported by Visual Basic or Visual C#. To call a function, you provide parameters whose data types match those in the declaration.

API functions can find a specific device by GUID value, obtain a handle for accessing the device, learn the number and type of endpoints, configure timeouts and other behavior, and exchange data using bulk, interrupt, and control transfers. If you’re not familiar with calling API functions, the programming can seem obscure, but my example applications show the way.

With this introduction to firmware and applications, you’re ready to start experimenting with USB transfers for use in your projects.

--------------------- 
作者:lanmanck 
来源:CSDN 
原文:https://blog.csdn.net/lanmanck/article/details/8883642 
版权声明:本文为博主原创文章,转载请附上博文链接!

winusb —— 不再为你的usb设备编写驱动相关推荐

  1. 微软通信winusb —— 不再为你的usb设备编写驱动

    最近应用开发的过程中出现了一个小问题,顺便记录一下原因和方法--微软通信 [blog.csdn.net/lanmanck] 曾几何时我们找工作还发现有个驱动工程师职位,薪月也不低,没触接过的人代码压根 ...

  2. 嵌入式linux 配置usb otg,嵌入式linux系统环境下USB设备的驱动实现

    0  引言 嵌入式linux系统环境以其易于移植裁减.内核小.效率高.完整.原代码开放及性能优异等特点,在嵌入式领域得到了非常广泛的应用.Linux的USB设备端的源代码中主要有USB device的 ...

  3. 一文搞懂 USB 设备端驱动框架

    关注+星标公众号,不错过精彩内容 转自 | 漫谈嵌入式 hello 大家好,今天带领大家学习一下USB 设备端驱动 内核版本:4.4.94 1. Linux USB 子系统 在介绍设备端驱动前,我们先 ...

  4. 解决供电不足造成的USB设备掉驱动

    解决供电不足造成的USB设备掉驱动,鼠标停顿.假死,等问题 来源: 神舟电脑 作者:fgwx 发表日期: 2009-10-1 15:03:29 阅读次数: 460 查看权限: 普通文章 有没有遇到过本 ...

  5. 一文入门USB设备的驱动编写方法

    摘要:本文介绍了USB设备驱动相关的基本知识结构,和编写驱动的基本步骤和流程.最后通过编写一个USB鼠标的驱动实力,讲述了简单字符型USB输入设备驱动的具体编写步骤,并给予了测试方法.文末附有完整程序 ...

  6. 如何使用 WinUSB 与 USB 设备 (USBDevice) 通信

    选择 USB 设备的驱动程序模型 https://github.com/libusbx/libusbx/wiki/Windows-Backend WinUSB does not support Win ...

  7. 如何在虚拟一个USB设备

    如何在虚拟一个USB设备 [问题点数:100分] 不显示删除回复 显示所有回复 显示星级回复 显示得分回复 只显示楼主 收藏 winterxu416 winterxu416 等级: 结帖率:98.75 ...

  8. Linux下通过CCID协议与USB设备进行交互经验总结

    Linux下通过CCID协议与USB设备进行交互经验总结 1.目标 2. 实现方法 2.1 安装libudev 2.1.1 编译安装 2.1.2 安装提示错误 2.2 编译安装libusb 2.2.1 ...

  9. usb扫描枪驱动下载 wince_wince下USB设备驱动程序

    随着USB设备的不断增加,我们这些开发人员也就多了对USB设备进行驱动程序开发的工作.但是对于很多初学者来说,存在以下三个困难: 一是对WinCE的驱动程序结构了解得太少,没办法得心应手的专注于驱动程 ...

最新文章

  1. 10个你必须知道的ios框架
  2. Struts+Hibernate+MyEclipse+Tomcat+MySQL的乱码之解决
  3. LibSvm python 调试实验
  4. Servlet实现Session
  5. Pinyin4j 的使用 Pinyin4jUtils工具类
  6. 在全员编程时代下,软件测试员又该何去何从?
  7. python socket原理 及socket如何使(tcp udp协议)
  8. python包的使用(一)——WordCloud词云
  9. 出走的门徒之一——地平线 余凯:造物主的一小步
  10. 怎么用python在淘宝抢单_淘宝抢单怎么做到秒抢 你需要知道的必杀步骤
  11. Blend 混合模式
  12. CAD如何安装才是最简单的详细教程方法呈现出来了
  13. 软件开发前言技术系列讲座
  14. CA Server证书申请与颁发 Apache2 HTTPS
  15. 阿里P8大牛手把手教你!15个经典面试问题及回答思路,全套教学资料
  16. html5课件动画制作,从此再也不担心课件/动画的开发了!
  17. 以软件测试的角度测试一支笔,如何测试一支笔.
  18. 【安全资讯】数据泄露、数据窃听,如何保障大数据时代的信息安全
  19. 中铁员工入职培训心得体会
  20. 利用ALSA库进行音频重采样

热门文章

  1. STM32/APM32 用DMA采集ADC1多通道--标准库
  2. 【Swing】图片查看器
  3. 将图像平移到画布中心python_python前端之Photoshop
  4. fuchsia hub文件系统
  5. 网络安全岗位介绍——等级保护测评师
  6. 淘宝直通车托管公司怎么样
  7. 后缀表达式看完这一篇文章就理解了!
  8. 分布式系统之-我的书单
  9. k8s——flannel网络
  10. QGIS进行坐标转换