接下来介绍USB设备的枚举,枚举便是从设备读取各种描绘符信息,这样主机就能够依据这些信息来加载适宜的驱动,然后知道是什么样的设备,怎么进行通讯。枚举进程运用的是操控传输。操控传输能够确保数据的正确性。操控传输分三个进程:树立进程,可选数据进程及状况进程。
下面介绍枚举的详细进程。
USB主机检测到USB设备刺进后,就会先对设备复位,并经过一个带数据进程的操控传输完结设备描绘符的获取。
第一步,USB主时机往地址0的端点0发送获取设备描绘符的规范恳求,发送恳求归于操控传输的树立进程。树立进程是一个业务。首先是令牌包,即主机发送一个SETUP令牌,令牌的格局如上一篇描绘的那样,有令牌的PID,地址和端点号等;其次是数据包,SETUP运用DATA0数据包,数据包中包含规范恳求的ID;最终是握手包,设备只能运用ACK来应对,除非犯错不应对。下面依据网上找的USB协议剖析捕捉的图剖析该树立进程。
下面经过STM32官方的USB的比如,自己添加打印信息,检查该操控传输的树立工程中USB主机发送的恳求。如上一篇介绍,咱们只需依据硬件置的标志位来判别USB传输的状况即可。在usb_istr.c的USB_Istr()函数中,依据中止标志,添加打印信息。在正确传输中止的处理函数CTR_LP()中Setup0_Process()函数一共端点0的树立进程,即上面USB主机复位获取设备描绘符将碑文的函数。添加打印信息的函数如下:
- /*******************************************************************************
- *FunctionName:Setup0_Process
- *Description:Getthedevicerequestdataanddispatchtoindividualprocess.
- *Input:None.
- *Output:None.
- *Return:Post0_Process.
- *******************************************************************************/
- uint8_tSetup0_Process(void)
- {
- union
- {
- uint8_t*b;
- uint16_t*w;
- }pBuf;
- #ifdefSTM32F10X_CL
- USB_OTG_EP*ep;
- uint16_toffset=0;
- ep=PCD_GetOutEP(ENDP0);
- pBuf.b=ep->xfer_buff;
- #else
- uint16_toffset=1;
- pBuf.b=PMAAddr+(uint8_t*)(_GetEPRxAddr(ENDP0)*2);/**2for32bitsaddr*/
- #endif/*STM32F10X_CL*/
- #ifdefUSB_DEBUG0
- printf(“\r\nSETUP0中止–>操控传输.树立进程\r\n”);
- #endif/*#ifUSB_DEBUG0*/
- if(pInformation->ControlState!=PAUSE)
- {
- #ifdefUSB_DEBUG0
- printf(“设备能够接纳新的数据\r\n”);
- #endif/*USB_DEBUG0*/
- pInformation->USBbmRequestType=*pBuf.b++;/*bmRequestType*/
- pInformation->USBbRequest=*pBuf.b++;/*bRequest*/
- pBuf.w+=offset;/*wordnotaccessedbecauseof32bitsaddressing*/
- pInformation->USBwValue=ByteSwap(*pBuf.w++);/*wValue*/
- pBuf.w+=offset;/*wordnotaccessedbecauseof32bitsaddressing*/
- pInformation->USBwIndex=ByteSwap(*pBuf.w++);/*wIndex*/
- pBuf.w+=offset;/*wordnotaccessedbecauseof32bitsaddressing*/
- pInformation->USBwLength=*pBuf.w;/*wLength*/
- #ifdefUSB_DEBUG0
- printf(“设备接纳数据如下:\r\n”);
- printf(“0x%x”,pInformation->USBbmRequestType);//用于指定恳求的数据传输反向恳求类型恳求的接纳者
- printf(“0x%x”,pInformation->USBbRequest);//规范恳求及代码
- printf(“0x%x”,pInformation->USBwValue0);
- printf(“0x%x”,pInformation->USBwValue1);//详细见圈圈书P77页
- printf(“0x%x”,pInformation->USBwIndex0);
- printf(“0x%x”,pInformation->USBwIndex1);
- printf(“0x%x”,pInformation->USBwLength1);
- printf(“0x%x”,pInformation->USBwLength0);
- printf(“\r\n”);
- #endif/*USB_DEBUG0*/
- }
- returnPost0_Process();
- pInformation->ControlState=SETTING_UP;
- if(pInformation->USBwLength==0)
- {
- /*Setupwithnodatastage*/
- NoData_Setup0();
- }
- else
- {
- /*Setupwithdatastage*/
- Data_Setup0();
- }
- returnPost0_Process();
- }
在打印信息之后直接就让函数回来,使主机得不到ACK应对,下面依据打印信息看下测验状况。
依据打印信息,咱们从机没有ACK应对给PC机的恳求,在PC机测验发了3次恳求后,就抛弃了。能够在PC机的设备管理器看到,在恳求打印3次今后呈现了unknown device。
关于8个字节的恳求代码的详细意义请参照USB协议,或许在《圈圈教你玩USB》晒干对照。
以上便是枚举进程获取设备描绘符的第一步操控传输的树立进程,主机发送获取描绘符的恳求,下一篇咱们将代码中ACK回来,使主机接纳到树立进程的应对,然后进入到数据进程,即设备呼应主机的恳求,将设备描绘符发送给主机。