USB驱动开发
STM32自定义USB设备开发详细流程讲解及全套资料源码下载
11
0xE0,
/* bmAttributes: Bus powered */
12
/*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits */
13
0xFA,
/* MaxPower 500 mA: this current is used for detecting Vbus */
10 {
11
CUSTOMHID_SIZ_STRING_VENDOR, /* Size of Vendor string */
12
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
13
// Manufacturer: "STMicroelectronics"
03 {
04
CUSTOMHID_SIZ_STRING_LANGID,
05
USB_STRING_DESCRIPTOR_TYPE,
06
0x09,
07
0x04
08 }; /* LangID = 0x0409: U.S. English */
09 const uint8_t CustomHID_StringVendor[CUSTOMHID_SIZ_STRING_VENDOR] =
18
0x00,
/* bInterfaceNumber: Number of Interface */
19
0x00,
/* bAlternateSetting: Alternate setting */
20
智能家居监控系统USB摄像头驱动的开发与实现
— _
D v e r es一 >/选择 U p ot S pr 一 > 】 u
— - — — — —
US u p r Bsp o t
{} S p o r o ts eU B u p rf s- i S t oH d
像 头是 U B .协议的。 S1 1 U B只是一个总线 , S 只提供一个数据通路 。 S U B总线 驱动程序并不知道一个设备具体如何操作 , 有哪些行 为。 个设备具体实现什么功能 , 由设备 自己来决定 。 于 要 对
一
译进 内核 , 具体实现如下 :
ma eme u o fg k n cn i
h s e di t ot npo 表示 ,它 们之 间的 n
关系如图 3 所示 。
D v e r es一 > / ei i r cD v / 选择设备 Z 3 1 C 0
< >M utme i u p r 一 l i das p o t > 木 木M ut e i o es p o t 宰术 术 li d ac r u p r 水 m <水 Vi e o i u > d 0F rL n x
[ U Bdv e l yt (E R C T D 木 S ei e s m D P E A E ) 】 cf s e i
[ U Bdv e l sdvcs E R C T D S ei a - ei ( P E A E ) ] ccs eD
< > OHCIHCD u p r sp o t
译进入 内核 , 内核初始化时 自动加载 , 在 本设计采用 的是 编译进 内核的方式 。 由于在 Lnx 2 . . iu一 .3 6的内核 中已有 68 Z 0 0 的驱 动代码 , C31 我们只需要修改 配置菜 单 , 使其 编
WindowsCE下USB摄像头驱动开发以OV511为例附带全部源代码以及讲解
这部分讲解如何在Windows 下实现 一样的功能。
Windows 的控制传输
查看MSDN,IssueControlTransfer和 IssueVendorTransfer是用来进行控制传输的,但两个函数 有什么区别呢? 看MSDN,IssueControlTransfer的第一个参数是 hPipe,就是说,在使用IssueControlTransfer之前,必须 用OpenPipe打开管道。 OpenPipe函数需要端点描述作为参数。但是,端点0是 没有这个描述可以用的(MSDN: However, endpoint zero (0) never has a USB_ENDPOINT structure)。 我没测试自己指定描述是否可以,但是, IssueVendorTransfer提供了更为方便的途径。这个函数默 认从端点0进行控制传输。 如果是其他端点的控制传输,是要用 IssueControlTransfer的。
Windows 下 流接口USB驱动程序加载的流程
6.接着CAM_Init函数被调用,参数就是ActiveDevice函数的 参数1,然后依据这个参数,在注册表中找到USB驱动程序的上下 文,并返回,这样对该流接口驱动的操作,就可以找到USB驱动 的上下文,并且交换数据。 以上这些工作完成之后,USB设备的信息被保存,并且USB 驱动程序上下文也被流接口驱动所记载。流接口USB驱动的加载 完成。我们就看见那个输入驱动程序名称的对话框消失了。如果前 面6个步骤中任何一步不成功,将不会使用这个驱动程序,会反复 弹出这个对话框,提示输入驱动程序名称,直到这些过程全部正确 完成。
HKEY_LOCAL_MACHINE\Drivers\Active中的项目。 注意:USB驱动程序不通过注册表API来操作注册表,而是通过 USBD提供的函数。
linux usb wifi驱动开发原理
linux usb wifi驱动开发原理Linux USB WiFi驱动开发原理一、引言随着无线网络的普及,WiFi成为了人们生活中不可或缺的一部分。
而在Linux操作系统中,为了支持各种WiFi设备,需要进行对应的驱动开发。
本文将介绍Linux USB WiFi驱动开发的原理和过程。
二、USB WiFi驱动开发的基本原理1. USB接口USB(Universal Serial Bus)是一种通用的串行总线标准,用于连接计算机与外部设备。
USB WiFi设备通过USB接口与计算机通信,传输数据和控制命令。
2. 驱动程序驱动程序是用于操作和控制硬件设备的软件。
USB WiFi驱动程序负责与USB WiFi设备进行通信,实现数据的传输和接收。
驱动程序需要与操作系统紧密结合,通过操作系统提供的API接口与设备进行交互。
三、USB WiFi驱动开发的过程1. 设备识别与初始化USB WiFi设备插入计算机后,操作系统会通过USB子系统进行设备的识别和初始化。
在Linux系统中,USB设备的识别和初始化由USB核心驱动完成。
核心驱动会根据设备的VID(Vendor ID)和PID (Product ID)来匹配对应的驱动程序。
2. 驱动程序注册驱动程序需要在Linux系统中进行注册,以便系统能够正确识别和加载驱动。
注册过程通常包括向系统注册设备类型、设备ID等信息。
3. 设备操作接口的实现驱动程序需要实现设备操作接口,包括设备的打开、关闭、读取数据、写入数据等功能。
这些操作接口是通过USB子系统提供的API 来实现的。
4. 数据传输与控制USB WiFi驱动程序需要实现数据的传输和控制功能。
数据传输主要包括从设备读取数据和向设备写入数据,而控制功能包括设置设备参数、配置网络等操作。
5. 错误处理与调试在USB WiFi驱动开发中,错误处理和调试是非常重要的一部分。
驱动程序需要处理各种异常情况,如设备断开连接、传输错误等。
CE中USB HID设备驱动开发
一. 理解: CE中USB HID设备的工作流程要想知道如何去设计一个自己的HID设备的驱动程序. 那么对CE中的USB HID设备工作的流程的初步了解是十分必要的. Microsoft公司已经在CE系统中增加了键盘/鼠标两种HID设备的驱动. 我们就从键盘驱动入手.CE的所有USB程序都在public\common\oak\drivers\usb下面. 在该文件夹下,分成了CLASS,CLIENTS,COMMON,HCD,INC,USBD几个文件夹,其中INC和COMMON里面有一个lock.c的程序,这个程序很明显是将要被其他USB有关的驱动程序所使用的一个锁,代码很简单,只是一个类似临界区的封装体,可以保护多线程对同一内存区域的读写访问,可以先不去管它。
CLIENTS文件夹可能最初微软的开发人员是用来放置设备驱动程序的,但是后来没有放,而发布的时候也没有删除,所以遗留了下来,里面是个空的文件夹,所以没用实际用处。
USBD和HCD是前述的底层驱动,里面含有很多子文件夹和程序,由于我们只针对USB设备驱动,因此对这两部分不做分析,有兴趣的朋友可以自己去了解. 重点就在CLASS文件夹了,展开来看,里面又包含了COMMON、HID、PRINTER、STORAGE几个文件夹,同样,COMMON里面存放的源程序是为HID、PRINTER、STORAGE 所共有的。
HID是USB输入设备如键盘/鼠标的样例驱动程序,PRINTER是USB打印机的样例驱动程序,STORAGE 是USB存储设备如U盘的样例程序.我们在这篇文章中只讲如何设备USB HID设备驱动. 因此我们只看HID路径下的所有程序.在HID下有CLIENTS和HIDCLASS两个文件夹. HIDCLASS里有所有HID设备驱动的共用代码(MDD和PDD). 我们在这里暂时不讲述.对于一个对CE系统不是非常熟悉的新手来说. 要想知道USB HID设备自插入后. 在Windows CE这个黑盒子里是怎么运行的. 里面到底发生了什么事. 我个人觉得最好在每个程序里设置一些标记. 通过串口将里面所发生的事情传出来并打印到我们的调试PC上面. 我们可以用:RETAILMSG(1, (TEXT(“HIDDeviceNotifications---conshid\r\n”)));来告诉程序员此时调用了conshid.cpp文件下的HIDDeviceNotifications函数.在将HID路径下所有的函数中增加了标记后. 编译.. 下栽…运行… 插入一个USB键盘后. 从串口处的到的信息如下:>DllEntry--usbhid (1)>HidMdd_DllEntry--hidmdd>USBDeviceAttach--usbhid>ParseUsbDescriptors--setup (4)>CreateHidInterface--setup (5)>Init--hidmdd>HID_Init--usbhid>SetUsbInterface--setup>SetReportProtocol--setup>GetReportDescriptor--setup>SetQueuedTransfers--setup>HidMdd_Attach--hidmdd (6)InitializeTLCStructures--hidmdd>LoadHidClients--hidmdd>FindClientRegKey--hidmdd>OpenClientRegKey--hidmdd>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:2362_9488_256>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:2362_9488>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:2362>OpenSpecificClientRegKey--hidmdd>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:0_1>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:0>OpenSpecificClientRegKey--hidmdd>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:1_2MOUHID DllEntry! (7)Mouse Attached!>AllocateUsageLists--mouhidCreateInterruptThread--setupMouseThreadProc!>InterruptThreadProc--setup>StartInterruptTransfer--setup>StartInterruptTransfer--setup>StartInterruptTransfer--setup>StartInterruptTransfer--setup>USBDeviceNotifications--usbhid>USB_CLOSE_DEVICE>HidMdd_Notifications--hidmddFreeHidContext--hidmdd>HIDDeviceNotifications--mouhidMouse moved!MOUHID DllEntry!>StartInterruptTransfer--setup>DllEntry--usbhid>HidMdd_DllEntry--hidmdd从以上的信息我们可以看出. 一插入USB鼠标. 系统就会调用usbdhid.cpp中的DllEntry这个动态链接库的入口函数. 这个比较好理解. 然后系统将调用hidmdd中的HidMdd_DllEntry函数. 这两个函数所做的工作不多. 我们基本可以不用太关心这两个函数.一旦系统发现有新的HID设备.usbhid中的USBDeviceAttach这个函数被调用. USBDeviceAttach中又调用(4)ParseUsbDescriptors主要是分析此USB设备的描述符. 在分析此USB设备为HID类设备后. 调用(5)CreateHidInterface. 主要是建立一个HID设备上下文. 并给这个设备上下文赋值. 这里的提一下. 在CreateHidInterface函数中调用了HidMdd_Attach这个函数. 传给这个函数的参数为分析得到的USB设备的描述符.这个在第(6)步可以看的出来. 在HidMdd_Attach中产生一个HID设备上下文.我怀疑这个函数中调用的那个HidP_GetCollectionDescription是处理HID设备的驱动文件位置有关系.但这个函数只是PUBLIC\COMMON\OAK\LIB\ARMV4I\RETAIL下的一个库文件中的函数. 见hidparse.def. 这个函数的参数主要是设备报告描述符和PHID_CONTEXT指向HID设备上下文的指针. 在*PHID_CONTEXT结构中我们看到有HidTLCQueue *pQueues.和一个struct _HID_CLIENT_HANDLE元素. 还有就是HID设备的其他描述符号HIDP_DEVICE_DESC及设备句柄._HID_CLIENT_HANDLE结构在hiddi.h中可以看出来. 里面有DWORD dwUsagePage;和DWORD dwUsage;在HidMdd_Attach用InitializeTLCStructures初始化该上下文. 最后用LoadHidClients 函数加载这个USB HID设备. 在LoadHidClients中寻找并注册本USB设备注册键.调用FindClientRegKey. 这个函数的参数有两个. &driverSettings. pClientHandle->driverSettings.类型分别是:HID_DRIVRE_SETTINGS 和PHID_CLIENT_HANDLEFindClientRegKey调用OpenClientRegKey函数. 这是根据HID设备的信息来寻找驱动.在OpenClientRegKey函数中多次调用OpenSpecificClientRegKey寻找匹配的HID设备.在OpenSpecificClientRegKey中我们在pszKey = szBuf;后面加一条调试信息:RETAILMSG(1,(TEXT("OpenSpecificClientRegKey key string:%s\r\n"),pszKey));调试信息如下. OpenSpecificClientRegKey key string:2362_9488_256 (21A)>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:2362_9488 (21B)>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:2362 (21C)>OpenSpecificClientRegKey--hidmdd>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:0_1 (31A)>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:0 (31B)>OpenSpecificClientRegKey--hidmdd>OpenSpecificClientRegKey--hidmddOpenSpecificClientRegKey key string:1_2 (41A)通过PC上的USB device viewer软件可以看出这个鼠标的idVendor/idProduct/bcdDevice分别是:0x093A/0x2510/0x0100. 转成十进制为:2362/9488/256与第一次得到的注册字键字符串吻合.这个鼠标的接口描述符中的bInterfaceClass/bInterfaceSubClass/bInterfaceProtocol分别是: 0x03 / 0x01 / 0x02. 这个与最后一个字符串相符. 但中间的0_1和0就不明白.当我一直在为驱动程序的注册表位置与HID设备类型的关系而绞尽脑汁时候.看到OpenClientRegKey函数有一段Microsoft的注释:可能是微软为了加快读者对这个问题的理解而特别写的注释.// The order of verndor precedence is described below.//// idVendor_idProduct_bcdDevice (21A)// idVendor_idProduct (21B)// idVendor (21C)// Default// The order of interface precedence is described below.//// bInterface_bCollection (31A)// bInterface (31B)// Default// The order of TLC precedence is//// UsagePage_Usage (41A)// UsagePage// Default// So the order of checking would be (50A)// 1.idVendor_idProduct_bcdDevice\bInterface_bCollection\UsagePage_Usage// 2.idVendor_idProduct_bcdDevice\bInterface_bCollection\UsagePage// .....// 42.Default\bInterface_bCollection\Default// 43.Default\bInterface\UsagePage_Usage// 44.Default\bInterface\UsagePage// 45.Default\bInterface\Default// 46.Default\Default\UsagePage_Usage (54_7A)// 47.Default\Default\UsagePage// 48.Default\Default\Default大家再看下common.reg下的[HKEY_LOCAL_MACHINE\Drivers\HID\LoadClients\Default\Default\1_2\Mouse] (61A)"DLL" = "MOUHID.DLL"这里的MOUHID.DLL正是我们的的USB鼠标的驱动程序. 那么在注册表文件中. 这个1_2是什么意思呢?从以上的注释的出的结论就是1_2原来就是设备的UsagePage_Usage. 而不是设备描述符的bInterfaceSubClass/bInterfaceProtocol.搜索的顺序应该是以50A以下的48种方式搜索. 我们在common.reg下定义的注册位置就是按照(54_7A)方式来存放的.这两个数据在FindClientRegKey中是由rgdwTLCVals[]传给OpenClientRegKey函数的.首先看bInterface_bCollection两个数据是怎么的到的.在FindClientRegKey函数中.看到:const DWROD rgdwInterfaceVals[]={pDriverSettings->dwInterfaceNumber,pDriverSettings->dwCollection};这个rgdwInterfaceVals是OpenClientRegKey的一个参数. 这个也是在寻找驱动时候的一个依据bInterface_bCollection. rgdwInterfaceVals是由LoadHidClients函数的第5个参数DWORD dwInterface赋值pDriverSettings->dwInterfaceNumber = dwInterface;pDriverSettings->dwCollection = pCollection->CollectionNumber;而PHIDP_COLLECTION_DESC pCollection = &pHidContext->hidpDeviceDesc.CollectionDesc[dwIdx]赋值的. 首先跟踪dwInterface其实是HidMdd_Attach中第7个参数. HidMdd_Attach是被setup.cpp中的CreateUsbHidDevice函数调用的. 看到CreateUsbHidDevice调用HidMdd_Attach的第7个参数其实就是pUsbHid->pUsbInterface->Descreiptor.bInterfaceNumber.这个其实就是在USB设备的接口描述符Interface Descriptor中的接口序列号. 在我的USB鼠标中只有一个接口. 因此在结构描述符(Configuration Descriptor)中的bNumInterfaces数值为1. bInterfaceNumber也就是只有0了. 而在我的USB键盘结构描述符(Configuration Descriptor)中的bNumInterfaces数值为2. 因此这个设备就有两个接口啦. 两个接口从0开始. 分别为0和1. 可以从下面的USB键盘所打印的信息看出以上的理解也是对的;还有bCollection是由&pHidContext->hidpDeviceDesc.CollectionDesc[dwIdx]->CollectionNumber的来的. 最后是从USB设备上下文HID_CONTEXT中的HIDP_DEVICE_DESC hidpDeviceDesc的来的.HIDP_DEVICE_DESC 就是HID设备的HID描述符. 比如下是另一个USB键盘的HID描述符组合:U8 HID_ReportDescriptor[63] = { //键盘. 可以通过使用HID Descriptor tool来生成,这个工具可以到下载//表示用途页为通用桌面设备0x05, 0x01, // USAGE_PAGE (Generic Desktop)//表示用途为键盘0x09, 0x06, // USAGE (Keyboard)//表示应用集合,必须要以END_COLLECTION来结束它,见最后的END_COLLECTION0xa1, 0x01, // COLLECTION (Application)//表示用途页为按键0x05, 0x07, // USAGE_PAGE (Keyboard)//用途最小值,这里为左ctrl键0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)//用途最大值,这里为右GUI键,即window键0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)//逻辑最小值为00x15, 0x00, // LOGICAL_MINIMUM (0)//逻辑最大值为10x25, 0x01, // LOGICAL_MAXIMUM (1)//报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为10x75, 0x01, // REPORT_SIZE (1)//报告的个数为8,即总共有8个bits0x95, 0x08, // REPORT_COUNT (8)//输入用,变量,值,绝对值。
winusb设备的开发方法
winusb设备的开发方法
开发WinUSB设备涉及一些复杂的步骤和概念,需要一定的专业
知识和经验。
以下是开发WinUSB设备的一般步骤和方法:
1. 硬件设计,首先需要设计和制造符合WinUSB标准的硬件设备。
这可能涉及选择合适的芯片、接口和电路设计。
2. 驱动程序开发,WinUSB设备需要相应的驱动程序来与Windows操作系统进行通信。
通常使用微软提供的WinUSB驱动框架
来开发驱动程序。
开发驱动程序需要熟悉Windows Driver Kit (WDK) 和 Windows Driver Framework (WDF)。
3. USB描述符配置,在设备固件中配置USB描述符,以确保设
备能够正确地与Windows系统进行通信。
描述符包括设备描述符、
配置描述符、接口描述符等。
4. 测试和调试,在开发过程中需要进行大量的测试和调试工作,确保设备和驱动程序的稳定性和兼容性。
可以使用微软提供的HLK (Windows Hardware Lab Kit) 进行测试。
5. 证书签名,最终的WinUSB驱动程序需要通过微软的数字签名认证,以确保安全性和兼容性。
这需要申请和获取相应的数字证书。
需要注意的是,开发WinUSB设备需要一定的专业知识和经验,包括硬件设计、驱动程序开发、USB协议等方面的知识。
此外,开发过程中可能会遇到各种问题和挑战,需要耐心和细心地解决。
最好的方法是参考微软官方文档和开发者社区的经验,以及与经验丰富的开发者进行交流和讨论。
USB设备的驱动程序实现
USB设备的驱动程序实现
USB驱动是用来控制使用USB接口的设备的软件程序,其实现是将实
际的硬件设备抽象为虚拟的设备,使其能够在计算机操作系统上应用。
一
般来讲,当你将USB设备插入你的计算机时,它将通过计算机的USB主控
芯片找到USB设备,然后测试它的功能,并决定它是否能够被用来通信,
最后安装相应的驱动程序。
实际的USB驱动程序的实现有若干方法,其中
有两种常用的技术:应用程序编程接口(API)和驱动程序模板。
1、应用程序编程接口(API)
API是一组用于访问操作系统提供的服务和功能的特殊指令序列。
应
用程序编程接口(API)可以用来创建USB驱动程序,其实现包括以下步骤:
(1)定义硬件设备的描述
在编写USB驱动程序时,首先需要定义硬件设备,即定义设备的功能,记录其编号、最大支持通信速率、硬件连接方式、发送和接收设备数据的
方式以及支持的驱动软件要求等信息。
(2)实现设备驱动的关键函数
关键函数是控制USB设备正常工作所必需的函数,包括初始化函数、
发送和接收数据的函数、获取设备状态的函数以及关闭设备的函数等。
WinCE6.0下双模终端的USB转串口驱动开发
0 引 言
我国 3 G牌 照 的 发放 , 宣告 了 3 时代 的到 来 , G
基于 T —C MA和 C MA WC MA 的双 模 终 端 将 DS D D / D 取代 2 时代 的单 模 终 端 。诺 基亚 、 星 、 为 、 G 三 华 中 兴等 国 内外 通 信 厂 商 都 积 极 投 入 到 双 模 手 机 终 端 的开发 中来 , 目前 双模 手 机终 端 的研发 已经 成 为热 点 。当前市场 中主要 的智 能手 机操 作 系统 有 : o i N ka 主推 的 Sm in 开 放 内核 的嵌 入 式 Ln x 微 软 的 y ba , iu , WiC n E等 。由于 WiC 6 0嵌人 式 系统具 有实 时性 n E.
Wi E. U B设备驱动开发只提供了一些底层支持 n 60对 S C
的原因, 以通 信 模 块 厂 商 未 提 供 WiC 6 0下 的 所 nE .
U B驱 动 , 要 实 现 通 信 模 块 的基 本 功 能 , 开 发 S 而 除
纯 U B驱 动 外 , WiC 6 0下 , 需 要 修 改 Mo S 在 nE. 还 . d m源码 , e 存在 着开 发 周 期 长 、 作量 大 、 容 性 差 工 兼 等 问题 , 给开发 人 员带 来 了极 大 的不 便 。而通 过 串 口直接对 Mo e dm进 行操作 , 不仅 避 免 了上述 在开 发 中存 在 的问 题 , 时 由于操 作 Mo e 的 是 虚 拟 串 同 dm 口, 由它来 适 配 Moe 不 会 出 现 由物 理 串 口操 作 d m, Mo e 时制 约 M d m处理速 率 的问题 , 然保持 了 dm oe 仍 U B高 速的特 点 , 开 发人 员 只 需 开发 出对应 模 块 S 故 的 U B转 串 口驱 动 亦 可实 现 上 网 、 电话 等 功 能 ; S 打
基于ThreadX实时操作系统的USB设备驱动开发
tx kernel enter(1
‘ ix initialize hish level和
_
tx Initialize low level ●
tialize high level初 始 化 Threadx的
调 刚tx_application define(} _
_
—
各 个 组 件 ,调 用 tx_application_de—
ThreadX is also widely used in embedded field.This paper describes the USB driver structure of ThreadX with actual project
and the com plete process of the development of USB device driver.This paper focuses on the analysis of USB ControUer and verifies the stability by using the Class of ThreadX.
钟 和 定 时 器 以 及 中 断 处理 。
调 ̄Jmain()
1.2 ThreadX启 动 过 程
‘
系 统上 电后 ,首先 是 注册 中 断 向量 表 ,紧接着 就是调用主函数 main(),在 主 函数 中进入 tx_kernel_enter(),进而 依 次调 用 _tx—initialize_low_level初 始 化 跟特 定 硬件 相 关 的部 分 ,调 用_tx_ini—
ThreadX 是 由 美 国 Express Logic公 司 开 发 的 一 款 实 时 操 作 系 统 [3],适 用 于 嵌 入 式 应 用 ,支 持 大 量 的处 理 器 和 SoC,包 括 ARM厂mumb、AVR32、BlackFin、Hitachi H8/300H 等 ,因 此 广 泛 应 用 于 消 费 电子 、汽 车 电子 、工 业 自动 化 、军 事 与 航 空 航 天 等 领 域 中 。 目前 ThreadX 已经 占有 全 球 第 三 大 硬 实 时 操作 系统 市 场 份 额 [ 。
嵌入式Linux系统下的USB驱动程序开发
程 中 的关键技 术 。
关键 词 : 嵌入 式 ; L i n u x ; U S B ; 驱动 开发 中图分 类号 : T P 3 1 6 文献标 识码 : A
De v e l o p me n t o f US B Dr i v e r Ba s e d o n Em b e d d e d Li n u x S y s t e m
L I C h u n - b o , C HE N We i - f e n g , L A I X u e - j i n
( C h e n g d u U n i v e r s i t y o f T e c h n o l o g y , C h e n g d u 6 1 0 0 5 9 , C h i n a )
Abs t r a c t : The a p pl i c a t i o n s o f Emb e d de d L i n ux s y s t e m a r e mo r e a n d mo r e wi de l y , i t s f u n c t i o ns a r e a l s o mo r e a n d mo r e
H O S T) 、 U S B设 备 ( U S B D E V I C E) 、 U S B 集 线 器
哑 I … ● I _ l C 【 l h 】 i n 国 a I n 集 t e g r 成 a t e d 电 C i r 路 c u i t
————— 珏 斗 。 ]I
嵌入式 L i n u x系统下的 US B驱动程序开发
USB设备驱动程序的研究与开发
种 例 程 的指 针 等 。其 相关 代码 如下 :
H ̄插 即用例 程人 口 l l J D i r be t > r eE tni > d D v e : r eO jc - D i r xe s n- A d ei v v o c
口。而要 实 现U B 件 设备 与 主机 间 稳定 的数 据 S硬
传 输 ,则 不 可避 免 的要 编 写适 合U B 件要 求 的 S硬
驱 动 程序 。为此 ,本 文结 合 实 例 ,论 述 了U B S 设
备 驱动 程序 的具 体实 现机 制和 开发 方法 。
示 是其 体 系结构 图。
/ R 发送 给下 层 的U B / 将U B S 总线 驱动 程序
D i r bet > aoF n t n【R _ _ R — r eO jc 一 M jru c o I P MJC E v i
A E =D v rae T] rC et;
nSa s sC l S D fo ub tt u =U b a U B I( , r); t l d
4 U B 备 驱 动 程 序 的 实现 S设
驱 动程 序 是一 些例 程 的集 合 ,它 一般 被 动地 存 在 ,以等 待 主 机 系统 软 件 (n 管 理 器 、I PP / O管 理 器 、 电源管 理器 1来 调用 。典 型 的U B 备 驱 S设 动 程序 主要 包 括若 干 例程 ,其 中有 驱 动程 序入 口
31 I P 求包 . R 请
个U B S 系统 的分 层 结 构 。 图 中 ,功 能层 负 责 实 现
U B 备 的特 定 功能 。该 层 不 需 要 理 解U B 体 S设 S具
嵌入式linux下基于libusb的USB驱动开发
种通 信 协 议 , 支 持 主 系 统 (ot和 U B 的 外 围 设 备 ( e 他 hs ) S d.
v e之 间 的数 据 传 输 . 前 流 行 的 U BH s规 范 有 : H IU i) c 当 S ot O C 、H— c 和 E C。嵌 入式 系统 主要 是 使 用 O C 规 范 。 I HI HI U B驱 动程 序 分 为 U B主 机 端 驱 动 程序 和 U B设 备 端 驱 S S S 动 程 序 , 文 重 点 分 析 U B主 机 端 驱 动 程 序 的 开 发 过程 。U B 本 S S
U B U i r l ea B s是 用 于 将 适 用 U B的 外 围设 备 连 S ( n e aSr l u) v 线 结 构 。 目 前 U B接 口 规 范 主 要 有 : S
U B .( 速 15 b s全 速 1M / ) U B .( 速 40 b S 11低 .M / , 2 b s 和 S2 0 高 8M / s , 够 满 足 大 部 分 外 围 设 备 的 传 输 速 度 要 求 。 U B 同时 又 是 )能 S
Lnx 台下 使 用 lub 基 于 ub文件 系统 的驱 动 开 发 , i 平 u i s库 b s 并将 其 应 用 到 嵌 入 式 系统 中 , 显 著 降低 开 发 难 度 , 高 工 可 提
作效 率 。
关 键 词 : 用 串行 总 线 通
l ub库 is b
嵌 入 式 lu U B文件 系统 ix S n
A N D M A R K E T
嵌入式 lu i x下基 于 l ub的 U B驱 动开 发 n is b S
彭定军 陈 安 高 健
华 南理 工大 学 自动化 科 学与 工程 学院 广 州 504 16 0
Linux系统下USB驱动程序的设计与开发
Ln x g iu  ̄ 动程序 的架构 , 分析 了US B设备 的用途与角 色, 出 了US 给 B程序 的设计 和开发 实现 。
关键词 :Ln x i ;US u B;设备 ;驱动程序 ;程序设 计 中图分类号 : P 1 T 39 文献标识码 : A 文章编号 :0 6 8 2 (0 1 O — 7 0 1 0 — 2 8 2 1 )7 3 — 2
究了 US B驱动程序的实现技术 。
每 次只能有 一个配 置是可 用的 , 而一旦 该配置 激活 , 的接 里面
口和端 口就 都可 以同时使 用 。主机 根据 设备发过 来的描述 符
1 Ln x 动 程序 基础 iu 驱
设备驱动程序是 操作系统 内核和机器 硬件之间 的接 口, 为
中来判 断用的是哪个配置或 哪个 接 口等等 , 而这些描述字 符通
点, 已被广泛应用在 P C机及嵌入式 系统上 。
一
般称作 为缺 省管道 。对于 同样性质 的一组 端 口的组 合叫作
在已经研制的家庭网关中,P C U通过自带的U B S 接口控制 接 口, 如果—个设备包含不 止 —个接 口, 就可以称之为复合设备。 U B设备 。本 文介 绍了 Lnx S i 驱动 程序的架构 和总线 , 点研 u 重 同理 , 于同样类型 的接 口的组合可 以称之 为配置。但是 对
对设备进行初始化, 使设备投入运行和退出服务; 把数据从内核 主机用主, 副协议来 与外 部U B设备通讯 。U B上的通汛主要 S S 传送到设备和从设备接受数据; 检测和处理设备出现的错误等 。 两个方 向进行 : 一个是 主机 到设备的下行方 向 ,一个是设备到
Lnx 统的设 备一般 分为字 符设备 、 设备 和网络 设备 主机的上行方 向 , i 系 u 块 不支持设 备间的直接通 讯。依 靠不同的设备 三种 。字符 设备是 指存取 时没有缓 存的设 备 。块 设备 的读 写 类 型 , S U B主 要 有 四 种 数 据 传 输 方 式 : 制 ( n o) 中断 : 控 c t 1、 or
(简易USB驱动)开发指导
实验七(2)设备驱动开发指导块设备种类多,使用广泛,其驱动程序的开发也比字符设备复杂。
通过本实验,大家要开发一个实际块设备(U盘)的驱动程序,将能够更深入地掌握块设备驱动程序的开发方法。
Linux下已经有一个通用的U盘驱动程序usb-storage.o,其源程序放在目录drivers\usb\storage下(相对于内核源码根目录)。
但这个驱动的实现相当复杂,本实验希望开发一个相对简单些的U盘驱动程序,不求高性能,只求结构明朗、清晰易懂,主要是让大家掌握一个实际块设备的驱动方式,从而加深理解。
事实上,本实验开发的驱动程序应该能够适用于所有基于Bulkonly传输协议的USB大容量存储设备(USB Mass Storage),比如USB移动硬盘和USB外置光驱,USB闪存盘(U 盘)只是其中的一种。
由于USB大容量存储设备具有容量大、速度快、连接灵活、即插即用、总线供电等优点,它们得到了广泛使用,掌握这类设备驱动程序的开发技术无疑具有很强的实用性。
实验内容编写一个U盘驱动程序myudisk,只要求能够驱动某个型号的U盘,能够支持U盘的常规操作,如命令hexdump、mke2fs和mount等。
同时,要求在系统内核日志中显示出U盘的容量。
若有余力,可增加多分区支持功能。
实验基础和思路在教材中P130,讲解了如何编写一个Ramdisk块设备驱动程序(sbull.c),称为radimo;在文献《Linux Device Drivers》讲解了如何编写一个USB设备驱动程序,并以Linux源代码中的usb-skeleton.c为例。
虽然前者驱动的并不是一个实际的块设备,且后者又只是针对usb字符设备,但是它们提供了一个不错的基础,通过合并我们就能基本得到一个支持usb块设备的驱动程序。
之所以说基本得到,是因为合并后只是有了块设备、USB设备的驱动支持框架,但还缺一样:对U盘(USB块设备)的实际访问操作。
USB设备驱动程序开发技术的研究
X D 。 ③ 安 装 N MeaD i r ui, 安 装 N Mea PD K u g re t o v Sd u g
Dr e td i r u i 后 , Vi ac+ 编 程 工 具栏 中 自动 添 加 一 个 v S o之 在 sl u +
D i rt i 单 项 。④ 编 译 函 数 库 V w i.w, 由 于 r e u o菜 vS d d L ss bd
【 关键 词】 B 通信 协 议 US DDK Dr eS do W DM s uc s i i rt i v u o re n f
笔 者也 曾因为安装顺序的颠倒而失- 。在实践 中笔者 总结了 败
1 开发 W D 驱 动程 序 的方 案 的选 定 M
目前 开 发 W DM ( i 2Dr e d1 ̄ 动 程 序 的 工 具 W n i r 3 v Mo e) 有 很 多 ,如 Mi oot 司 的 W idws c sf 公 r n o DDK 开 发 工 具 、 XP K T c公 司 的 W i ie、 mea 司 的 Dr e tdo等 。 RF e n vrNu g 公 Dr i r ui vS 若 仅 以 W id ws n o DDK 来 开 发 驱 动 , 度 较 大 , 且 有 很 XP 难 而 多 相 当 烦琐 的基 础 性 工 作 要 做 。如 果 对 整 个 系 统 ( 括 操 作 系 包 统、 件、 件、 硬 软 DDK 库 函 数) 系 结 构 没 有 十 分 细 致 的 了 解 , 体 开 发 者 没 有 阅 读 大 量 的 DD 文 档 和 深 入 了 解 操 作 系 统 的 内 K
D ie ok\o re文 件 夹 下 的 Vd i w。② 选 择 V — r r rs uC vW s wLb d ss d
基于Windows的USB驱动程序开发
摘 要 :为 了配 合 US B驱 动 程 序 的 开发 ,首 先 详 细 阐 述 了微 软 所提 倡 的 WDM 驱 动 模 型 。 并 以 L C 3 8为例i 具 包 ,开发 US r rtdo工 v B设 备 驱 动 程 序 的 过程 和 US 驱 动 程 序 的调 用过 程 。利 用 Dr eWok 发 驱 动程 序 B i r rs开 v 快 捷 方便 ,必 将 有 着 广 阔 的应 用 前 景 。 关 键 词 :WDM 驱 动 模 型 ;D DK;Dr eSu i;US 驱 动 i rtdo v B
程 序 负责 的 工 作有 :枚举 总 线 上 的 设 备 ;向操 作 系 统 报 告 总 线上 的动 态事 件 ; 响应 即插 即用 和 电源 管理 的 I /O 请 求 ; 管理 总线上 的设备 。 总线驱动程序创建一个物理设备对象 来 代 表 它 发现 的 设备 。 发 现 总 线 上 的 所 有 设 备 和 检 测 设 备添 即 加 或 者 删 除 ,创 建 物 理 设 备 对 象 P DO; 功能驱动程序 处理 设备 的 I / O请求包 (R ) I P ,负责创 建 功 能设 备对象 F DO; 其 他 层 的 驱 动 程 序 是 一 些 过 滤 程 序 ( ie Dr e) 对 应 的 设 备 对 象 是 过 滤 器 设 备 。 安 装硬 件 Fl r i r, t v
驱 动 程 序 完 成 不 同 的操 作 ,不 同层 之 间 可 以 互 相 调 用 , 在
设备 时操作系 统的即插 即用管理器 按照设备驱 动程序 的要 求构造设备的对象 , 首先是最 底层 的总线驱动程序检测 到实
际 的物 理 设 备 ,创 建 物 理 设 备对 象 P DO,然 后 , 即插 即用 管理器查询注册表 , 按注册表信 息依次 加载过滤驱动程序和
一文入门usb设备的驱动编写方法
一文入门usb设备的驱动编写方法USB设备驱动编写入门USB(通用串行总线)是一种广泛使用的协议,用于在计算机和外围设备之间建立通信渠道。
编写USB设备驱动程序需要对USB规范以及操作系统提供的底层机制有深入的理解。
1. 理解USB规范USB规范定义了设备之间的通信协议、设备类型和描述符格式等方面。
理解规范对于编写符合标准且能够与其他USB设备交互的驱动程序至关重要。
2. 选择操作系统平台不同操作系统对USB设备驱动程序的要求有所不同。
为Windows环境编写驱动程序与为Linux或macOS编写驱动程序具有不同的方法。
了解目标操作系统的特定要求至关重要。
3. 设置开发环境设置开发环境包括安装必要的工具和库。
这可能需要安装USB 开发工具包或编译器。
阅读操作系统的文档以设置正确的环境。
4. 创建USB描述符USB描述符是描述设备功能和配置的数据结构。
驱动程序需要创建这些描述符才能注册设备并向操作系统公开其功能。
5. 实现USB端点USB端点是设备与计算机之间的数据传输通道。
驱动程序需要实现端点处理程序来处理数据传输和控制请求。
6. 处理USB事件驱动程序需要处理各种USB事件,例如设备插入、拔出和配置更改。
实现事件处理程序来响应这些事件并更新设备状态。
7. 使用USB堆栈操作系统提供USB堆栈,为驱动程序提供与底层USB硬件接口的抽象层。
了解USB堆栈的API和功能对于与硬件交互至关重要。
8. 调试驱动程序调试USB设备驱动程序需要专门的工具和技术。
使用调试器、日志记录和分析工具来识别并解决问题。
9. 测试驱动程序在不同环境和条件下全面测试驱动程序至关重要。
执行功能测试、兼容性测试和压力测试以验证驱动程序的可靠性和稳定性。
10. 提交并分发驱动程序开发完成后,需要向操作系统供应商提交驱动程序以进行认证和分发。
遵守供应商的准则并提供必要的文档。
开发usb驱动程序的方法
开发驱动程序的方法(连载一)开始驱动程序设计下面的文字是从的帮助中节选出来的,它让我们明白在开始设计驱动程序应该注意些什么问题,这些都是具有普遍意义的开发准则。
应该支持哪些请求在开始写任何代码之前,应该首先确定我们的驱动程序应该处理哪些例程。
如果你在设计一个设备驱动程序,你应该支持和其他相同类型设备的驱动程序相同的和请求代码。
如果你是在设计一个中间层驱动程序,应该首先确认你下层驱动程序所管理的设备,因为一个高层的驱动程序必须具有低层驱动程序绝大多数例程入口。
高层驱动程序在接到请求时,在确定自身当前堆栈单元参数有效的前提下,设置好中下一个低层驱动程序的堆栈单元,然后再调用将请求传递给下层驱动程序处理。
一旦决定好了你的驱动程序应该处理哪些,就可以开始确定驱动程序应该有多少个例程。
当然也可以考虑把某些处理的例程合并为同一例程处理。
例如在和里,对和处理的例程就是同一函数。
对和处理的例程也是同一个函数。
应该有多少个对象?一个驱动程序必须为它所管理的每个可能成为请求的目标的物理和逻辑设备创建一个命名对象。
一些低层的驱动程序还可能要创建一些不确定数目的对象。
例如一个硬盘驱动程序必须为每一个物理硬盘创建一个对象,同时还必须为每个物理磁盘上的每个逻辑分区创建一个对象。
一个高层驱动驱动程序必须为它所代表的虚拟设备创建一个对象,这样更高层的驱动程序才能连接它们的对象到这个驱动程序的对象。
另外,一个高层驱动程序通常为它低层驱动程序所创建的对象创建一系列的虚拟或逻辑对象。
尽管你可以分阶段来设计你的驱动程序,因此一个处在开发阶段的驱动程序不必一开始就创建出所有它将要处理的所有对象。
但从一开始就确定好你最终要创建的所有对象将有助于设计者所要解决的任何同步问题。
另外,确定所要创建的对象还有助于你定义对象的的内容和数据结构。
开始驱动程序开发驱动程序的开发是一个从粗到细逐步求精的过程。
的\ 目录下有一个庞大的样板代码,几乎覆盖了所有类型的设备驱动程序、高层驱动程序和过滤器驱动程序。
利用windriver开发了个usb的驱动,写个开发心得
利用windriver开发了个usb的驱动,写个开发心得利用windriver 开发了个usb的驱动,写个开发心得项目组需要利用2440采集数字电视的采样数据,所以让我开发一个usb的数据采集系统,就两个要求1 速度要达到500kbyte/s以上2 稳定由于之前没有做过windows驱动的经验,所以花了3,4天时间读了读ddk的文档,期间还上chinapub找个本书,读了免费的第1章,按照他配置了vc的编译环境,呵呵。
然后就吧ddk下面的bulkusb源代码进行了修改,写好usb device的驱动,有些了个应用程序,测试一下,采集数据是ok了,但是发现有时候蓝屏,特别是采集100m左右,就会出现蓝品!这下没办法了,由于我本身就对windows内核编程不熟悉,有调试了大概3,4天确认问题可能处在电源管理方面,联系到自己对这方面不是很熟悉,而且时间紧迫,没办法转向windriver开发!我安装的是9.21版本(请到迅雷下载)。
1. 驱动的开发:a 这步开发比较简单,首先确认你的device固件正确能枚举成功,然后将device连接到pc usb ho st 端。
b 按照向导指引刷出你的设备进行配置,然后点击编译按钮生成代码。
这部分内容请参考安装文档的快速开发向导!2.应用程序开发:最主要的几个函数是,opendevice 和readwrite 函数:其实大家只要摘录向导生成代码的内容即可,这里贴一个我的static WDU_DRIVER_HANDLE hDriver = 0;static DRIVER_CONTEXT DrvCtx ;static BOOL DLLCALLCONVDeviceAttach(WDU_DEVICE_HANDLE hDevice,WDU_DEVICE *pDeviceInfo, PVOID pUserData){DRIVER_CONTEXT *pDrvCtx = (DRIVER_CONTEXT *)pUserData;DEVICE_CONTEXT *pDevCtx, **ppDevCtx;DWORD dwInterfaceNum = pDeviceInfo->pActiveInterface[0]->pActiveAltSetting->Descript or.bInterf aceNumber;DWORD dwAlternateSetting = pDeviceInfo->pActiveInterface[0]->pActiveAltSetting->Descript or.bAlt ernateSetting;TRACE("\nDeviceAttach: received and accepted attach for vendor id 0x%x, ""product id 0x%x, interface %ld, device handle 0x%p\n",pDeviceInfo->Descriptor.idVendor,pDeviceInfo->Descriptor.idProduct,dwInterfaceNum, hDevice);/* Add our device to the device list */pDevCtx = (DEVICE_CONTEXT *)malloc(sizeof(DEVICE_CONTEXT));if (!pDevCtx){ERR("DeviceAttach: failed allocating memory\n");return FALSE;}BZERO(*pDevCtx);pDevCtx->hDevice = hDevice;pDevCtx->dwInterfaceNum = dwInterfaceNum;pDevCtx->dwVendorId = pDeviceInfo->Descriptor.idVendor;pDevCtx->dwProductId = pDeviceInfo->Descriptor.idProduct;pDevCtx->dwAlternateSetting = dwAlternateSetting;OsMutexLock(pDrvCtx->hMutex);for (ppDevCtx = &pDrvCtx->deviceContextList; *ppDevCtx;ppDevCtx = &((*ppDevCtx)->pNext));*ppDevCtx = pDevCtx;pDrvCtx->dwDeviceCount++;OsMutexUnlock(pDrvCtx->hMutex);OsEventSignal(pDrvCtx->hEvent);/* Accept control over this device */return TRUE;}static VOID DLLCALLCONV DeviceDetach(WDU_DEVICE_HANDLE hDevice, PVOID pUserData) {DRIVER_CONTEXT *pDrvCtx = (DRIVER_CONTEXT *)pUserData;DEVICE_CONTEXT **pCur;DEVICE_CONTEXT *pTmpDev;BOOL bDetachActiveDev = FALSE;TRACE("\nDeviceDetach: received detach for device handle 0x%p\n", hDevice);OsMutexLock(pDrvCtx->hMutex);for (pCur = &pDrvCtx->deviceContextList;*pCur && (*pCur)->hDevice != hDevice;pCur = &((*pCur)->pNext));if (*pCur == pDrvCtx->pActiveDev){pDrvCtx->pActiveDev = NULL;pTmpDev = *pCur;*pCur = pTmpDev->pNext;free(pTmpDev);pDrvCtx->dwDeviceCount--;OsMutexUnlock(pDrvCtx->hMutex);if (bDetachActiveDev){/* When hDeviceUnusedEvent is not signaled, hDevice is possibly in use,* and therefore the detach callback needs to wait on it until it is* certain that it cannot be used.* When it is signaled - hDevice is no longer used. */OsEventWait(pDrvCtx->hDeviceUnusedEvent, INFINITE);}}DWORD DriverInit(WDU_MATCH_TABLE *pMatchTables, DWORD dwNumMatchTables, const PCHAR sDriverName, const PCHAR sLicense, DRIVER_CONTEXT *pDrvCtx) {DWORD dwError;WDU_EVENT_TABLE eventTable;/* Set Driver Name */if (!WD_DriverName(sDriverName))ERR("Error: Could not set driver name to %s, exiting\n",sDriverName);return WD_SYSTEM_INTERNAL_ERROR;}dwError = OsEventCreate(&pDrvCtx->hEvent);if (dwError)ERR("DriverInit: OsEventCreate() failed on event 0x%p: error 0x%lx " "(\"%s\")\n", pDrvCtx->hEvent, dwError, Stat2Str(dwError));return dwError;}dwError = OsMutexCreate(&pDrvCtx->hMutex);if (dwError){ERR("DriverInit: OsMutexCreate() failed on mutex 0x%p: error 0x%lx " "(\"%s\")\n", pDrvCtx->hMutex, dwError, Stat2Str(dwError));return dwError;}dwError = OsEventCreate(&pDrvCtx->hDeviceUnusedEvent);if (dwError){ERR("DriverInit: OsEventCreate() failed on event 0x%p: error 0x%lx " "(\"%s\")\n", pDrvCtx->hDeviceUnusedEvent, dwError, Stat2Str(dwError));return dwError;OsEventSignal(pDrvCtx->hDeviceUnusedEvent);BZERO(eventTable);eventTable.pfDeviceAttach = DeviceAttach;eventTable.pfDeviceDetach = DeviceDetach;eventTable.pUserData = pDrvCtx;dwError = WDU_Init(&hDriver, pMatchTables, dwNumMatchTables, &eventTabl e, sLicense, WD_ACKNOWLEDGE);if (dwError)ERR("DriverInit: failed to initialize USB driver: error 0x%lx ""(\"%s\")\n", dwError, Stat2Str(dwError));return dwError;}return WD_STATUS_SUCCESS;}VOID DriverUninit(DRIVER_CONTEXT *pDrvCtx){DEVICE_CONTEXT *pCur, *pTmpDev;if (pDrvCtx->hEvent)OsEventClose(pDrvCtx->hEvent);if (pDrvCtx->hMutex)OsMutexClose(pDrvCtx->hMutex);if (pDrvCtx->hDeviceUnusedEvent)if (hDriver)WDU_Uninit(hDriver);/* Release any remaining devices */ pCur = pDrvCtx->deviceContextList; while (pCur){pTmpDev = pCur;pCur = pCur->pNext;free(pTmpDev);}}DWORD OpenUsbDevice( void){DWORD dwError;WORD wVendorId = 0;WORD wProductId = 0;WDU_MATCH_TABLE matchTable; BZERO(DrvCtx);wVendorId = USE_DEFAULT;wProductId = USE_DEFAULT;/* use defaults */if (wVendorId == USE_DEFAULT)if (wProductId == USE_DEFAULT)wProductId = DEFAULT_PRODUCT_ID;BZERO(matchTable);matchTable.wVendorId = wVendorId;matchTable.wProductId = wProductId;dwError = DriverInit(&matchTable, 1, DEFAULT_DRIVER_NAME,DEFAULT_LICENSE_STRING, &DrvCtx);if (dwError){goto Exit;}/* Wait for the device to be attached */dwError = OsEventWait(DrvCtx.hEvent, ATTACH_EVENT_TIMEOUT); if (dwError){if (dwError==WD_TIME_OUT_EXPIRED){ERR("Timeout expired for connection with the device.\n""Check that the device is connected and try again.\n");}else{ERR("main: OsEventWait() failed on event 0x%p: error 0x%lx " "(\"%s\")\n", DrvCtx.hEvent, dwError, Stat2Str(dwError));}goto Exit;OsMutexLock(DrvCtx.hMutex);if (!DrvCtx.dwDeviceCount){OsMutexUnlock(DrvCtx.hMutex);return 1;}OsMutexUnlock(DrvCtx.hMutex);if (!DrvCtx.pActiveDev)DrvCtx.pActiveDev = DrvCtx.deviceContextList; OsEventReset(DrvCtx.hDeviceUnusedEvent);return 0 ;Exit:DriverUninit(&DrvCtx);return dwError;}void CloseUsbDevice( void){DriverUninit(&DrvCtx);}DWORD UsbRead(char *pBuffer , DWORD dwBufferSize , PDWORD pdwBytesTransferred){DWORD dwError ;WDU_DEVICE_HANDLE hDevice;OsMutexLock(DrvCtx.hMutex);hDevice = DrvCtx.pActiveDev->hDevice;OsMutexUnlock(DrvCtx.hMutex);dwError = WDU_TransferBulk(hDevice, 0x81,TRUE, 0, pBuffer,dwBufferSize,pdwBytesTransferred, TRANSFER_TIMEOUT);return dwError ;}3.驱动程序的发布:这个也比较简单,请参考自带文档usb manual 的11章节,其实就是用到了他的一个wdreg工具,我写了个批处理文件,想安装的直接点批处理即可!windriver开发驱动是比较方便,至于稳定性,现在正在测试,看来比较稳定!速度方面500kB是没问题!不过速度方面pc驱动固然有影响,device的firmware影响也是很大的,特别是双缓冲的ep,处理不当速度很难上去!。
嵌入式系统Linux及USB驱动开发
Ln x 作 系统 主要 由 4大部 分组 成 : 户应 用 iu 操 用
程序 、 操作 系统服 务 、 操作 系统 内核 、 硬件 系统 。操 作 系统 内核是 Ln x操作 系统 中最核 心的部 分 , iu 也是 嵌 入式系统 开发 中修 改 、 移植 的重点 。一个 最小 型化 的 Ln x系统 , 内核 的构造见 图 1 iu 其 。
关键 词 嵌 入 式 Liu ; 备 驱 动 ; B n x设 US
中 图分 类号 : 6 2 文 献标识 码 :A 文章 编号 :6 2 6 2 2 1 )4 O 2 5 TD 7 1 7 —0 5 (0 0 0 —0 5 ~O
1 Ln x内核 iu
1 )引导模 块 ( o t。引导 加载程 序又称 为 B o bo) ot
la e, o d r 它是 C U 加 电 以后 运 行 的第 一 段 程 序 。 因 P
此 , o t a e 的设 计 是 嵌 入 式 Ln x开 发 的 基 础 , B ol d r o iu
其基本 功 能是初始 化硬 件设备 、 立 内存 空间 的映射 建 图 , 而为调 用嵌 入式 L n x内核 准备好 硬件环境 。 从 iu S RAM、 D AM 等存储 设备 属于 挥发性 的存储 SR 器 , 电以后 其 中的 内容 就会 全 部丢 失 , 以必须 ]掉 所
Байду номын сангаас第 生 . 期
21 0 0年 4月
・
山 西 焦 煤 科 技
S a x k n a ce c & Te h o o y hn i Co ig Co l in e S c n lg
NO .4 A pr 01 .2 0
专题 综述 ・
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第17章USB设备驱动USB设备驱动和PCI设备驱动是PC中最主要的两种设备驱动程序。
与PCI协议相比,USB协议更复杂,涉及面较多。
本章将介绍USB设备驱动开发。
首先介绍USB协议,使读者对USB协议有个整体认识。
然后介绍USB设备在WDM中的开发框架。
由于操作系统的USB总线驱动程序提供了丰富的功能调用,因此开发USB驱动开发变得相对简单,只需要调用USB总线驱动接口。
17.1 USB总线协议USB总线协议比PCI协议复杂的多,涉及USB物理层协议,又涉及USB传输层协议等。
对于USB驱动程序开发者来说,不需要对USB协议的每个细节都很清楚。
本节概要地介绍USB总线协议,并对驱动开发者需要了解的地方进行详细介绍。
17.1.1 USB设备简介USB即通用串行总线(Universal Serial Bus),是一种支持即插即用的新型串行接口。
也有人称之为“菊链(daisy-chaining)”,是因为在一条“线缆”上有链接127 个设备的能力。
USB要比标准串行口快得多,其数据传输率可达每秒4Mb~12Mb(而老式的串行口最多是每秒115Kb)。
除了具有较高的传输率外,它还能给外围设备提供支持。
需要注意的是,这不是一种新的总线标准,而是计算机系统连接外围设备(如键盘、鼠标、打印机等)的输入/输出接口标准。
到现在为止,计算机系统连接外围设备的接口还没有统一的标准,例如,键盘的插口是圆的、连接打印机要用9针或25针的并行接口、鼠标则要用9针或25针的串行接口。
USB能把这些不同的接口统一起来,仅用一个4针插头作为标准插头,如图17-1所示。
通过这个标准插头,采用菊花链形式可以把所有的外设连接起来,并且不会损失带宽。
USB正在取代当前PC上的串口和并口。
第17章 USB 设备驱动431图17-1 USB 的四条传输线以USB 方式连接设备时,所有的外设都在机箱外连接,连接外设不必再打开机箱;允许外设热插拔,而不必关闭主机电源。
USB 采用“级联”方式,即每个USB 设备用一个USB 插头连接到另一个外设的USB 插座上,而其本身又提供一个USB 插座供下一个USB 外设连接用。
通过这种类似菊花链式的连接,一个USB 控制器可以连接多达127个外设,而每个外设间距离(线缆长度)可达5米。
USB 能智能识别USB 链上外围设备的插入或拆卸。
它可使多个设备在一个端口上运行,速度也比现在的串行口或并行口快得多,而且其总的连线在理论上说可以无限延长。
对PC 来说,以上这些都是一些难得的优点,因为不再需要PS/2端口、MIDI 端口等各种不同的端口了,还可以随时随地在各种设备上任意插拔。
可以在一个端口上运行鼠标、控制手柄、键盘以及其他输入装置(例如数码相机),而且,也不必重新启动系统去做这些工作。
现在USB 设备正在快速增多,且由于操作系统已内置支持USB 的功能,因而用户现在就可以方便地使用。
显然,USB 为PC 的外设扩充提供了一个很好的解决方案。
目前USB 技术的发展,已经允许用户在不使用网卡、HUB 的情况下,直接通过USB 技术将几台计算机连接起来组成小型局域网,用户只需要给各台计算机起个名字就可以开始工作。
这种网络具备Ethernet 网络的各种优点,同时少了Ethernet 网络的许多限制。
假设一位用户上班时使用笔记本电脑,回家时使用PC 机,为实现数据传输,他可以通过采用USB 技术的接口将两部电脑连接起来交换资源,其数据传输速度可达12Mbps ,这是传统串行口无法比拟的。
而且用户在组网的时候根本无须考虑DIP 、IRQ 等问题。
此类技术除支持兼容Ethernet 的软硬件外,也支持标准的网络通信协议,包括IPX/SPX 、NetBEUI 和TCP/IP ,这为通过USB 技术组成的小局域网连接至大型网络或Internet 提供了条件。
17.1.2 USB 连接拓扑结构USB 设备的连接如图17-2所示,对于每个PC 来说,都有一个或者多个称为Host 控制器的设备,该Host 控制器和一个根Hub 作为一个整体。
这个根Hub 下可以接多级的Hub ,每个子Hub 又可以接子Hub 。
每个USB 作为一个节点接在不同级别的Hub 上。
(1)USB Host 控制器:每个PC 的主板上都会有多个Host 控制器,这个Host 控制器其实就是一个PCI 设备,挂载在PCI 总线上。
Host 控制器的驱动由微软公司提供,如图17-3所示,这是笔者PC 中的Host 控制器及USB Hub 的驱动。
值得注意的是,这里Host 分别有两种驱动,一种是1.0,另一种是2.0,分别对应着USB 协议1.0和USB协Windows 驱动开发技术详解432 议2.0。
第17章 USB 设备驱动433图17-2 USB 连接拓扑结构(2)USB Hub :每个USB Host 控制器都会自带一个USB Hub ,被称为根(Root)Hub 。
这个根Hub 可以接子(Sub)Hub ,每个Hub 上挂载USB 设备。
一般PC 有8个USB 口,通过外接USB Hub ,可以插更多的USB 设备。
当USB 设备插入到USB Hub 或从上面拔出时,都会发出电信号通知系统。
这样可以枚举USB 设备,例如当被插入的时候,系统就会创建一个USB 物理总线,并询问用户安装设备驱动。
如图17-4所示为一个典型的USB Hub 的示意图。
图17-3 USB Host 和USB Hub 驱动 图17-4 USB Hub 示意图 (3)USB 设备:USB 设备就是插在USB 总线上工作的设备,广义地讲USB Hub 也算是USB 设备。
每个根USB Hub 下可以直接或间接地连接127个设备,并且彼此不会干扰。
对于用户来说,可以看成是USB 设备和USB 控制器直接相连,之间通信需要满足USB 的通信协议。
有的USB 设备功能单一,直接挂载在USB Hub 上。
而有的USB 设备功能复杂,会将Windows 驱动开发技术详解434 多个USB 功能连在一起,成为一个复合设备,它甚至可以自己内部带一个Hub ,这个Hub 下接多个USB 子设备,其和多个子设备作为一个整体当做一个USB 设备,如图17-5所示。
以上是USB 的物理拓扑结构,但对于用户来说,可以略去USB Hub 的概念,或者说USB Hub 的概念对于用户可以看成是透明的。
用户只需要将USB 设备理解成一个USB Host 连接多个逻辑设备。
可能逻辑设备1和逻辑设备2是集中在第一个物理设备里,例如有的手机连接计算机后,系统会当做多个USB 设备加载。
因此,作为用户需要用如图17-6所示的逻辑拓扑结构理解USB 拓扑结构。
图17-5 符合设备 图17-6 USB 逻辑拓扑结构 但对于具体USB 设备来说,每个USB 设备的传输绝对不会影响其他USB 设备的传输。
例如,在有USB 设备传输的时候,其他USB 设备的带宽不会被占用。
对于USB 设备来说,每个USB 设备是直接连接到USB Host 控制器上的。
因此,应该用如图17-7所示的视角考虑USB 设备的通信。
图17-7 用户对USB 设备的观察17.1.3 USB 通信的流程USB 的连接模式是Host 和Devcie的连接模式,它不同于早期的串口和并口,所有的第17章 USB 设备驱动435请求必须是Host 向Device 发出,这就使Host 端设计相对复杂,而Device 端设计相对简单。
Host 端会在主板的南桥设计好,而Device 的厂商众多,厂商只需要遵循USB 协议,重点精力可以放在设备的研发上,而与PC 的通信不用过多考虑。
在USB 的通信中,可以看成是一个分层的协议。
分为三个层次,即最底层USB 总线接口层、USB 设备层、功能通信层,如图17-8所示。
图17-8 USB 协议以USB 摄像头设备为例,视频播放软件想通过USB 总线得到USB 摄像头捕捉的视频数据,这就相当于在功能层上。
Clinet SW 是视频播放软件,Function 是USB 摄像头。
而这些数据的读取需要USB 设备层提供的服务,在这一层上,主要是USB 设备的驱动调度Host 控制器向USB 摄像头发出读请求。
每个USB 设备会有多个管道,使用哪个管道,传输的大小都需要指定。
这个层次的USB System SW 就是USB 摄像头的驱动程序。
而在USB 设备一端一般会有小单片机或者处理芯片负责响应这种读请求,而这一层的传输又依赖于USB 总线接口层的服务。
在这一层,完全是USB 的物理协议,包括如何分成更小的包(packages )传输,如何保证每次包传输不丢失数据等。
对于USB 设备驱动程序员,主要是工作在USB 设备层,向“上”对应用程序提供读写等接口,向“下”将读取某个管道的请求发往USB Host 控制器驱动程序,它实现了最底层的传输请求。
对于每个USB 设备,都有一个或者多个的接口(Interface ),每个Interface 都有多个端点(Endpoints ),每个端点通过管道(Pipes )和USB Host 控制器连接。
每个USB 设备都会有一个特殊的端点,即Endpoint0,它负责传输设备的描述信息,同时也负责传输PC 与设备之间的控制信息,如图17-9所示。
Windows 驱动开发技术详解436图17-9 USB 管道与端点17.1.4 USB 四种传输模式当USB 插入USB 总线时,USB 控制器会自动为该USB 设备分配一个数字来标示这个设备。
另外,在设备的每个端点都有一个数字来表明这个端点。
USB 设备驱动向USB 控制器驱动请求的每次传输被称为一个事务(Transaction ),事务有四种类型,分别是Bulk Transaction 、Control Transaction 、Interrupt Transaction 和Isochronous Transaction 。
每次事务都会分解成若干个数据包在USB 总线上传输。
每次传输必须历经两个或三个部分,第一部分是USB 控制器向USB 设备发出命令,第二部分是USB 控制器和USB 设备之间传递读写请求,其方向主要看第一部分的命令是读还是写,第二部分有时候可以没有。
第三部分是握手信号。
以下针对这四种传输,分别进行讲解。
1.Bulk 传输事务顾名思义,改种事务传输主要是大块的数据,传送这种事务的管道叫做Bulk 管道。
这种事务传输的时候分为三部分,如图17-10所示。
第一部分是Host 端发出一个Bulk 的令牌请求,如果令牌是IN 请求则是从Device 到Host 的请求,如果是OUT 令牌,则是从Host 到Device 端的请求。