>也寫的很好很詳細(點擊閱讀原文,21ic嵌入式論壇有下載),唯一美中不足的就是寫得太詳細了反而感覺思路架構不是很清晰了。今天我們來簡單地把USB在Linux里的結構框架大致整理下,其中重點解析下USB Core和Hub。" />

在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

USB在Linux里的結構框架是什么樣的?USB Core和Hub是什么?

Q4MP_gh_c472c21 ? 來源:未知 ? 作者:易水寒 ? 2018-07-27 16:08 ? 次閱讀

USB博大精深不是一篇文章就能夠解釋清楚的。想要深入研究USB的話,USB協議(外加Host和OTG協議)是必要的知識,另外,國內有本<>也寫的很好很詳細(點擊閱讀原文,21ic嵌入式論壇下載),唯一美中不足的就是寫得太詳細了反而感覺思路架構不是很清晰了。今天我們來簡單地把USB在Linux里的結構框架大致整理下,其中重點解析下USB Core和Hub。

0. 預備理論

說實話,讀USB協議還是蠻痛苦的,它僅僅是一個協議,一個在USB世界里制定的游戲規則,就像法律條文一樣,它并不是為了學習者而寫的,可讀性很差。這里總結以下幾個重點基本點。

0.1 拓撲結構 (ch4.1.1)

·之所以要規定這個樹形拓撲結構是為了避免環形連接。

·一條USB總線有且只有一個USB Host,對應一個RootHub

·USB設備分為兩類,Hub和Functions,Hub通過端口Port連接更多USB設備,Functions即USB外接從設備。

·層次最多7層,且第7層不能有Hub,只能有functions。

·Compound Device - 一個Hub上接多個設備組成一個小設備。

·Composite Device - 一個USB外接設備具有多個復用功能。

0.2 機械性能 (ch5)

·連接件connector,就是設備上的那個連接口。

·插頭plug,就是USB電纜線兩頭的插口。

·Mini-AB, Micro-AB指的是支持A和B兩類插頭的連接件。

0.3 電氣性能 (ch6)

·VBUS - +5V電源供電

·D+ D- - 用于數據傳輸的電纜線。

·低速 low-speed 10-100Kb/s 應用于鼠標和鍵盤等

·全速 full-speed 500Kb-10Mb/s應用于音頻和麥克等

·高速high-speed 25-400Mb/s 應用于存儲和視頻等 (USB3.0比之塊10倍)

0.4 四大描述符 (ch9.5)

協議規定了USB的四個描述符descriptor - 設備device,配置configure,接口interface,端點endpoint。

終端下輸入命令 # ls /sys/bus/usb/devices

usb1 1-0:1.0 usb2 2-0:1.0 // USB總線(RootHub) No.2,USB port端口號No.0,配置號No.1,接口號No.0。

·區別port和endpoint,port之于hub,endpoint是每個USB設備用于數據傳輸所必需的端點。

·設備device>配置configure>接口interface>設置setting>端點endpoint。

·設備可以有多個配置,配置可以有一個或多個接口,接口可以有一個或多個設置。

·一個接口對應一個驅動,接口是端點的集合。

0.5 啟動流程 (ch9.1,9.2)

·attached->powered->default->address->configured

·啟動流程與其他設備比如SD卡相比,最大的不同在于Hub,主機Host通過Hub狀態的變化判斷USB外接設備的有無。

·USB外接設備插入和拔出整個實現過程稱為總線枚舉Bus Enumeration。

0.6 數據流傳輸 (ch5)

·endpoint分零端點和非零端點,零端點作為默認的控制方法用于初始化和操控USB邏輯設備。

·數據流傳輸分 control/bulk/interrupt/isochronous data transfer。

0.7 數據包 (ch8)

·數據包分Token, Data, Handshake, Special,四種包有自己的數據組織方式。

·Token令牌包只能由主機傳送給設備,分IN, OUT, SOF和SETUP。

·SETUP包實現主機向設備發出的請求request,也要滿足特定的格式。(ch9.3,9.4)

1. USB Core

先啰嗦幾句,回答一個困擾我很久的問題,讀Linux源碼究竟要讀到什么程度?這是個永恒的話題,每個同道中人都有自己的看法。以吾輩之見,如何閱讀源碼主要取決于自己的職業定位,是研發還是開發,是為Linux社區作貢獻還是用已有的方案開發?我想大多數驅動工程師屬于后者,那么,面對已經很完善的核心層源碼,還有必要看嗎,或者有必要去深入研究嗎?我認為既然我們已經站在了巨人的肩膀上,至少要知道這寬闊的肩膀是如何煉成的,它所存在的價值以及如何去使用它。

既然如此,那USB核心層到底是什么,它都默默地做了些什么,我們要如何使用它?這里主要有兩個重點,USB總線和urb。

1.1 USB子系統結構

協議里說,HCD提供主控制器驅動的硬件抽象,它只對USB Core一個負責,USB Core將用戶的請求映射到相關的HCD,用戶不能直接訪問HCD。換句話說,USB Core就是HCD與USB設備唯一的橋梁。

1.2 USB子系統的初始化

USB core源碼位于./drivers/usb/core,其中的Makefile摘要如下,

usbcore這個模塊代表的不是某一個設備,而是所有USB設備賴以生存的模塊,它就是USB子系統。

./drivers/usb/core/usb.c里實現了初始化,偽代碼如下,

usbcore注冊了USB總線,USB文件系統,USB Hub以及USB的設備驅動usb generic driver等。

1.3 USB總線

注冊USB總線通過bus_register(&usb_bus_type);

struct bus_type usb_bus_type = {.name ="usb",.match =usb_device_match, // 這是個很重要的函數,用來匹配USB設備和驅動。.uevent =usb_uevent,.pm =&usb_bus_pm_ops,};下面總結下USB設備和驅動匹配的全過程,

-> step 1 - usb device driver

USB子系統初始化的時候就會注冊usb_generic_driver, 它的結構體類型是usb_device_driver,它是USB世界里唯一的一個USB設備驅動,區別于struct usb_driver USB驅動。

·USB設備驅動(usb device driver)就只有一個,即usb_generice_driver這個對象,所有USB設備都要綁定到usb_generic_driver上,它的使命可以概括為:為USB設備選擇一個合適的配置,讓設備進入configured狀態。

·USB驅動(usb driver)就是USB設備的接口驅動程序,比如adb驅動程序,u盤驅動程序,鼠標驅動程序等等。

-> step 2 - usb driver

Linux啟動時注冊USB驅動,在xxx_init()里通過usb_register()將USB驅動提交個設備模型,添加到USB總線的驅動鏈表里。

-> step3 - usb device

USB設備連接在Hub上,Hub檢測到有設備連接進來,為設備分配一個struct usb_device結構體對象,并將設備添加到USB總線的設備列表里。

-> step4 - usb interface

USB設備各個配置的詳細信息在USB core里的漫漫旅途中已經被獲取并存放在相關的幾個成員里。

usb_generic_driver得到了USB設備的詳細信息,然后把準備好的接口送給設備模型,Linux設備模型將接口添加到設備鏈表里,然后去輪詢USB總線另外一條驅動鏈表,針對每個找到的驅動去調用USB總線的match函數,完成匹配。

1.4 USB Request Block (urb)

USB主機與設備間的通信以數據包(packet)的形式傳遞,Linux的思想就是把這些遵循協議的數據都封裝成數據塊(block)作統一調度,USB的數據塊就是urb,結構體struct urb,定義在,其中的成員unsigned char *setup_packet指針指向SETUP數據包。下面總結下使用urb完成一次完整的USB通信需要經歷的過程,

-> step 1 - usb_alloc_urb()

創建urb,并指定USB設備的目的端點。

-> step 2 - usb_control_msg()

將urb提交給USB core, USB core將它交給HCD主機控制器驅動。

-> step3 - usb_parse_configuration()

HCD解析urb,拿到數據與USB設備通信。

-> step 4

HCD把urb的所有權交還給驅動程序。

協議層里最重要的函數就是usb_control/bulk/interrupt_msg(),這里就簡單地理一條線索,

usb_control_msg() => usb_internal_control_msg() => usb_start_wait_urb() => usb_submit_urb() => usb_hcd_submit_urb => hcd->driver->urb_enqueue() HCD主控制器驅動根據具體平臺實現USB數據通信。

2. USB Hub

Hub集線器用來連接更多USB設備,硬件上實現了USB設備的總線枚舉過程,軟件上實現了USB設備與接口在USB總線上的匹配。

下面總結下USB Hub在Linux USB核心層里的實現機制,

USB子系統初始化時,usb_hub_init()開啟一個名為"khubd"的內核線程,

內核線程khubd從Linux啟動后就自始至終為USB Hub服務,沒有Hub事件時khubd進入睡眠,有USB Hub事件觸發時將會經由hud_irq() => hub_activate() => kick_khubd() 最終喚醒khubd,將事件加入hub_event_list列表,并執行hub_events()。hub_events()會不停地輪詢hub_events_list列表去完成hub觸發的事件,直到這個列表為空時退出結束,回到wait_event_xxx繼續等待。

處理hub事件的全過程大致可分為兩步,

·第一步 判斷端口狀態的變化

通過hub_port_status()得到hub端口的狀態。

源碼里類似像hub_port_status(), hub_hub_status()等功能函數,都調用了核心層的usb_control_msg()去實現主控制器與USB設備間的通信。

·第二步處理端口的變化

hub_port_connect_change()是核心函數,以端口發現有新的USB設備插入為例,USB Hub為USB設備做了以下幾步重要的工作,注意這里所謂的USB設備是指插入USB Hub的外接USB設備(包括Hub和Functions),接下來Hub都在為USB設備服務。

1) usb_alloc_dev() 為USB設備申請一個sturct usb_device結構。

2) usb_set_device_state() 設置USB設備狀態為上電狀態。(硬件上設備已進入powered狀態)。

3) choose_address() 為USB設備選擇一個地址,利用一個輪詢算法為設備從0-127里選擇一個地址號。

4)hub_port_init() 端口初始化,實質就是獲取設備描述符device descriptor。

5) usb_get_status() 這個有點特殊,它是專門給Hub又外接Hub而準備的。

6)usb_new_device() 這時USB設備已經進入了Configured狀態,調用device_add()在USB總線上尋找驅動,若匹配成功,則加載對應的驅動程序。

3. USB OTG

引入OTG的概念是為了讓設備可以充當主從兩個角色,主設備即HCD,從設備即UDC,也就是Gadget。這里就簡單梳理下協議和源碼。

3.1 協議

1) Protocol

OTG的傳輸協議有三類 - ADP,SRP,HNP。

·ADP(Attach Detection Protocol)當USB總線上沒有供電時,ADP允許OTG設備或USB設備決定連接狀態。

·SRP(Session Request Protocol) 允許從設備也可以控制主設備。

·HNP(Host Negotiation Protocol)允許兩個設備互換主從角色。

2) Device role

協議定義兩種角色,OTG A-device和OTG B-device,A-device為電源提供者,B-device為電源消費者,默認配置下,A-device作為主設備,B-device作為從設備,之后可以通過HNP互換。

3) OTG micro plug

協議上說"An OTG product must have a single Micro-AB receptacle and no other USB receptacles."這句話有點問題。。。應該還包括mini-AB receptacle,以下所有micro都可以是mini。

OTG電纜一端為micro-A plug,另一端為micro-B plug。

OTG加了第5個pin腳,名為ID-pin,micro-A plug的ID-pin接地,micro-B plug的ID-pin懸空。

OTG設備被接上micro-A plug后被稱為micro-A device,被接上micro-B plug后被稱為micro-B device。

3.2 源碼淺析

OTG控制器集成在CPU內,Linux下的源碼驅動由各家開發平臺提供,位于./drivers/usb/otg/下。

以Freescale平臺為例,主要的思路就是,當有OTG線插入OTG設備時產生中斷,中斷處理函數上半部通過讀取OTG控制器寄存器相應值判斷OTG設備屬于Host(HCD)還是Gadget(UDC),下半部通過工作隊列由回調函數類似host->resume()或gadget->resume()重啟Host或Gadget控制器,resume()具體的實現過程在HCD或UDC相關驅動里實現。

4. USB Host

USB主控制器(HCD)同樣集成在CPU內,由開發平臺廠商提供驅動,源碼位于./drivers/usb/host/下。

主控制器主要有四類:EHCI, FHCI, OHCI, UHCI, 它們各自的寄存器接口協議不同,嵌入式設備多為EHCI。

該驅動的結構體類型為struct hc_driver,其中的成員(*urb_enqueue)最為重要,它是主控制器HCD將數據包urb傳向USB設備的核心實現函數,之前已經提到,協議層里最主要的函數usb_control_msg()最終就會回調主控制器的(*urb_enqueue)。

usb_control_msg() => usb_internal_control_msg() => usb_start_wait_urb() => usb_submit_urb() => usb_hcd_submit_urb => hcd->driver->urb_enqueue()

5. USB Gadget

Gadget源碼位于./drivers/usb/gadget/下,涉及的驅動程序和數據結構相對較多。

驅動主要有,

·平臺相關的Gadget控制器驅動

·平臺無關的復用設備驅動composite.c

·android平臺的復用設備驅動android.c

·adb驅動f_adb.c,U盤驅動f_mass_storage.c等一些復用的USB驅動

數據結構主要有,

·struct usb_gadget 里面主要有(*ops)和struct usb_ep *ep0。

·struct usb_gadget_driver 其中的(*bind)綁定復用設備驅動,(*setup)完成USB枚舉操作。

·struct usb_compostie_driver 其中的(*bind)綁定比如android復用設備驅動。

·struct usb_request USB數據請求包,類似urb。

·struct usb_configuration 就是這個gadget設備具有的配置,其中的struct usb_function *interface[]數組記錄著它所擁有的USB接口/功能/驅動。

·struct usb_function 其中的(*bind)綁定相關的USB接口,(*setup)完成USB枚舉操作。

整體框架可概括為,(mv_gadget為gadget控制器的數據)

6. USB Mass Storage

全世界只有一個Linux U盤驅動,位于./drivers/usb/storage/usb.c,偽代碼如下,這里需要注意的是,在進行U盤驅動的初始化probe之前,USB core和hub已經對這個U盤做了兩大工作,即

1) 完成了USB設備的枚舉,此時U盤已經進入configured狀態,U盤數據存放在struct usb_interface。

2) 完成了USB總線上設備和驅動的匹配,這時總線上已經找到了接口對應的驅動即U盤驅動。

·土黃色部分由SCSI子系統封裝實現最終的U盤驅動注冊。

·usb_stor_scan_thread 掃描U盤的線程,等待5秒,如果5秒內不拔出就由SCSI進行全盤掃描,

·usb_stor_contro_thread 一個核心的線程,具體參看《USB那些事》...

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • usb
    usb
    +關注

    關注

    60

    文章

    7989

    瀏覽量

    266275
  • Linux
    +關注

    關注

    87

    文章

    11351

    瀏覽量

    210505
  • Core
    +關注

    關注

    0

    文章

    175

    瀏覽量

    43032
  • hub
    hub
    +關注

    關注

    1

    文章

    117

    瀏覽量

    41915

原文標題:Linux USB的那些事之設備驅動子系統終極篇

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    實現了多媒體數據的同步傳輸的USB3.0 HUB設計方案

    的,所以它有完整的USB2.0 HUB設計,而Super Speed HUB部分就是USB3.0 HUB區別于
    的頭像 發表于 11-01 08:10 ?1.2w次閱讀
    實現了多媒體數據的同步傳輸的<b class='flag-5'>USB</b>3.0 <b class='flag-5'>HUB</b>設計方案

    USB2514i USB HUB及其應用

    USB2514i USB HUB及其應用 通用串行總線(Universal Serial Bus,USB)是一種快速、雙向、同步、可動態監測的串行接口,廣泛應用于個人電腦的
    發表于 04-22 18:28 ?1.3w次閱讀
    <b class='flag-5'>USB</b>2514i <b class='flag-5'>USB</b> <b class='flag-5'>HUB</b>及其應用

    USB的低層結構

    USB的低層結構 USB設備USB的設備可以接在PC上的任意的USB接口上。而使用HUB還可以
    發表于 05-06 16:06 ?673次閱讀

    USB結構框架

    USB結構框架               
    發表于 05-06 17:05 ?978次閱讀

    usb hub是什么意思

    usb hub是什么意思 USB HUB就是USB接口擴展器。 這個參數是指鍵盤上是否帶有USB
    發表于 05-29 01:18 ?2.2w次閱讀

    什么是鍵盤USB HUB

    什么是鍵盤USB HUB 這個參數是指鍵盤上是否帶有USB HUB。計算機上的USB接口通常是
    發表于 12-28 11:14 ?4690次閱讀

    嵌入式LinuxUSB驅動設計

    本文主要介紹了 Linux 平臺的USB設備驅動開發的一般步驟方法和技巧,通過詳細介紹USB的相關概念和LinuxUSB設備驅動程序的數據
    發表于 06-08 17:15 ?49次下載
    嵌入式<b class='flag-5'>Linux</b>的<b class='flag-5'>USB</b>驅動設計

    嵌入式linuxUSB開發

    內容包括: 1.linux內核對USB規范的支持 2.USB主機驅動程序 3.USB設備驅動程序 4.USB
    發表于 01-04 18:30 ?35次下載

    八合一USB HUB擴展塢解決了USB HUB的接口不足問題

    福音Gospelwin USB HUB ODM廠商此前推出有多款USB HUB產品,今天要為大家介紹的是其近期推出的八合一USB
    發表于 05-21 10:24 ?1721次閱讀

    微雪電子USB集線器|USB HUB HAT簡介

    樹莓派USB擴展板 HUB 集線器 帶USB轉串口 外擴4個USB口;5V供電 型號 USB
    的頭像 發表于 12-30 14:17 ?3058次閱讀
    微雪電子<b class='flag-5'>USB</b>集線器|<b class='flag-5'>USB</b> <b class='flag-5'>HUB</b> HAT簡介

    如何使用Linux內核實現USB驅動程序框架

    Linux內核提供了完整的USB驅動程序框架USB總線采用樹形結構一條總線上只能有唯一的主
    發表于 11-06 17:59 ?20次下載
    如何使用<b class='flag-5'>Linux</b>內核實現<b class='flag-5'>USB</b>驅動程序<b class='flag-5'>框架</b>

    USB3.0 HUB的資料

    USB3.0 HUB的資料
    發表于 11-16 17:31 ?139次下載

    USB Hub

    USB Hub
    發表于 12-28 19:42 ?7次下載
    <b class='flag-5'>USB</b> <b class='flag-5'>Hub</b>

    USB HUB一擴四/USB轉以太網(PHY)簡介

    3.0 HUB支持USB3.0,向下兼容USB2.0/1.1,理論帶寬達5Gbps; USB3.1 HUB支持
    發表于 03-17 23:22 ?6199次閱讀

    USB2.0 HUB高速4端口USB HUB集線器

    NS1.1S是一個高性能的符合USB 2.0高速4端口USB HUB集線器控制器.4個端口功能可同時工作,低功耗 采用NS1.1S USB2.0 H
    的頭像 發表于 04-03 15:38 ?2146次閱讀
    <b class='flag-5'>USB</b>2.0 <b class='flag-5'>HUB</b>高速4端口<b class='flag-5'>USB</b> <b class='flag-5'>HUB</b>集線器
    主站蜘蛛池模板: 色播在线永久免费视频网站 | 欧美黑人巨大日本人又爽又色 | 亚洲爽爽网 | 成年女人毛片免费观看97 | 久久天天丁香婷婷中文字幕 | 亚洲午夜精品久久久久久人妖 | 欧美激情第一欧美在线 | 美女黄网站 | 国产一区美女视频 | 黄色在线播放视频 | 一级毛片西西人体44rt高清 | 免费黄色大片网站 | 久久男人网 | 一本到卡二卡三卡福利 | 天天干夜夜曰 | 午夜久| 国产精品成人aaaaa网站 | 91操碰| 日本欧美一级 | 欧美最猛黑人xxxx黑人猛交69 | 免费一级大片 | 亚洲理论在线观看 | 一区二区三区在线观看免费 | 加勒比一木道|视频在线看 加勒比在线免费视频 | 二级片在线 | 日韩特级毛片免费观看视频 | 她也啪97在线视频 | 亚洲色图久久 | 夜夜爽天天爽 | 色婷婷欧美| 天天操天天操天天操香蕉 | 奇米狠狠干 | 色香影视| 亚洲精品久久久久午夜福 | 亚洲成a人片在线观看导航 亚洲成a人片在线观看尤物 | 狼狼狼色精品视频在线播放 | 国产无圣光高清一区二区 | 求毛片网站 | 好大好硬好爽免费视频 | 哟交小u女国产精品视频 | 亚洲最大成人 |