0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于WinUSB实现的嵌入式USB免驱设备通信方式

润欣科技Fortune 2019-01-14 09:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

上海润欣科技股份有限公司创研社


引言

USB接口作为PC上最流行和通用的接口,具备可连接多种类型的设备,连接简单,即插即用,支持热插拨,多数应用场景下不需要提供独立的电源,高传输速率,高可靠性等特点,被越来越多的产品作为首选接口作为接入PC的连接方式。为了简化USB设备的开发和接入到PC系统,微软开发了WinUSB,可以将Winusb.sys作为设备功能驱动程序安装,并提供WinUSB API供应用程序访问设备。一直以来,除了USB HID设备,其他类型的设备在WINDOWS环境下需要安装驱动程序才能工作。要实现USB设备免驱,就只能使用HID设备。而HID设备传输速度慢,在有些场合必须使用Bulk类型进行批量传输时,就必须使用第三方驱动或者自己开发一个驱动,使得项目开发非常麻烦。现在好了,自从微软推出了WinUSB,在微软的最新操作系统上实现简单的Bulk类型批量传输也变得非常的方便快捷,在研发过程当中或者一些对于差异化要求不高的场合,是非常适用且容易实现的。本文致力于实现一个最简单的WinUSB通信系统,以满足此类需求。

如何让嵌入式设备枚举成WinUSB设备

系统通过USB描述符来确定以何种USB Class类型来工作。如果希望WINDOWS能够将嵌入式设备识别为WinUSB设备,则其描述符至少应当包含以下字段:

1、支持OS 字符串描述符:

为了让 USB 驱动程序堆栈了解设备支持扩展的特征描述符,设备必须定义存储在字符串索引 0xEE 处的 OS 字符串描述符。在枚举过程中,驱动程序堆栈查询字符串描述符。如果存在描述符,驱动程序堆栈会假定设备包含一个或多个 OS 特征描述符和检索这些特征描述符所需要的数据。检索的字符串描述符具有bMS_VendorCode字段值。该值为1表示USB驱动程序堆栈必须用来检索扩展特征描述符的供应商代码。

#define bMS_VendorCode ( 0x01 )

// "MSFT100" : index : 0xEE : langId : 0x0000

const U8 OS_StringDescritpor[ ] =

{ 0x12, 0x03, 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, bMS_VendorCode, 0 };

2、设置兼容ID特征描述符:

const U8 WINUSB_ExtendedCompatId_Descritpor[ ] =

{

0x28, 0x00, 0x00, 0x00, // dwLength

0x00, 0x01, // bcdVersion

0x04, 0x00, // wIndex

0x01, // bCount

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved[7]

0x00, // bFirstInterfaceNumber

0x01, // RESERVED ( 0x01 )

'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compactiableID[8]

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompactiableID[8]

0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved[6]

};

注:WinUSB还支持复合设备,对于单一传输类型最简系统,我们忽略复合设备的要求即可。compatibleID字段必须指定 "WINUSB" 作为字段值。其他可以根据需求更改。

3、注册设备接口 GUID描述符:

该描述符用于区分不同的WinUSB设备。

const U8 WINUSB_ExtendedProperty_InterfaceGUID_Descritpor[ ] =

{

0x8E, 0x00, 0x00, 0x00, // dwTotalSize = Header + All sections

0x00, 0x01, // bcdVersion

0x05, 0x00, // wIndex

0x01, 0x00, // wCount

0x84, 0x00, 0x00, 0x00, // dwSize -- this section

0x01, 0x00, 0x00, 0x00, // dwPropertyDataType

0x28, 0x00, // wPropertyNameLength 'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,'I',0,'n',0x00,'t',0,'e',0,'r',0,'f',0,'a',0,'c',0,'e',0, 'G',0,'U',0,'I',0,'D',0,0,0,

0x4E, 0x00, 0x00, 0x00, // dwPropertyDataLength : 78 Bytes = 0x0000004E

'{',0,'1',0,'2',0,'3',0,'4',0, '5',0,'6',0,'7',0,'8',0,'-',0,'1',0,'2',0,'3',0,'4',0,'-',0,'1',0,'3',0,'4',0,'4',0,'-',0,'1',0,'2',0,'3',0,'4',0,'-',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,'A',0,'B',0,'C',0,'}',0,0,0

};// bPropertyData : WCHAR : L"{12345678-1234-1234-1234-123456789ABC}"

4、端点描述符:

按实际的需求的配置端点数量和类型,即可完成嵌入式设备的描述符配置了。

一般固件程序可以通过MCU厂家提供的范例程序进行修改,这里省略USB固件功能的说明。只要包含以上三个描述符中的必须的字段,就可以成功枚举成USB Device。枚举成功后在设备WINDOWS设备管理器中可看到类似设备,如下图1所示。

1544663705964878.png

图1 成功枚举为USB Device

如何编写PC应用程序与嵌入式设备进行USB通信

PC机软件相对来说比较简单,并且微软官方也给出了示例代码。唯一需要注意的是,对应的软件程序获取WinUSB设备句柄的GUID参数,需要与嵌入式设备的描述符中的GUID保持一致。GUID是WinUSB用以区分设备的唯一标志。GUID,是Globally Unique Identifier的简称,翻译为全局唯一标识符,是一种由算法生成的二进制数据,长度为128位的数字标识符。

具体实现步骤如下:

1、创建设备的文件句柄:

调用 SetupDiGetClassDevs 获取设备信息集的句柄;调用 SetupDiEnumDeviceInterfaces 枚举设备信息集中的设备接口并获取有关设备接口的信息;调用 SetupDiGetDeviceInterfaceDetail 获取设备接口的详细信息,所获取的信息通过SP_DEVICE_INTERFACE_DETAIL_DATA结构返回。由于该结构大小无法提前获取,故需连续两次调用该函数,第二次调用时接口详细信息将填充到根据第一次调用返回值所确定大小的该缓冲区,通过缓冲内该结构的DevicePath成员中可获得“设备路径”。

2、获取设备的 WinUSB 接口句柄:

调用 WinUsb_Initialize通过传递在创建设备的文件句柄中创建的文件句柄。

3、查询设备以获取 USB 描述符:

接下来,查询设备以获取特定于 USB 的信息,如设备速度、接口描述符、相关端点及其管道。调用 WinUsb_QueryDeviceInformation 从设备的设备描述符请求信息。调用 WinUsb_QueryInterfaceSettings 并传递设备的接口句柄,以获得对应的接口描述符。调用 WinUsb_QueryPipe 获取有关每个接口每个终结点的信息。此步骤不是必须的,因为端点方向及传输特性由嵌入式设备描述符决定,是已知的。

4、向默认端点发送控制传输:

此步骤也不是必须的。一般都不通过默认端点发送有效载荷。

5、发送 I/O 请求:

将数据发送到设备的批量输入和批量输出端点,这些端点点可分别用于读取请求和写入请求。调用 WinUsb_ReadPipe 从设备的批量输入端点读取数据。调用 WinUsb_WritePipe 通过批量输出端点将数据写入设备。在嵌入式设备的输出端点内写入数据之后,就可以在PC端读出数据。反之,如果在PC端对嵌入式设备的输入端点写入数据,则嵌入式设备会产生一个USB端点写入事件,具体如何捕捉该事件,则由MCU厂家的产品硬件决定,产生相应的中断信息,供中断服务程序来判断。一般而言,芯片厂家会提供MCU的USB通信基础范例程序,在其基础上做简单的修改和适配即可。

6、释放设备句柄

在完成对设备的所有必要的调用之后,释放设备的文件句柄和 WinUSB 接口句柄。CloseHandle 释放由 CreateFile 创建的句柄。

WinUsb_Free 释放由 WinUsb_Initialize 返回的设备的 WinUSB 接口句柄。

至此,已经完成了嵌入式设备端固件的USB代码移植和PC端应用程序的编写,就可以实现USB免驱设备的通信方式了

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5209

    文章

    20625

    浏览量

    336759
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    2025嵌入式开发教程|远航哥

    https://www.bilibili.com/opus/1178756596191199237 嵌入式通信协议三剑客:串口、I2C与SPI的深度解析 在嵌入式系统开发中,通信协议是
    的头像 发表于 03-20 17:35 1309次阅读
    2025<b class='flag-5'>嵌入式</b>开发教程|远航哥

    什么是嵌入式应用开发?

    实现和部署,还包括硬件选择、软件设计、测试、集成和维护等流程‌。 定义和背景 嵌入式应用开发是指将软件部署到嵌入式系统中,这些系统广泛应用于消费电子和工业自动化中。嵌入式系统通常
    发表于 01-12 16:13

    C语言在嵌入式开发中的应用

    C 语言在汽车电子控制系统开发中的主导地位。 2、设备驱动程序 设备驱动程序是嵌入式系统中连接硬件和软件的桥梁,它负责实现嵌入式系统与
    发表于 11-21 08:09

    嵌入式和FPGA的区别

    效。 典型应用场景 嵌入式系统广泛应用于: 消费电子产品(智能家居、穿戴设备) 工业控制(PLC、HMI) 汽车电子(ECU、信息娱乐系统) FPGA则更多出现在: 通信系统(5G基站
    发表于 11-19 06:55

    嵌入式系统的定义和应用领域

    嵌入式系统,简而言之,就是一种专为特定设备或装置设计的计算机系统。它们通常配备一个嵌入式处理器,其控制程序被存储在ROM中。这些系统在许多日常用品中都有广泛的应用,例如手表、微波炉、录像机和汽车等
    发表于 11-17 06:49

    嵌入式需要掌握哪些核心技能?

    /网络设备)、中断底半部处理,适用于高端嵌入式设备。 企业需求:RTOS是60%岗位的核心要求,Linux开发需求随项目复杂度增长。 4)通信协议与接口 基础协议:UART、SPI、
    发表于 10-21 16:25

    嵌入式达到什么水平才能就业?

    :包括GPIO、定时器、中断、ADC 等外设的配置与调试,能实现如温湿度采集、电机控制等功能掌握嵌入式 Linux 驱动开发基础:能编写简单字符设备驱动,实现
    发表于 09-15 10:20

    广州邮科嵌入式通信电源系统:提升通信设备稳定性与效率的关键

    在今天的信息化社会,嵌入式通信电源系统已经成为许多通信设备的核心组成部分。特别是在广州邮科,嵌入式通信
    的头像 发表于 08-30 11:01 731次阅读
    广州邮科<b class='flag-5'>嵌入式</b><b class='flag-5'>通信</b>电源系统:提升<b class='flag-5'>通信</b><b class='flag-5'>设备</b>稳定性与效率的关键

    外部晶振在USB转串口模块的应用

    在工业设备嵌入式系统以及各类专业仪器中,串口通信依然是关键的数据传输方式。为适应现代计算机,USB 转串口模块应运而生。可将
    的头像 发表于 08-12 17:28 1558次阅读
    外部晶振在<b class='flag-5'>USB</b>转串口模块的应用

    入行嵌入式应该怎么准备?

    任务调度的代码是非常重要的。此外,了解操作系统内核的工作原理以及与硬件交互的方式也是必须的。 四、通信协议嵌入式系统通常需要与其他设备或系统进行
    发表于 08-06 10:34

    嵌入式开发就业还有前景吗?

    。在智能家居领域,嵌入式开发的主要工作是开发各种智能化设备和系统,如智能照明、智能安防、智能家电等。嵌入式开发人员需要掌握相关的硬件和软件技术,如处理器、传感器、通信技术、操作系统等,
    发表于 07-16 10:47

    Linux嵌入式和单片机嵌入式的区别?

    Linux嵌入式与单片机嵌入式在多个方面存在显著的区别,以下是详细的比较和归纳: 一、基本概念 1. Linux嵌入式: 定义:将Linux操作系统运行在嵌入式
    发表于 06-20 09:46

    嵌入式力矩电机设计及其系统仿真分析

    摘要:针对所要设计的转塔刀架嵌入式力矩电机的应用领域和技术指标,计算确定了嵌入式力矩电机的初步尺寸及各项性能参数,分别建立了基于 AnsofRMxpr 的力矩电机系统仿真模型
    发表于 06-11 15:11

    嵌入式开发入门指南:从零开始学习嵌入式

    特定功能的计算机系统,广泛应用于智能家居、工业控制、医疗设备、车载系统等领域。 2. 学习嵌入式开发的前置知识熟悉C语言编程掌握基本的数据结构与算法了解数字电路与微控制器原理熟悉Linux操作系统
    发表于 05-15 09:29

    一文看懂:嵌入式与壁挂工控机安装方式的关键差异

    在工业自动化领域,工控机作为核心控制设备,其安装方式的选择直接影响设备运行稳定性与后期维护便捷性。嵌入式工控机和壁挂工控机是常见的两种类型
    的头像 发表于 05-14 14:40 1180次阅读