新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于STM32的USB枚舉過(guò)程學(xué)習(xí)筆記(二)

基于STM32的USB枚舉過(guò)程學(xué)習(xí)筆記(二)

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
接下來(lái)介紹USB設(shè)備的枚舉,枚舉就是從設(shè)備讀取各種描述符信息,這樣主機(jī)就可以根據(jù)這些信息來(lái)加載合適的驅(qū)動(dòng),從而知道是什么樣的設(shè)備,如何進(jìn)行通信。枚舉過(guò)程使用的是控制傳輸。控制傳輸可以保證數(shù)據(jù)的正確性。控制傳輸分三個(gè)過(guò)程:建立過(guò)程,可選數(shù)據(jù)過(guò)程及狀態(tài)過(guò)程。

下面介紹枚舉的詳細(xì)過(guò)程。

本文引用地址:http://butianyuan.cn/article/201611/318464.htm

USB主機(jī)檢測(cè)到USB設(shè)備插入后,就會(huì)先對(duì)設(shè)備復(fù)位,并通過(guò)一個(gè)帶數(shù)據(jù)過(guò)程的控制傳輸完成設(shè)備描述符的獲取。

第一步,USB主機(jī)會(huì)往地址0的端點(diǎn)0發(fā)送獲取設(shè)備描述符的標(biāo)準(zhǔn)請(qǐng)求,發(fā)送請(qǐng)求屬于控制傳輸?shù)慕⑦^(guò)程。建立過(guò)程是一個(gè)事務(wù)。首先是令牌包,即主機(jī)發(fā)送一個(gè)SETUP令牌,令牌的格式如上一篇描述的那樣,有令牌的PID,地址和端點(diǎn)號(hào)等;其次是數(shù)據(jù)包,SETUP使用DATA0數(shù)據(jù)包,數(shù)據(jù)包中包括標(biāo)準(zhǔn)請(qǐng)求的ID;最后是握手包,設(shè)備只能使用ACK來(lái)應(yīng)答,除非出錯(cuò)不應(yīng)答。下面根據(jù)網(wǎng)上找的USB協(xié)議分析捕捉的圖分析該建立過(guò)程。

下面通過(guò)STM32官方的USB的例子,自己添加打印信息,查看該控制傳輸?shù)慕⒐こ讨蠻SB主機(jī)發(fā)送的請(qǐng)求。如上一篇介紹,我們只需根據(jù)硬件置的標(biāo)志位來(lái)判斷USB傳輸?shù)臓顟B(tài)即可。在usb_istr.c的USB_Istr()函數(shù)中,根據(jù)中斷標(biāo)志,添加打印信息。在正確傳輸中斷的處理函數(shù)CTR_LP()中Setup0_Process()函數(shù)表示端點(diǎn)0的建立過(guò)程,即上面USB主機(jī)復(fù)位獲取設(shè)備描述符將執(zhí)行的函數(shù)。增加打印信息的函數(shù)如下:

[cpp]view plaincopy
  1. /*******************************************************************************
  2. *FunctionName:Setup0_Process
  3. *Description:Getthedevicerequestdataanddispatchtoindividualprocess.
  4. *Input:None.
  5. *Output:None.
  6. *Return:Post0_Process.
  7. *******************************************************************************/
  8. uint8_tSetup0_Process(void)
  9. {
  10. union
  11. {
  12. uint8_t*b;
  13. uint16_t*w;
  14. }pBuf;
  15. #ifdefSTM32F10X_CL
  16. USB_OTG_EP*ep;
  17. uint16_toffset=0;
  18. ep=PCD_GetOutEP(ENDP0);
  19. pBuf.b=ep->xfer_buff;
  20. #else
  21. uint16_toffset=1;
  22. pBuf.b=PMAAddr+(uint8_t*)(_GetEPRxAddr(ENDP0)*2);/**2for32bitsaddr*/
  23. #endif/*STM32F10X_CL*/
  24. #ifdefUSB_DEBUG0
  25. printf("rnSETUP0中斷-->控制傳輸.建立過(guò)程rn");
  26. #endif/*#ifUSB_DEBUG0*/
  27. if(pInformation->ControlState!=PAUSE)
  28. {
  29. #ifdefUSB_DEBUG0
  30. printf("設(shè)備可以接收新的數(shù)據(jù)rn");
  31. #endif/*USB_DEBUG0*/
  32. pInformation->USBbmRequestType=*pBuf.b++;/*bmRequestType*/
  33. pInformation->USBbRequest=*pBuf.b++;/*bRequest*/
  34. pBuf.w+=offset;/*wordnotaccessedbecauseof32bitsaddressing*/
  35. pInformation->USBwValue=ByteSwap(*pBuf.w++);/*wValue*/
  36. pBuf.w+=offset;/*wordnotaccessedbecauseof32bitsaddressing*/
  37. pInformation->USBwIndex=ByteSwap(*pBuf.w++);/*wIndex*/
  38. pBuf.w+=offset;/*wordnotaccessedbecauseof32bitsaddressing*/
  39. pInformation->USBwLength=*pBuf.w;/*wLength*/
  40. #ifdefUSB_DEBUG0
  41. printf("設(shè)備接收數(shù)據(jù)如下:rn");
  42. printf("0x%x",pInformation->USBbmRequestType);//用于指定請(qǐng)求的數(shù)據(jù)傳輸反向請(qǐng)求類(lèi)型請(qǐng)求的接收者
  43. printf("0x%x",pInformation->USBbRequest);//標(biāo)準(zhǔn)請(qǐng)求及代碼
  44. printf("0x%x",pInformation->USBwValue0);
  45. printf("0x%x",pInformation->USBwValue1);//具體見(jiàn)圈圈書(shū)P77頁(yè)
  46. printf("0x%x",pInformation->USBwIndex0);
  47. printf("0x%x",pInformation->USBwIndex1);
  48. printf("0x%x",pInformation->USBwLength1);
  49. printf("0x%x",pInformation->USBwLength0);
  50. printf("rn");
  51. #endif/*USB_DEBUG0*/
  52. }
  53. returnPost0_Process();
  54. pInformation->ControlState=SETTING_UP;
  55. if(pInformation->USBwLength==0)
  56. {
  57. /*Setupwithnodatastage*/
  58. NoData_Setup0();
  59. }
  60. else
  61. {
  62. /*Setupwithdatastage*/
  63. Data_Setup0();
  64. }
  65. returnPost0_Process();
  66. }

在打印信息之后直接就讓函數(shù)返回,使主機(jī)得不到ACK應(yīng)答,下面根據(jù)打印信息看下測(cè)試情況。

根據(jù)打印信息,由于從機(jī)沒(méi)有ACK應(yīng)答給PC機(jī)的請(qǐng)求,在PC機(jī)嘗試發(fā)了3次請(qǐng)求后,就放棄了。可以在PC機(jī)的設(shè)備管理器看到,在請(qǐng)求打印3次以后出現(xiàn)了unknown device。

關(guān)于8個(gè)字節(jié)的請(qǐng)求代碼的具體含義請(qǐng)參照USB協(xié)議,或者在《圈圈教你玩USB》里面對(duì)照。

以上就是枚舉過(guò)程獲取設(shè)備描述符的第一步控制傳輸?shù)慕⑦^(guò)程,主機(jī)發(fā)送獲取描述符的請(qǐng)求,下一篇我們將代碼中ACK返回,使主機(jī)接收到建立過(guò)程的應(yīng)答,從而進(jìn)入到數(shù)據(jù)過(guò)程,即設(shè)備響應(yīng)主機(jī)的請(qǐng)求,將設(shè)備描述符發(fā)送給主機(jī)。



關(guān)鍵詞: STM32USB枚舉過(guò)

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉