目錄
1. USB主機" >1. USB主機
\2. USB裝置" >\2. USB裝置
\3. 在USB設備組織架構中,從上到下分為設備(device)、設定(config)、介面(interface)和端點(endpoint)四個層次。 USB裝置程式綁定到介面上。 " >\3. 在USB設備組織架構中,從上到下分為設備(device)、設定(config)、介面(interface)和端點(endpoint)四個層次。 USB裝置程式綁定到介面上。
\5. 資料結構" >\5. 資料結構
\6. USB端點分類" >\6. USB端點分類
\7. endpoint" >\7. endpoint
\8. urb" >\8. urb
\9. 探測與斷開" >\9. 探測與斷開
首頁 系統教程 Linux 詳解Linux USB驅動程式工作流程

詳解Linux USB驅動程式工作流程

Feb 09, 2024 pm 06:40 PM
linux linux教程 linux系統 linux指令 shell腳本 資料遺失 b網 嵌入式linux linux入門 linux學習

Linux核心驅動是Linux系統中最重要的組成部分之一。它們負責與硬體設備進行通信,使得作業系統能夠正確地識別和使用硬體。然而,開發Linux核心驅動並不是一件容易的事。在本文中,我們將深入探討Linux核心驅動的實作方法,為讀者提供全面的了解與指導。

详解Linux USB驱动工作流程

1. USB主機

#在Linux驅動中,USB驅動處於最底層的是USB主機控制器硬件,在其之上運行的是USB主機控制器驅動,主機控制器之上為USB核心層,再上層為USB設備驅動層(插入主機上的USB隨身碟、滑鼠、USB轉串口等裝置驅動程式)。

因此,在主機側的層次結構中,要實現的USB驅動包括兩類:USB主機控制器驅動和USB設備驅動,前者控制插入其中的USB設備,後者控制USB設備如何與主機通訊。 Linux核心USB核心負責USB驅動管理和協定處理的主要工作。主機控制器驅動和設備驅動之間的USB核心非常重要,其功能包括:透過定義一些資料結構、巨集和功能函數,向上為設備驅動提供編程接口,向下為USB主機控制器驅動提供編程接口;透過全域變數維護整個系統的USB設備資訊;完成設備熱插拔控制、匯流排資料傳輸控制等。

\2. USB裝置

#Linux核心中USB裝置側驅動程式分為3個層次:UDC驅動程式、Gadget API和Gadget驅動程式。 UDC驅動程式直接存取硬件,控制USB設備和主機間的底層通信,向上層提供與硬體相關操作的回調函數。目前Gadget API是UDC驅動程式回呼函數的簡單包裝。 Gadget驅動程式具體控制USB設備功能的實現,使設備表現出「網路連接」、「印表機」或「USB Mass Storage」等特性,它使用Gadget API控制UDC實現上述功能。 Gadget API把下層的UDC驅動程式和上層的Gadget驅動程式隔離開,使得在Linux系統中編寫USB設備側驅動程式時能夠把功能的實作和底層通訊分開。

\3. 在USB設備組織架構中,從上到下分為設備(device)、設定(config)、介面(interface)和端點(endpoint)四個層次。 USB裝置程式綁定到介面上。

對於這四個層次的簡單描述如下:
設備通常具有一個或多個的配置
配置經常具有一個或多個的介面
介面沒有或具有一個以上的端點

详解Linux USB驱动工作流程

\4. USB通訊最基本的形式是透過端點(USB端點分**中斷(Interrupt)、批次(Bulk)、等時(ISO)、控制(Control)**四種,每種用途不同),USB端點只能往一個方向傳送數據,從主機到設備或從設備到主機,端點可以看作是單向的管道(pipe)。驅動程式把驅動程式物件註冊到USB子系統中,稍後再使用製造商和裝置識別來判斷是否已經安裝了硬體。 USB核心使用一個清單(是一個包含製造商ID和設備號ID的一個結構體)來判斷對於一個設備該使用哪一個驅動程序,熱插撥腳本使用它來確定當一個特定的設備插入到系統時該自動執行哪一個驅動程式的Probe。

\5. 資料結構

\1) USB裝置:對應資料結構struct usb_device

\2) 設定:struct usb_host_config (任一時刻,只能有一個設定生效)

3)USB介面:struct usb_interface (USB 核心將其傳遞給USB裝置驅動,並由USB裝置驅動負責後續的控制。一個USB介面代表一個基本功能,每個USB驅動控制一個介面。所以一個物理上的硬體設備可能需要一個以上的驅動程式。)

4)端點: struct usb_host_endpoint ,它所包含的真實端點資訊在另一個結構中:struct usb_endpoint_descriptor(端點描述符,包含所有的USB特定資料)。

\6. USB端點分類

USB 通訊的最基本形式是透過一個稱為端點的東西。一個USB端點只能向一個方向傳輸資料(從主機到設備(稱為輸出端點)或從設備到主機(稱為輸入端點))。端點可被看作單向的管道。

USB 端點有 4 種不同類型, 分別具有不同的資料傳送方式:

1) 控制CONTROL
控制端點被用來控制對USB設備的不同部分存取. 通常用作配置設備、獲取設備資訊、發送命令到設備或獲取設備狀態報告。這些端點通常較小。每個 USB 裝置都有一個控制端點稱為」端點 0″, 被 USB 核心用來在插入時配置裝置。 USB協定保證總有足夠的頻寬留給控制端點傳送資料到裝置.

2)中斷INTERRUPT
每當 USB 主機向裝置要求資料時,中斷端點以固定的速率傳送小量的資料。此為USB 鍵盤和滑鼠的主要的資料傳送方法。它也用以傳送資料到USB設備來控制設備。通常不用來傳送大量資料。 USB協定保證總有足夠的頻寬留給中斷端點傳送資料到裝置.

3) 批次BULK
批量端點用以傳送大量資料。這些端點通常比中斷端點大得多. 它們普遍用於不能有任何資料遺失的情況。 USB 協定不保證傳輸在特定時間範圍內完成。如果總線上沒有足夠的空間來傳送整個BULK包,它會被分成多個包進行傳輸。這些端點普遍用於印表機、USB Mass Storage和USB網路設備上。

4) 等時ISOCHRONOUS
等時端點也批量傳送大量資料, 但是這個資料不被保證能送達。這些端點用在可以處理資料遺失的裝置中,並且更依賴保持持續的資料流。如音訊和視訊設備等等。

控制和批次端點用於非同步資料傳送,而中斷和等時端點是週期性的。這意味著這些端點被設定來在固定的時間連續傳送數據,USB 核心為它們保留了相應的頻寬。

\7. endpoint

struct usb_host_endpoint{  struct usb_endpoint_descriptor desc;//端点描述符  struct list_head urb_list;//此端点的URB对列,由USB核心维护  void *hcpriv;  struct ep_device *ep_dev; /* For sysfs info */  unsigned char*extra;/* Extra descriptors */  int extralen;  int enabled;};
登入後複製

當呼叫USB裝置驅動程式呼叫usb_submit_urb提交urb請求時,將呼叫int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)把此urb增加到urb_list的尾巴上。 (hcd: Host Controller Driver,對應資料結構struct usb_hcd )

\8. urb

所有USB通訊均為請求–>回應模式,USB裝置不會主動向Host傳送資料。寫入資料:USB設備驅動發送urb請求給USB設備,USB設備不需要回資料。讀取資料:USB設備驅動程式發送urb請求給USB設備,USB設備需要回資料。

USB 裝置驅動透過urb和所有的 USB 裝置通訊。 urb以 struct urb 結構描述(include/linux/usb.h )。
urb 以一種非同步的方式在同一個特定USB設備的特定端點發送或接受資料。一個 USB 裝置驅動可根據驅動的需要,分配多個 urb 給一個端點或重複使用單一 urb 給多個不同的端點。裝置中的每個端點都處理一個 urb 佇列, 所以多個 urb 可在佇列清空之前被傳送到相同的端點。

一個 urb 的典型生命循環如下:
(1)被創建;
(2)被指派給一個特定 USB 裝置的特定端點;
(3)被提交給 USB 核心;
(4)被 USB 核心提交給特定裝置的特定 USB 主機控制器驅動;
(5)由 USB 主機控制器驅動處理, 並傳送到裝置;
(6)以上操作完成後,USB主機控制器驅動程式通知 USB 裝置驅動程式。

urb 也可被提交它的驅動程式在任何時間取消;如果裝置被移除,urb 可以被USB核心取消。 urb 被動態建立並包含一個內部引用計數,使它們可以在最後一個使用者釋放它們時自動釋放。

8.1 提交 urb

一旦 urb 被正確地創建並初始化, 它就可以提交給 USB 核心以發送出到 USB 設備. 這透過調用函數sb_submit_urb 實現.

int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
參數:
struct urb *urb :指向被提交的 urb 的指標
gfp_t mem_flags :使用傳遞給 kmalloc 呼叫相同的參數, 用來告訴 USB 核心如何及時分配記憶體緩衝

#因為函數 usb_submit_urb 可被在任何時候被呼叫(包括從一個中斷上下文), mem_flags 變數必須正確設定. 根據 usb_submit_urb 被呼叫的時間,只有 3 個有效值可用:

GFP_ATOMIC
只要滿足以下條件,就應使用此值:
\1) 呼叫者處於一個 urb 結束處理例程,中斷處理例程,底半部,tasklet或一個定時器回呼函數.
\2) 呼叫者持有自旋鎖定或讀寫鎖定. 注意如果正持有一個信號量, 這個值不必要.
\3) current->state 不是 TASK_RUNNING. 除非驅動程式已自行改變 current 狀態,否則狀態應該一直是TASK_RUNNING .

GFP_NOIO
驅動程式處於區塊 I/O 處理過程中. 它也應當用在所有的儲存類型的錯誤處理過程中.

GFP_KERNEL
所有不屬於之前提到的其他情況

在 urb 成功提交給 USB 核心之後, 直到結束處理例程函數被呼叫前,都不能存取 urb 結構的任何成員

8.2 urb結束處理例程

如果usb_submit_urb 被成功呼叫, 並且把對urb 的控制權傳遞給USB 核心, 函數返回0; 否則返回一個負的錯誤代碼. 如果函數調用成功, 當urb 被結束的時候結束處理例程會被呼叫一次.當這個函數被呼叫時, USB 核心就完成了這個urb, 並將它的控制權回傳給裝置驅動.

只有3 種結束urb並呼叫結束處理例程的情況:
(1)urb 成功傳送給裝置, 且裝置傳回正確的確認.如果這樣, urb 中的status變數被設定為 0.
(2)發生錯誤, 錯誤值記錄在 urb 結構中的 status 變數.
(3)urb 從 USB 核心unlink. 這發生在要么當驅動通過調用 usb_unlink_urb 或 usb_kill_urb告知 USB 核心取消一個已提交的 urb,或者在一個 urb 已經被提交給它時設備從系統中去除.

\9. 探測與斷開

在 struct usb_driver 結構中, 有 2 個 USB 核心在適當的時候調用的函數:
(1)當設備插入時, 如果USB 核心認為這個驅動可以處理(USB核心使用一個列表(是一個包含製造商ID和設備號ID的一個結構體)來判斷對於一個設備該使用哪一個驅動程序) ,則呼叫探測(probe)函數,探測函數檢查傳遞給它的設備資訊, 並判斷驅動是否真正合適這個設備.
(2)由於某些原因,設備被移除或驅動不再控制設備時,調用斷開(disconnect)函數,做適當清理.

探測和斷開回調函數都在USB集線器內核線程上下文中被調用, 因此它們休眠是合法的. 為了縮短USB 探測時間,大部分工作盡可能在設備打開時完成。這是因為USB 核心是在一個執行緒中處理USB 設備的添加和移除, 因此任何慢設備驅動都可能使USB 設備探測時間變長。

9.1探測函數分析
在探測回調函數中, USB設備驅動應當初始化它可能用來管理USB 設備的所有本地結構並保存所有需要的設備信息到本地結構, 因為在此時做這些通常更容易.為了和設備通訊,USB 驅動通常要探測設備的端點位址和緩衝大小.

在本文中,我們詳細介紹了Linux核心驅動的實作方法,包括核心驅動的框架、核心模組的編寫、裝置驅動的註冊與註銷等方面。我們相信,透過本文的學習,讀者可以更深入地了解Linux核心驅動的實作原理,為自己的開發工作提供更多的參考和幫助。

以上是詳解Linux USB驅動程式工作流程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

sublime寫好代碼後如何運行 sublime寫好代碼後如何運行 Apr 16, 2025 am 08:51 AM

在 Sublime 中運行代碼的方法有六種:通過熱鍵、菜單、構建系統、命令行、設置默認構建系統和自定義構建命令,並可通過右鍵單擊項目/文件運行單個文件/項目,構建系統可用性取決於 Sublime Text 的安裝情況。

laravel安裝代碼 laravel安裝代碼 Apr 18, 2025 pm 12:30 PM

要安裝 Laravel,需依序進行以下步驟:安裝 Composer(適用於 macOS/Linux 和 Windows)安裝 Laravel 安裝器創建新項目啟動服務訪問應用程序(網址:http://127.0.0.1:8000)設置數據庫連接(如果需要)

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

git軟件安裝 git軟件安裝 Apr 17, 2025 am 11:57 AM

安裝 Git 軟件包括以下步驟:下載安裝包運行安裝包驗證安裝配置 Git安裝 Git Bash(僅限 Windows)

VSCode怎麼用 VSCode怎麼用 Apr 15, 2025 pm 11:21 PM

Visual Studio Code (VSCode) 是一款跨平台、開源且免費的代碼編輯器,由微軟開發。它以輕量、可擴展性和對眾多編程語言的支持而著稱。要安裝 VSCode,請訪問官方網站下載並運行安裝程序。使用 VSCode 時,可以創建新項目、編輯代碼、調試代碼、導航項目、擴展 VSCode 和管理設置。 VSCode 適用於 Windows、macOS 和 Linux,支持多種編程語言,並通過 Marketplace 提供各種擴展。它的優勢包括輕量、可擴展性、廣泛的語言支持、豐富的功能和版

See all articles