http://msdn.microsoft.com/en-us/library/windows/hardware/ff553412(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff553428(v=vs.85).aspx
Device Class GUID 是INF文件中Verison Section中指名的设备类GUID,他标志着此设备图标,此设备出现在哪一栏,电压电流等各种信息。

Interface GUID是指驱动程序中的GUID, 用于使用API打开此设备进行一系列读写操作,API代码如下(FINDSTR_USB_DEVICE即为我驱动程序中使用的GUID):
1 //得到设备的句柄 2 HDEVINFO info=SetupDiGetClassDevs((LPGUID)&FINDSTR_USB_DEVICE,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); 3 if(info==INVALID_HANDLE_VALUE) 4 { 5 AfxMessageBox("No HDEVINFO avaliable for this GUIDn"); 6 return ; 7 } 8 9 SP_INTERFACE_DEVICE_DATA ifdata; 10 ifdata.cbSize=sizeof(ifdata); 11 DWORD instance=0; 12 if(!SetupDiEnumDeviceInterfaces(info,NULL,(LPGUID)&FINDSTR_USB_DEVICE,instance,&ifdata)) 13 { 14 AfxMessageBox("No SP_INTERFACE_DEVICE_DATA available for this GUID instance"); 15 SetupDiDestroyDeviceInfoList(info); 16 return ; 17 } 18 19 //得到符号链接名 20 DWORD ReqLen; 21 SetupDiGetDeviceInterfaceDetail(info,&ifdata,NULL,0,&ReqLen,NULL); 22 PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail=(PSP_INTERFACE_DEVICE_DETAIL_DATA)new char[ReqLen]; 23 if(ifDetail==NULL) 24 { 25 AfxMessageBox("Error 1"); 26 SetupDiDestroyDeviceInfoList(info); 27 return ; 28 } 29 ifDetail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); 30 if(!SetupDiGetDeviceInterfaceDetail(info,&ifdata,ifDetail,ReqLen,NULL,NULL)) 31 { 32 AfxMessageBox("Error 2"); 33 SetupDiDestroyDeviceInfoList(info); 34 delete ifDetail; 35 return ; 36 } 37 char buff[256]={0}; 38 char * format="Symbolic link is %sn"; 39 sprintf(buff,format,ifDetail->DevicePath); 40 HANDLE rv=CreateFile(ifDetail->DevicePath, 41 GENERIC_READ|GENERIC_WRITE, 42 FILE_SHARE_READ|FILE_SHARE_WRITE, 43 NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL); 44 //end of 得到设备句柄 45 delete ifDetail; 46 SetupDiDestroyDeviceInfoList(info); 47 48 hDevice=rv; 49 DWORD ThreadId; 50 hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)UpDate,this,0,&ThreadId); 51 m_EchoLed1.EnableWindow(TRUE); 52 m_EchoLed2.EnableWindow(TRUE); 53 m_OpenDevice.SetWindowText("关闭设备");
Device Interface Class GUID是Microsoft定义用来调用RegisterDeviceNotification时所使用的一类GUID,关于Microsoft所定义的所有Devcie Interface Class GUID 可以参看上面给出的网址,下面给出这类GUID的使用方法(用于动态检测某类USB设备的插入与拔出):
1 //注册 某个USB设备接口类 事件 2 GUID zz = {0xA5DCBF10, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 3 0x51, 0xED}; 4 DEV_BROADCAST_DEVICEINTERFACE DevBroadcastDeviceInterface; 5 6 DevBroadcastDeviceInterface.dbcc_size = sizeof(DevBroadcastDeviceInterface); 7 DevBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 8 DevBroadcastDeviceInterface.dbcc_classguid = zz; 9 RegisterDeviceNotification(m_hWnd, &DevBroadcastDeviceInterface, 10 DEVICE_NOTIFY_WINDOW_HANDLE);
注:上述三种GUID没有任何实质上的关联,不能混为一谈。
GUID(A5DCBF10-6530-11D2-901F-00C04FB951ED)写成代码为
static const GUID x_guid = { 0xA5DCBF10, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED };
]]>如有错误还请指正!!!
]]>STM32的USB模块包缓冲区有512B,但是在STM32的参考手册中的存储器映像中却表明0x40006000-0x400063ff,整整多了512B,怎么会这样呢,同时在尝试着编程时也遇到了一个问题:
在usb_core.c文件的Setup0_Process(void)这个函数中,有这么一段:
uint16_t offset = 1;
if (pInformation->ControlState != PAUSE)
{
pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
pInformation->USBbRequest = *pBuf.b++; /* bRequest */
pBuf.w += offset; /* word not accessed because of 32 bits addressing */
pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
pBuf.w += offset; /* word not accessed because of 32 bits addressing */
pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */
pBuf.w += offset; /* word not accessed because of 32 bits addressing */
pInformation->USBwLength = *pBuf.w; /* wLength */
}
这其中又不太明白为什么需要pBuf.w += offset;而且后面的解释也不太懂 /* word not accessed because of 32 bits addressing */
,我于是在这段之前加入调试以显示收到什么数
#ifdef DEBUG
UARTSend_String("*** 端点0收到SETUP数据 ***rn");
for(offset=0;offset<16;offset++)
{
UARTSend_Hex(*pBuf.b++);
}
#endif
结果串口调试显示如下:
*** USB总线复位 ***
*** USB总线CTR置位 ***
*** 进入端点0 ***
*** 端点0收到SETUP包 ***
*** 端点0收到SETUP数据 ***
0x80 0x06 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x40 0x00 0x00 0x00
本来应该显示0x80 0x06 0x00 0x01 0x00 0x000x40 0x00才对,不太明白怎么0x80 0x06和0x00 0x01 后面多了两个 0x00 ,难道USB模块还会将收到的数据跳着放吗?
后来反复看参考手册,问了些人,才知道原来STM32的USB缓冲区是一个双端口的RAM,CPU一端需要使用32位方式访问,但USB模块一端使用16位方式访问。也就是说每个USB模块中的地址*2才能对应到控制器中的实际地址,这样每四个字节地址空间后两个字节地址空间是空的。所以上面串口调试显示的数据每正确两个字节就会多出两个字节的0x00。
这里也对STM32的USB库函数中对缓冲区的操作函数做个说明:
在usb_men.c文件有这么一个函数
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
uint32_t n = (wNBytes + 1) >> 1;/* /2*/
uint32_t i;
uint32_t *pdwVal;
pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i–)
{
*(uint16_t*)pbUsrBuf++ = *pdwVal++;
pbUsrBuf++;
}
它的作用是将缓冲区中的数据拷贝到你所定义的uint8_t Receive_Buffer[];数组中。其它地方都好理解,这里说说
pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i–)
{
*(uint16_t*)pbUsrBuf++ = *pdwVal++;
pbUsrBuf++;
}
首先是pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);这里wPMABufAddr * 2之所以要*2就是前面所述的USB模块中的地址*2才能对应到控制器中的实际地址,在取得对应端点的缓冲区首地址后,将其(uint32_t*)强制指向uint32_t型,这样每次*pdwVal++,pdwVal的地址都增加4个字节,并且每次都会有四个字节的数据读出。
在for循环中,*(uint16_t*)pbUsrBuf++ = *pdwVal++;这句重点说说,++与指针*同优先级,结合顺序为至右向左结合,因此相当于*((uint16_t*)pbUsrBuf++),先*(uint16_t*)pbUsrBuf赋值只取*pdwVal++的32位数据的前16位,然后再将pbUsrBuf加上1个字节。到这里,前面定义的uint8_tReceive_Buffer[];数组中就有两个数组变量被赋值了,但这时地址还指增加一个字节,因此还需要pbUsrBuf++;让其指向Receive_Buffer[];的下下个数组变量。一次循环,知道读出所有数据。
转自http://blog.csdn.net/ringstart/article/details/6822377
]]>]]>2.微帧是用来作为传输时间基准的。在每个微帧间可以传一到多次DATA0/DATA1,但是根据DATA0/DATA1(也就是68013一次发送的数据的长度)的大小,每个微帧之间可以传送DATA数据包的个数也不同,DATA0/DATA1越大,每个微帧之间能传输的DATA的数据包的个数越少。
3.在USB2.0之中限定了描述符中的最大包长,是因为在一个微帧内由于物理条件的限制(物理带宽、bit率的原因),只能传输那么多。
4.固件使用的USB协议其实就是用来与上位机驱动进行通信的一种语言。换句话说,里面的描述符中的内容都是给上位机驱动看的。其中端点中的最大包长也就是指的是,硬件的端点缓冲区。如果端点缓冲区比描述符中的最大包长小(在USB2.0协议最大包长范围之内),那么USB硬件接收到的数据在一定情况下将会被截断或者不被接收,如果端点缓冲区比描述符中的最大包长大(在USB2.0协议最大包长范围之内),端点缓冲将会被浪费。
VOID
UsbBuildSelectInterfaceRequest(
IN PURB Urb,
IN USHORT Length,IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
IN UCHAR InterfaceNumber,
IN UCHAR AlternateSetting
);
PUSB_INTERFACE_DESCRIPTOR
USBD_ParseConfigurationDescriptorEx(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
IN PVOID StartPosition,
IN LONG InterfaceNumber,
IN LONG AlternateSetting,
IN LONG InterfaceClass,
IN LONG InterfaceSubClass,
IN LONG InterfaceProtocol
);
这两个函数中都有一个共同的参数:AlternateSetting!
至此,基本可以说明得出的结论是正确的!
设备的挂起
我们知道,在USB系统中,正常状态下hub或root hub会一直周期性地发送SOF包(Start Of Frame,全速USB每1ms发送一个,高速USB则是125

设备的唤醒
设备处于挂起状态时,任何总线上的活动(非空闲信号)都可以把设备唤醒/恢复,从而退出低功耗模式。(同样,设备也可以换醒host,比如电脑待机时通过USB键盘来换醒主机,这种功能称之为“远程唤醒”(remote wakeup),不在本文的讨论范围内。)
因为设备挂起时处于全速信号,在当host需要把将设备退出suspend状态时,需要先发送一个持续时间超过20ms的Fulll Speed K状态。设备看到K状态结束的1.3us内醒过来,而host需要在3ms内发送uSOF信号以维持正常的高速信号模式,否则设备又将进入suspend。如下图所示:
原文转自:http://apps.hi.baidu.com/share/detail/17542952

一旦获悉有新设备连接上来,主机就会发送一系列的请求(Resqusts)给设备所挂载到的hub,再由hub建立起一条连接主机(Host)和设备(Device)之间的通信通道。然后主机以控制传输(Control
Transfer)的方式,通过端点0(Endpoint 0)对设备发送各种请求,设备收到主机发来的请求后回复相应的信息,进行枚举(Enumerate)操作。所有的USB设备必须支持标准请求(Standard
Requests),控制传输方式(Control
Transfer)和端点0(Endpoint 0)。
从用户角度来看,枚举过程是自动完成并不可见的。但很多初次使用的设备连接时,系统会弹出说新硬件检测到,设备安装成功,可以使用之类的消息提示框,而且有时还需要用户配合选择安装相关的驱动。
当枚举完成后,这个新添加的设备可在Windows的设备管理器里面看到,当用户删除这个设备/硬件时,系统把这个设备从设备管理器里删除。
对于一般的设备,固件(Firmware)内包含主机所要请求的信息,而有些设备则是完全由硬件来负责响应主机的请求。在主机方面则是由操作系统而非应用程序负责处理相关枚举操作。
枚举步骤
USB协议定义了设备的6种状态,仅在枚举过程种,设备就经历了4个状态的迁移:上电状态(Powered),默认状态(Default),地址状态(Address)和配置状态(Configured)(其他两种是连接状态和挂起状态(Suspend))。
下面步骤是Windows系统下典型的枚举过程,但是固件不能依此就认为所有的枚举操作都是按照这样一个流程行进。设备必须在任何时候都能正确处理所有的主机请求。
1.用户把USB设备插入USB端口或给系统启动时设备上电
这里指的USB端口指的是主机下的根hub或主机下行端口上的hub端口。Hub给端口供电,连接着的设备处于上电状态。
2.Hub监测它各个端口数据线上(D+/D-)的电压
在hub端,数据线D+和D-都有一个阻值在14.25k到24.8k的下拉电阻Rpd,而在设备端,D+(全速,高速)和D-(低速)上有一个1.5k的上拉电阻Rpu。当设备插入到hub端口时,有上拉电阻的一根数据线被拉高到幅值的90%的电压(大致是3V)。hub检测到它的一根数据线是高电平,就认为是有设备插入,并能根据是D+还是D-被拉高来判断到底是什么设备(全速/低速)插入端口(全速、高速设备的区分在我将来的文章中描述)。如下图。

USB全速/高速设备上电连接
(Full-speed Device Cable and Resistor Connections)
检测到设备后,hub继续给设备供电,但并不急于与设备进行USB传输。
3. Host了解连接的设备
每个hub利用它自己的中断端点向主机报告它的各个端口的状态(对于这个过程,设备是看不到的,也不必关心),报告的内容只是hub端口的设备连接/断开的事件。如果有连接/断开事件发生,那么host会发送一个
Get_Port_Status请求(request)以了解更多hub上的信息。Get_Port_Status等请求属于所有hub都要求支持的hub类标准请求(standard hub-class requests)。
4.Hub检测所插入的设备是高速还是低速设备
hub通过检测USB总线空闲(Idle)时差分线的高低电压来判断所连接设备的速度类型,当host发来Get_Port_Status请求时,hub就可以将此设备的速度类型信息回复给host。(USB
2.0规范要求速度检测要先于复位(Reset)操作)。
5.hub复位设备
当主机获悉一个新的设备后,主机控制器就向hub发出一个 Set_Port_Feature请求让hub复位其管理的端口。hub通过驱动数据线到复位状态(D+和D-全为低电平 ),并持续至少10ms。当然,hub不会把这样的复位信号发送给其他已有设备连接的端口,所以其他连在该hub上的设备自然看不到复位信号,不受影响。
6.Host检测所连接的全速设备是否是支持高速模式
因为根据USB 2.0协议,高速(High Speed)设备在初始时是默认全速(Full Speed )状态运行,所以对于一个支持USB 2.0的高速hub,当它发现它的端口连接的是一个全速设备时,会进行高速检测,看看目前这个设备是否还支持高速传输,如果是,那就切到高速信号模式,否则就一直在全速状态下工作。
同样的,从设备的角度来看,如果是一个高速设备,在刚连接bub或上电时只能用全速信号模式运行(根据USB 2.0协议,高速设备必须向下兼容USB 1.1的全速模式)。随后hub会进行高速检测,之后这个设备才会切换到告诉模式下工作。假如所连接的hub不支持USB
2.0,即不是高速hub,不能进行高速检测,设备将一直以全速工作。
高速设备检测的过程在我另外一篇文章(USB2.0速度识别)中有详细描述,这里不具体深入。
7.
Hub建立设备和主机之间的信息通道
主机不停得向hub发送 Get_Port_Status请求,以查询设备是否复位成功。Hub返回的报告信息中有专门的一位用来标志设备的复位状态。
当hub撤销了复位信号,设备就处于默认/空闲状态(Default state),准备着主机发来的请求。设备和主机之间的通信通过控制传输,默认地址0,端点号0进行。在此时,设备能从总线上得到的最大电流是100mA。
8.主机发送Get_Descriptor请求获取默认管道的最大包长度
默认管道(Default Pipe)在设备一端来看就是端点0。主机此时发送的请求是默认地址0,端点0,虽然所有位分配地址的设备都是通过地址0来获取主机发来的信息,但由于枚举过程不是多个设备并行处理,而是一次枚举一个设备的方式进行,所以不会发生多个设备同时响应主机发来的请求。
设备描述符的第8字节代表设备端点0的最大包大小。对于Windows系统来说,Get_Descriptor请求中的wLength一项都会设为64,虽然说设备所返回的设备描述符(Device Descriptor)长度只有18字节,但系统也不在乎,此时,描述符的长度信息对它来说是最重要的,其他的瞄一眼就过了。Windows系统还有个怪癖,当完成第一次的控制传输后,也就是完成控制传输的状态阶段,系统会要求hub对设备进行再一次的复位操作(USB规范里面可没这要求)。再次复位的目的是使设备进入一个确定的状态。
9.主机给设备分配一个地址
主机控制器通过Set_Address请求向设备分配一个唯一的地址。在完成这次传输之后,设备进入地址状态(Address state),之后就启用新地址继续与主机通信。这个地址对于设备来说是终生制的,设备在,地址在;设备消失(被拔出,复位,系统重启),地址被收回。同一个设备当再次被枚举后得到的地址不一定是上次那个了。
10.主机获取设备的信息
主机发送 Get_Descriptor请求到新地址读取设备描述符,这次主机发送Get_Descriptor请求可算是诚心,它会认真解析设备描述符的内容。设备描述符内信息包括端点0的最大包长度,设备所支持的配置(Configuration)个数,设备类型,VID(Vendor ID,由USB-IF分配), PID(Product ID,由厂商自己定制)等信息。Get_Descriptor请求(Device
type)和设备描述符(已抹去VID,PID等信息)见下图:

标准Get_Descriptor请求
(Get_Descriptor Request)

之后主机发送Get_Descriptor请求,读取配置描述符(Configuration Descriptor),字符串等,逐一了解设备更详细的信息。事实上,对于配置描述符的标准请求中,有时wLength一项会大于实际配置描述符的长度(9字节),比如255。这样的效果便是:主机发送了一个Get_Descriptor_Configuration
的请求,设备会把接口描述符,端点描述符等后续描述符一并回给主机,主机则根据描述符头部的标志判断送上来的具体是何种描述符。
11.主机给设备挂载驱动(复合设备除外)
主机通过解析描述符后对设备有了足够的了解,会选择一个最合适的驱动给设备。在驱动的选择过程中,Windows系统会和系统inf文件里的厂商ID,产品ID,有时甚至用到设备返回来的产品版本号进行匹配。如果没有匹配的选项,Windows会根据设备返回来的类,子类,协议值信息选择。如果该设备以前在系统上成功枚举过,操作系统会根据以前记录的登记信息而非inf文件挂载驱动。当操作系统给设备指定了驱动之后,就由驱动来负责对设备的访问。
对于复合设备,通常应该是不同的接口(Interface)配置给不同的驱动,因此,需要等到当设备被配置并把接口使能后才可以把驱动挂载上去。
设备-配置-接口-端点关系见下图:

实际情况没有上述关系复杂。一般来说,一个设备就一个配置,一个接口,如果设备是多功能符合设备,则有多个接口。端点一般都有好几个,比如Mass Storage设备一般就有两个端点(控制端点0除外)。
12. 设备驱动选择一个配置
驱动(注意,这里是驱动,之后的事情都是有驱动来接管负责与设备的通信)根据前面设备回复的信息,发送Set_Configuration请求来正式确定选择设备的哪个配置(Configuration)作为工作配置(对于大多数设备来说,一般只有一个配置被定义)。至此,设备处于配置状态,当然,设备也应该使能它的各个接口(Interface)。
对于复合设备,主机会在这个时候根据设备接口信息,给它们挂载驱动。
13. 设备可使用
********************
写在最后:
写此文是为了自己对最近一段时间学习USB有个总结,也希望能让其他USB初学者有点小小的收获。本文主要参考来源是Jan
Axelson的Enumeration: How the Host Learns about Devices(http://www.lvr.com/usbcenum.htm)和Danny Simpson的An Overview of the Universal Serial Bus (USB) (http://www.sss-mag.com/usb.html),并结合些自己的一些体会和理解,辅以图片。由于我自己也是刚接触USB不久,文中必有一些瑕疵,还请各位高手多多指教了:)
原文来自:http://apps.hi.baidu.com/share/detail/44244162
全速和低速识别

(Full-speed Device Cable and Resistor Connections)

USB低速设备上电连接
(Low-speed Device Cable and Resistor Connections)
高速识别
USB全速/低速识别相当简单,但USB2.0,USB1.x就一对数据线,不能像全速/低速那样仅依靠数据线上拉电阻位置就能识别USB第三种速度:高速。因此对于高速设备的识别就显得稍微复杂些。
高速设备初始是以一个全速设备的身份出现的,即和全速设备一样,D+线上有一个1.5k的上拉电阻。USB2.0的hub把它当作一个全速设备,之后,hub和设备通过一系列握手信号确认双方的身份。在这里对速度的检测是双向的,比如高速的hub需要检测所挂上来的设备是高速、全速还是低速,高速的设备需要检测所连上的hub是USB2.0的还是1.x的,如果是前者,就进行一系列动作切到高速模式工作,如果是后者,就以全速模式工作。
下图展示了一个高速设备连到USB2.0 hub上的情形:

hub检测到有设备插入/上电时,向主机通报,主机发送Set_Port_Feature请求让hub复位新插入的设备。设备复位操作是hub通过驱动数据线到复位状态SE0(Single-ended 0,即D+和D-全为低电平),并持续至少10ms。
高速设备看到复位信号后,通过内部的电流源向D-线持续灌大小为17.78mA电流。因为此时高速设备的1.5k上拉电阻还未撤销,在hub端,全速/低速驱动器形成一个阻抗为45欧姆(Ohm)的终端电阻,2电阻并联后仍是45欧姆左右的阻抗,所以在hub端看到一个约800mV的电压(45欧姆*17.78mA),这就是Chirp
K信号。Chirp K信号的持续时间是1ms~7ms。
在hub端,虽然下达了复位信号,并一直驱动着SE0,但USB2.0的高速接收器一直在检测Chirp K信号,如果没有Chirp
K信号看到,就继续复位操作,直到复位结束,之后就在全速模式下操作。如果只是一个全速的hub,不支持高速操作,那么该hub不理会设备发送的Chirp K信号,之后设备也不会切换到高速模式。
设备发送的Chirp K信号结束后100us内,hub必须开始回复一连串的KJKJKJ….序列,向设备表明这是一个USB2.0的hub。这里的KJ序列是连续的,中间不能间断,而且每个K或J的持续时间在40us~60us之间。KJ序列停止后的100~500us内结束复位操作。hub发送Chirp
KJ序列的方式和设备一样,通过电流源向差分数据线交替灌17.78mA的电流实现。
再回到设备端来。设备检测到6个hub发出的Chirp信号后(3对KJ序列),它必须在500us内切换到高速模式。切换动作有:
1. 断开1.5k的上拉电阻。
2. 连接D+/D-上的高速终端电阻(high-speed termination),实际上就是全速/低速差分驱动器。
3. 进入默认的高速状态。
执行1,2两步后,USB信号线上看到的现象就发生变化了:hub发送出来的Chirp KJ序列幅值降到了原先的一半,400mV。这是因为设备端挂载新的终端电阻后,配上原先hub端的终端电阻,并联后的阻抗是22.5欧姆。400mV就是由17.78mA*22.5Ohm得来。以后高速操作的信号幅值就是400mV而不像全速/低速那样的3V。
至此,高速设备与USB2.0 hub握手完毕,进行后续的480Mbps高速信号通信。
最后附上几幅实际USB高速识别的示波器抓图,图中蓝色信号是D+,黄色信号是D-。
1.数据线D+在T点之前挂上1.5K电阻,在T点被host拉成SE0状态。在近2ms后,设备发送第一个Chirp K,向host通知说:我是一个高速设备,如果可能,请用高速方式与我通信。其幅度是800mV(17.78mA * (45Ohm ||1.5kOhm)
= 800mV,见上文解释)。在这里,Chirp K的持续时间是2.13ms(a,b两点之间)。

2.这幅图显示了host发出的chirp KJ信号的幅度,头几个KJ是800mv(a,b之间),随后的是400mV。图中可以看到设备在收到第三个chirp J(蓝色短条)后马上把1.5k电阻取消,导致chirp J的幅值下降到400mV。(17.78mA * (45Ohm ||45Ohm)
= 17.78mA * 22.5Ohm = 400mV)

3.量测了一个chirp J的宽度:43.5us。

最后附上一张来自Don Anderson的USB System Architecture里的USB HS接口图:

原文来自 http://hi.baidu.com/doyanger/blog/item/af45d995dd64f419d31b704d.html
1.首先,安装windbg,并把它的快捷方式发送到桌面上并把
中的内容改为:
D:/WinDDK/7600.16385.1/Debuggers/windbg.exe -b -k com:pipe,port=//./pipe/com_1,resets=0
然后点file->symbols file path,打开如下对话框

在里面输入上“srv*c:/symbols*http://msdl.microsoft.com/download/symbols;自已的工程路径”(以分号隔开);
2.然后点file->source file path会出现如下对话框

3.在其中输入要调试的源码文件所在的路径
然后点file->image file path会出现如下对话框

4.输入驱动文件的生成路径!
最后设置windows环境变量(不设环境变量有时会出现错误,可能我的设置有些问题)

变量名如上,变量值与Windbg中的第一个值一样也是“ srv*c:/symbols*http://msdl.microsoft.com/download/symbols”
5.最后为虚拟机设置串口

虚拟串口如上。
6.进入虚拟机系统
右键我的电脑->属性

在如下位置单击设置

进入如下输入并单击编辑

会打开boot.ini文件,拷入以下代码:
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)/WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS=”Microsoft Windows XP Professional” /noexecute=optin /fastdetect /noguiboot
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS=”Microsoft Windows XP Professional” /noexecute=optin /fastdetect /debug /debugport=com1 /baudrate=115200 /noguiboot
保存重启即可!
7.重启动在虚拟机中选择调试模式引导
然后打开windbg
在出现一如下界面


依次在”kd>”中输入.!smy noisy
.sympath+ srv*c:/symbols*http://msdl.microsoft.com/download/symbols
.reload /f
来更新符号包,这时windbg会从网上下载符号包,windbg会表现出死机一样的现象,但不能关闭!可能一次会更新不完,有可能需要多次更新!
8.在最后调试时
使用“SRVINSTW_内核驱动安装.EXE”工具或“driver studio”附带的工具”driver monitor”时一定要先把生成的驱动文件拷到C:/windows/system32/drivers后再使用
“SRVINSTW_内核驱动安装.EXE”工具安装服务(目标文件要选择拷到C:/windows/system32/drivers目录下的我们自己的驱动文件),才会成功安装!要不然使用“net start 服务名”时会出现找不到路径!
]]>