国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

Hi,歡迎來到嵌入式培訓高端品牌 - 華清遠見教育科技集團<北京總部官網(wǎng)>,專注嵌入式工程師培養(yǎng)15年!
當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > Linux USB gadget設備驅動解析(2)---驅動調試
Linux USB gadget設備驅動解析(2)---驅動調試
時間:2016-12-29作者:華清遠見

這一節(jié)主要把在實現(xiàn)“linux模擬U盤功能”過程中的一些調試過程記錄下來,并加以解析。

一、背景知識 
    1、USB Mass Storage類規(guī)范概述 
       USB 組織在universal Serial Bus Mass Storage Class Spaceification 1.1版本中定義了海量存儲設備類(Mass Storage Class)的規(guī)范,這個類規(guī)范包括四個 
        獨立的子類規(guī)范,即: 
       1. USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport
       2.USB Mass Storage Class Bulk-Only Transport
       3.USB Mass Storage Class ATA Command Block 
       4.USB Mass Storage Class UFI Command Specification 
       前兩個子規(guī)范定義了數(shù)據(jù)/命令/狀態(tài)在USB 上的傳輸方法。Bulk- Only 傳輸規(guī)范僅僅使用Bulk 端點傳送數(shù)據(jù)/命令/狀態(tài),CBI 傳輸規(guī)范則使用Control/Bulk/Interrupt 三種類型的端點進行數(shù)據(jù)/命令/狀態(tài)傳送。后兩個子規(guī)范則定義了存儲介質的操作命令。ATA 命令規(guī)范用于硬盤,UFI 命令規(guī)范是針對USB 移動存儲。 
       Microsoft Windows 中提供對Mass Storage 協(xié)議的支持,因此USB 移動設備只需要遵循 Mass Storage 協(xié)議來組織數(shù)據(jù)和處理命令,即可實現(xiàn)與PC 機交換數(shù)據(jù)。而Flash 的存儲單元組織形式采用FAT16 文件系統(tǒng),這樣,就可以直接在Windows的瀏覽器中通過可移動磁盤來交換數(shù)據(jù)了,Windows 負責對FAT16 文件系統(tǒng)的管理,USB 設備不需要干預FAT16 文件系統(tǒng)操作的具體細節(jié)。 
       USB(Host)唯一通過描述符了解設備的有關信息,根據(jù)這些信息,建立起通信,在這 些描述符中,規(guī)定了設備所使用的協(xié)議、端點情況等。因此,正確地提供描述符,是USB 設備正常工作的先決條件。 
       Linux-2.6.26內核中在利用USB gadget驅動實現(xiàn)模擬U盤時主要涉及到file_storage.c、s3c2410_udc.c等驅動文件(這些文件的具體結構,將在下一篇文章中描述)。此時我們想先從這些代碼中找到USB描述描述符,從中確定使用的存儲類規(guī)范,從而確定協(xié)議。確定通訊協(xié)議是我們調試的基礎。 
       存儲類規(guī)范是由接口描述符決定的。接口描述符各項的定義義如下:

   其中,bInterfaceClass、bInterfaceSubClass、bInterfaceProtocol可以判斷出設備是否是存儲類,以及屬于哪種存儲子類和存儲介質的操作命令。
       在file_storage.c文件中,

   /* USB protocol value = the transport method */
       #define USB_PR_CBI     0x00         // Control/Bulk/Interrupt
       #define USB_PR_CB      0x01         // Control/Bulk w/o interrupt
       #define USB_PR_BULK        0x50           // Bulk-only

   /* USB subclass value = the protocol encapsulation */
       #define USB_SC_RBC   0x01           // Reduced Block Commands (flash)
       #define USB_SC_8020  0x02           // SFF-8020i, MMC-2, ATAPI (CD-ROM)
       #define USB_SC_QIC   0x03           // QIC-157 (tape)
       #define USB_SC_UFI   0x04           // UFI (floppy)
       #define USB_SC_8070  0x05           // SFF-8070i (removable)
       #define USB_SC_SCSI  0x06           // Transparent SCSI

      默認的情況是:
               mod_data = {                                    // Default values
                         .transport_parm                      = "BBB",
                         .protocol_parm                        = "SCSI",
                         ……

    默認的賦值如下:
        bInterfaceClass=08 表示:存儲類
        bInterfaceSubClass=0x06 表示:透明的SCSI指令
        bInterfaceProtocol=0x50 表示:bulk-only 傳輸

    2、Bulk-Only 傳輸協(xié)議 
        下面看看Bulk-Only 傳輸協(xié)議:(詳細的規(guī)范請閱讀《Universal Serial BusMass Storage ClassBulk-Only Transport》) 
        設備插入到USB 后,USB 即對設備進行搜索,并要求設備提供相應的描述符。在USBHost 得到上述描述符后,即完成了設備的配置,識別出為Bulk-Only 的Mass Storage 設備, 然后即進入Bulk-Only 傳輸方式。在此方式下,USB 與設備間的所有數(shù)據(jù)均通過Bulk-In和Bulk-Out 來進行傳輸,不再通過控制端點傳輸任何數(shù)據(jù)。 
        在這種傳輸方式下,有三種類型的數(shù)據(jù)在USB 和設備之間傳送,CBW、CSW 和普通數(shù)據(jù)。CBW(Command Block Wrapper,即命令塊包)是從USB Host 發(fā)送到設備的命令, 命令格式遵從接口中的bInterfaceSubClass 所指定的命令塊,這里為SCSI 傳輸命令集。USB設備需要將SCSI 命令從CBW 中提取出來,執(zhí)行相應的命令,完成以后,向Host 發(fā)出反映 當前命令執(zhí)行狀態(tài)的CSW(Command Status Wrapper),Host 根據(jù)CSW 來決定是否繼續(xù)發(fā) 送下一個CBW 或是數(shù)據(jù)。Host 要求USB 設備執(zhí)行的命令可能為發(fā)送數(shù)據(jù),則此時需要將 特定數(shù)據(jù)傳送出去,完畢后發(fā)出CSW,以使Host 進行下一步的操作。USB 設備所執(zhí)行的操 

 作可用下圖描述: 

CBW的格式如下:

dCBWSignature: 
        CBW的標識,固定值:43425355h (little endian)。
    dCBWTag: 
        主機發(fā)送的一個命令塊標識,設備需要原樣作為dCSWTag(CSW中的一部分)再發(fā)送給Host;主要用于關聯(lián)CSW到對應的CBW。 
    dCBWDataTransferLength: 
        本次CBW命令要求在命令與回應之間傳輸?shù)淖止?jié)數(shù)。如果為0,則不傳輸數(shù)據(jù)。
    bmCBWFlags: 
        反映數(shù)據(jù)傳輸?shù)姆较颍? 表示來自Host,1 表示發(fā)至Host; 
    bCBWLUN: 
        對于有多個LUN邏輯單元的設備,用來選擇具體目標。如果沒有多個LUN,則寫0。
    bCBWCBLength: 
        命令的長度,范圍在0~16.

CBWCB: 
        傳輸?shù)木唧w命令,符合bInterfaceSubClass.中定義的命令規(guī)范,此處是SCSI
    CSW命令格式如下:


    dCSWSignature: 
        CSW的標識,固定值:53425355h (little endian)
    dCSWTag: 
        設置這個標識和CBW中的dCBWTag一致,參照上面關于dCBWTag的解釋
    dCSWDataResidue: 
        還需要傳送的數(shù)據(jù),此數(shù)據(jù)根據(jù)dCBWDataTransferLength-本次已經(jīng)傳送的數(shù)據(jù)得到 
    bCSWStatus: 
        指示命令的執(zhí)行狀態(tài)。如果命令正確執(zhí)行,bCSWStatus 返回0 即可。

3、SCSI指令集

Bulk-Only 的CBW 中的CBWCB 中的內容即為如下格式的命令塊描述符(Command Block Descriptor)。SCSI-2 有三種字長的命令,6 字節(jié)、10字節(jié)和12字節(jié),Microsoft Windows 環(huán)境下支持12 字節(jié)長的命令。 


    Operation Code: 
        操作代碼,表示特定的命令。高3 位為Group Code,共有8 種組合, 
    即8 個組,低5 五位為Command Code,可以有32 種命令。 
    Logicol unit Number: 
        為了兼容SCSI-1 而設的,此處可以不必關心。 
    Logical block address: 
        為高位在前,低位在后的邏輯塊地址,即扇區(qū)地址。第2 位為高位,第3、4、5 依次為低位。 
    Transfer length: 
        為需要從邏輯塊地址處開始傳輸?shù)纳葏^(qū)數(shù)(比如在Write 命令中)。 
    Parameter list length: 
        為需要傳輸?shù)臄?shù)據(jù)長度(比如在Mode Sense 命令中); 
    Allocation length: 
        為初始程序為返回數(shù)據(jù)所分配的大字節(jié)數(shù),此值可以為零,表示不需要傳送數(shù)據(jù)。 
        SCSI指令集的Direct Accesss 類型存儲介質的傳輸命令有許多, Mass Storage協(xié)議只用到了其中的一些。更多的SCSI指令參見://en.wikipedia.org/wiki/SCSI_command 
    指令代碼      指令名稱            說明
    04h          Format Unit      格式化存儲單元
    12h          Inquiry          索取器件信息
    1Bh          Start/Stop        load/unload
    55h          Mode select     允許Host對外部設備設置參數(shù)。 
    5Ah          Mode  Sense      向host傳輸參數(shù) 
    Eh  Prevent/Allow Medium Removal    寫保護
    >28h         Read(10)          Host讀存儲介質中的二進制數(shù)據(jù)
    A8h         Read(12)          同上,不過比較詳細一點
    25h         Read Capacity       要求設備返回當前容量
    23h         Read Format Capacity   查詢當前容量及可用空間  
    03h         Request  Sense        請求設備向主機返回執(zhí)行結果,及狀態(tài)數(shù)據(jù) 
    01h        Rexero Unit          返回零軌道
    2Bh         Seek(10)          為設備分配到特定地址
    1Dh         Send  Diagnostic      執(zhí)行固件復位并執(zhí)行診斷
    00h        Test Unit Ready       請求設備報告是否處于Ready狀態(tài) 
    2Fh         Verify               在存儲中驗證數(shù)據(jù)
    2Ah         Write(10)          從主機向介質寫二進制數(shù)據(jù)
    AAh         Write(12)          同上,不過比較詳細    
    2Eh        Write and Verify      寫二進制數(shù)據(jù)并驗證 

對于不同的命令,其命令塊描述符略有不同,其要求的返回內容也有所不同,根據(jù)相 應的文檔,可以對每種請求作出適當?shù)幕貞。比如,下面是INQUIRY 請求的命令塊描述符和其返回內容的數(shù)據(jù)格式:如:INQUIRY 
    命令描述符: 

返回數(shù)據(jù)格式 


        Host 會依次發(fā)出INQUIRY、Read Capacity、UFI Mode Sense 請求,如果上述請求的返回結果都正確,則Host 會發(fā)出READ 命令,讀取文件系統(tǒng)0 簇0 扇區(qū)的MBR 數(shù)據(jù),進入文件系統(tǒng)識別階段。 

4、利用USB View觀察結果 
       可通過USB View軟件查看到USB設置階段獲取到的信息。

 
        二、出現(xiàn)的主要問題 
            在調試過程中遇到了一個問題,F(xiàn)象是:在目標板加載完驅動后,即執(zhí)行完:
            # insmod g_file_storage.ko file=/dev/mtdblock2 stall=0 removable=1
         后,接好USB線。此時在windows端設備出有usb storage設備加入,但出現(xiàn)不了盤符。
         下面記錄下調試過程。

、調試過程 
      根據(jù)規(guī)范,當完成SCSI指令集中Inquiry 命令時,可以出現(xiàn)盤符。所以可以通過bushound軟件查看通訊過程,找出原因。
      下面是利用bushound工具在出現(xiàn)問題時采集到的數(shù)據(jù)。
      Dev     Phase    Data                                                                   Info             Time       Cmd.Phase. Ofs 

  --- ----- --------------------------------- ---------- ----- -----------
      26      CTL      80 06 00 01 - 00 00 12 00                                          GET DESCRIPTR         0us           1.1.0 
      26      DI       12 01 10 01 - 00 00 00 10 - 25 05 a5 a4 - 12 03 01 02 ........%....... 4.8ms                           1.2.0 
                       03 01 ..                                                                                               1.2.16 
      26      CTL      80 06 00 02 - 00 00 09 00                                          GET DESCRIPTR         14us          2.1.0 
      26      DI       09 02 20 00 - 01 01 04 c0 - 01                                     .. ......             3.9ms         2.2.0 
      26      CTL      80 06 00 02 - 00 00 20 00                                          GET DESCRIPTR         16us          3.1.0 
      26      DI       09 02 20 00 - 01 01 04 c0 - 01 09 04 00 - 00 02 08 06   .. ............. 4.9ms           3.2.0
                       50 05 07 05 - 81 02 40 00 - 00 07 05 02 - 02 40 00 00 P.....@......@..                  3.2.16  
      26      CTL      80 06 00 03 - 00 00 02 00                                          GET DESCRIPTR         60us          4.1.0 
      26      DI       09 02 20 00 - 01 01 04 c0 - 01                                     .. ......             3.9ms         2.2.0 
      26      DI       04 03                                                                 ..                 3.9ms         3.1.0 
      26      CTL      80 06 00 03 - 00 00 04 00                                          GET DESCRIPTR         15us          5.1.0 
      26      DI       04 03 09 04                                                             ....             3.9ms         6.1.0
      26     CTL      80 06 03 03 - 09 04 02 00                                          GET DESCRIPTR        10us            1.2.16 
      26      DI       1a 03                                                                   ....            4.0ms           6.2.0 
      26     CTL      80 06 03 03 - 09 04 1a 00                                           GET DESCRIPTR        18us            7.1.0 
      26      DI      1a 03 33 00 - 37 00 32 00 - 30 00 34 00 - 31 00 37 00 ..3.7.2.0.4.1.7. 4.9ms             7.2.0 
                      35 00 36 00 - 37 00 37 00 - 35 00                                   5.6.7.7.5. 7.2.16 
      26     CTL      00 09 01 00 - 00 00 00 00                                           SET CONFIG         16us              8.1.0 
      26     CTL      01 0b 00 00 - 00 00 00 00                                           SET INTERFACE      60ms              9.1.0 
      26     CTL      a1 fe 00 00 - 00 00 01 00                                           CLASS               62ms              10.1.0 
      26     DI             00 .                                                                              3.9ms           10.2.0 
      26     DO        55 53 42 43 - 08 60 e0 86 - 24 00 00 00 - 80 00 06 12 USBC.`..$....... 985us           11.1.0 
                      00 00 00 24 - 00 00 00 00 - 00 00 00 00 - 00 00 00       ...$...........                11.1.16 
      26      DI      00 80 02 02 - 1f 00 00 00 - 4c 69 6e 75 - 78 20 20 20      ........Linux 1.0ms             12.1.0 
                      46 69 6c 65 - 2d 53 74 6f - 72 20 47 61 - 64 67 65 74           File-Stor Gadget        12.1.16 
                      30 33 31 32                                                       0312                  12.1.32 
      26     CTL      80 06 00 02 - 00 00 20 00                                        GET DESCRIPTR           893ms           13.1.0 

      26     DI       09 02 20 00 - 01 01 04 c0 - 01 09 04 00 - 00 02 08 06 .. ............. 4.1ms           13.2.0 
                      50 05 07 05 - 81 02 40 00 - 00 07 05 02 - 02 40 00 00 P.....@......@..                13.2.16 
      26      CTL     80 06 00 02 - 00 00 20 00                                             GET DESCRIPTR         2.7sc        14.1.0 
      26      DI      09 02 20 00 - 01 01 04 c0 - 01 09 04 00 - 00 02 08 06 .. .............  4.4ms           14.2.0 
                      50 05 07 05 - 81 02 40 00 - 00 07 05 02 - 02 40 00 00 P.....@......@..                   14.2.16 
      26      USTS 05 00 00 c0                                                              no response       2.8sc             15.1.0

注意上面紅色部分的代碼,DO發(fā)出了55 53 42 43開始的CBW命令塊,命令碼是12,即Inquiry命令。要求目標返回Inquiry命令要求的數(shù)據(jù),長度是0x24。接下來設備端通過DI返回了設備信息。按照規(guī)范,在返回完了數(shù)據(jù)后,設備端還應該通過DI向系統(tǒng)返回CSW的值。但實際的捕獲內容并沒有。所以導致不能正確出現(xiàn)盤符。
    在file_storage.c,發(fā)送數(shù)據(jù)時都會調用到start_transfer()函數(shù)。在此函數(shù)中加入printk調試語句,觀察現(xiàn)象。發(fā)現(xiàn)只要加入的調試語句,windows端就能夠正常設別設備了。于是,可以猜測是因為需要在連續(xù)兩次發(fā)送之間加上一些延時。在函數(shù)中加入udelay(800)后,windows系統(tǒng)可以正常發(fā)現(xiàn)設備了。具體的代碼架構,將在下一遍文章中解析。
    下面是程序正常后,用bushound捕獲到的數(shù)據(jù)。


    紅色部分,可以看出設備正確的按照規(guī)范在發(fā)送完數(shù)據(jù)后,返回CSW信息。


      四、總結做好USB gadget驅動、或者USB host驅動調試需要:
        ·掌握一定的知識基礎
        包括:USB協(xié)議、具體的類設備規(guī)范、USB驅動程序架構、USB設備端控制器操作等。
        ·合理利用調試工具。
        包括:USB view 、bushound 、及一些硬件USB信號分析儀。

發(fā)表評論
評論列表(網(wǎng)友評論僅供網(wǎng)友表達個人看法,并不表明本站同意其觀點或證實其描述)