0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

USB設(shè)備在Linux系統(tǒng)中的識別和加載過程

嵌入式悅翔園 ? 來源:嵌入式悅翔園 ? 2023-05-10 11:53 ? 次閱讀

一、前言

不知道大家在學(xué)習(xí)Linux的時(shí)候有沒有過這樣的疑問,為什么我們通過同一個(gè)接口接入的不同USB設(shè)備,我們的電腦都可以識別到呢?為什么Linux電腦不會(huì)把鼠標(biāo)識別成鍵盤呢?帶著這些疑問我們一起來看一下USB的識別和加載過程。

二、USB設(shè)備的識別過程

當(dāng)我們插入一個(gè)USB設(shè)備時(shí),Linux內(nèi)核會(huì)自動(dòng)檢測并加載相應(yīng)的驅(qū)動(dòng)程序,使設(shè)備能夠正常工作。下面我們將深入探討USB設(shè)備在Linux系統(tǒng)中的識別和加載過程。

2.1 USB控制器檢測設(shè)備插入

USB控制器是一個(gè)硬件設(shè)備,用于控制USB總線上的設(shè)備。當(dāng)你插入一個(gè)USB設(shè)備時(shí),USB控制器會(huì)檢測到電壓變化并發(fā)出一個(gè)中斷信號。這個(gè)中斷信號被送到處理器上的USB控制器中斷線上,告訴Linux內(nèi)核有新的USB設(shè)備插入。

2.2 內(nèi)核檢測并加載驅(qū)動(dòng)程序

當(dāng)內(nèi)核接收到USB控制器發(fā)出的中斷信號時(shí),它會(huì)調(diào)用USB子系統(tǒng)中的usbcore模塊,該模塊負(fù)責(zé)檢測新的USB設(shè)備并加載相應(yīng)的驅(qū)動(dòng)程序。usbcore模塊首先會(huì)檢測設(shè)備的描述符,這個(gè)描述符包括設(shè)備的廠商ID、產(chǎn)品ID、類別碼等信息。

如果已經(jīng)存在一個(gè)匹配的驅(qū)動(dòng)程序,那么usbcore模塊就會(huì)加載這個(gè)驅(qū)動(dòng)程序。如果沒有匹配的驅(qū)動(dòng)程序,則會(huì)嘗試加載一個(gè)通用的驅(qū)動(dòng)程序,這個(gè)驅(qū)動(dòng)程序能夠支持大多數(shù)USB設(shè)備。

2.3 驅(qū)動(dòng)程序向USB子系統(tǒng)注冊

一旦正確的驅(qū)動(dòng)程序被加載,它會(huì)向USB子系統(tǒng)注冊并告訴它自己可以處理哪些設(shè)備。這一步通常包括向內(nèi)核注冊USB設(shè)備的類別(如存儲設(shè)備、輸入設(shè)備等)。

這個(gè)過程包括了向內(nèi)核注冊一個(gè)新的USB設(shè)備驅(qū)動(dòng)程序,并在該驅(qū)動(dòng)程序中指定設(shè)備的廠商ID、產(chǎn)品ID等信息。一旦驅(qū)動(dòng)程序被成功注冊,USB子系統(tǒng)就可以將設(shè)備與正確的驅(qū)動(dòng)程序進(jìn)行匹配。

2.4 USB子系統(tǒng)創(chuàng)建設(shè)備節(jié)點(diǎn)

USB子系統(tǒng)接下來會(huì)為設(shè)備創(chuàng)建一個(gè)設(shè)備節(jié)點(diǎn)。設(shè)備節(jié)點(diǎn)是一個(gè)特殊的文件,在/dev目錄下,它允許用戶空間程序與設(shè)備通信。設(shè)備節(jié)點(diǎn)的名稱通常是由內(nèi)核根據(jù)設(shè)備的廠商ID、產(chǎn)品ID和序列號等信息動(dòng)態(tài)生成的。

設(shè)備節(jié)點(diǎn)的創(chuàng)建是通過udev守護(hù)進(jìn)程實(shí)現(xiàn)的,這個(gè)守護(hù)進(jìn)程會(huì)監(jiān)視系統(tǒng)中的設(shè)備插拔事件,并自動(dòng)創(chuàng)建或刪除相應(yīng)的設(shè)備節(jié)點(diǎn)。創(chuàng)建設(shè)備節(jié)點(diǎn)之后,內(nèi)核就可以將設(shè)備的訪問權(quán)限分配給用戶空間程序。

2.5 驅(qū)動(dòng)程序初始化設(shè)備

驅(qū)動(dòng)程序被通知有新的設(shè)備插入后,它會(huì)對設(shè)備進(jìn)行初始化。初始化可能包括設(shè)置設(shè)備的傳輸速率、分配內(nèi)存緩沖區(qū)等。設(shè)備初始化完成后,驅(qū)動(dòng)程序會(huì)向USB子系統(tǒng)報(bào)告設(shè)備已準(zhǔn)備好。

2.6 用戶空間程序打開設(shè)備:

最后,用戶空間程序可以打開設(shè)備節(jié)點(diǎn)并與設(shè)備通信。設(shè)備節(jié)點(diǎn)的權(quán)限通常被設(shè)置為只允許root用戶或在相關(guān)組中的用戶訪問。用戶空間程序可以使用系統(tǒng)調(diào)用(如read和write)向設(shè)備發(fā)送命令和接收數(shù)據(jù)。

通過這個(gè)過程,Linux系統(tǒng)可以自動(dòng)識別設(shè)備并加載相應(yīng)的驅(qū)動(dòng)程序,使設(shè)備可以正常工作。這也是為什么當(dāng)我們插入一個(gè)USB設(shè)備時(shí),我們不需要手動(dòng)安裝任何驅(qū)動(dòng)程序或執(zhí)行任何其他操作就可以直接開始使用設(shè)備。

當(dāng)你插入一個(gè)USB設(shè)備時(shí),Linux系統(tǒng)會(huì)自動(dòng)執(zhí)行上述步驟,從而自動(dòng)識別設(shè)備并加載相應(yīng)的驅(qū)動(dòng)程序,使設(shè)備可以正常工作。下面我們從代碼的層面來分析一下該過程。

三、代碼實(shí)現(xiàn)講解

下面我通過一些示例代碼,講解一下USB設(shè)備在Linux系統(tǒng)中的識別和加載過程。這些示例代碼只是講解一下原理,實(shí)際代碼將會(huì)更加復(fù)雜。

3.1 檢測設(shè)備插入

當(dāng)USB設(shè)備插入到系統(tǒng)中時(shí),會(huì)產(chǎn)生一個(gè)中斷信號,這個(gè)信號會(huì)被處理器上的USB控制器中斷線捕獲,并由內(nèi)核的USB子系統(tǒng)處理。下面是一個(gè)示例代碼,演示如何檢測USB設(shè)備的插入和拔出事件:

#include
#include

intmain(){
libusb_device**devs;
libusb_context*ctx=NULL;

intr=libusb_init(&ctx);
if(r

這段代碼使用了libusb庫,這是一個(gè)C語言庫,用于訪問USB設(shè)備。它提供了一個(gè)用于初始化USB子系統(tǒng)和掃描USB總線的API,以及用于訪問USB設(shè)備的API。

3.2 加載驅(qū)動(dòng)程序

一旦檢測到設(shè)備插入,USB子系統(tǒng)會(huì)嘗試加載一個(gè)適當(dāng)?shù)尿?qū)動(dòng)程序。下面是一個(gè)示例驅(qū)動(dòng)程序代碼,它負(fù)責(zé)支持USB存儲設(shè)備(例如U盤):

#include
#include

staticstructusb_device_idstorage_devices[]={
{USB_DEVICE(0xabcd,0x1234)},
{USB_DEVICE(0xffff,0xffff)},
{}
};
MODULE_DEVICE_TABLE(usb,storage_devices);

staticintstorage_probe(structusb_interface*interface,conststructusb_device_id*id){
//初始化設(shè)備并注冊
return0;
}

staticvoidstorage_disconnect(structusb_interface*interface){
//釋放設(shè)備
}

staticstructusb_driverstorage_driver={
.name="usb-storage",
.probe=storage_probe,
.disconnect=storage_disconnect,
.id_table=storage_devices,
};

module_usb_driver(storage_driver);

這段代碼演示了一個(gè)簡單的驅(qū)動(dòng)程序,它可以處理USB存儲設(shè)備的插入和拔出事件。在加載驅(qū)動(dòng)程序時(shí),內(nèi)核將搜索已加載的驅(qū)動(dòng)程序列表,以查找與設(shè)備匹配的驅(qū)動(dòng)程序。

如果找到了匹配的驅(qū)動(dòng)程序,內(nèi)核將使用該驅(qū)動(dòng)程序來管理該設(shè)備。如果沒有找到匹配的驅(qū)動(dòng)程序,內(nèi)核將不會(huì)加載任何驅(qū)動(dòng)程序。

3.3 設(shè)備注冊

一旦找到了與設(shè)備匹配的驅(qū)動(dòng)程序,驅(qū)動(dòng)程序?qū)⒈患虞d并啟動(dòng),它將嘗試對設(shè)備進(jìn)行初始化,并將其注冊到內(nèi)核。下面是一個(gè)示例代碼,演示如何初始化USB存儲設(shè)備并將其注冊到內(nèi)核:

staticintstorage_probe(structusb_interface*interface,conststructusb_device_id*id){
structusb_device*dev=interface_to_usbdev(interface);

//獲取設(shè)備描述符
structusb_device_descriptordesc;
intr=usb_get_descriptor(dev,USB_DT_DEVICE,0,&desc,sizeof(desc));
if(r

上面這段示例代碼使用了內(nèi)核的usb_get_descriptor()函數(shù)來獲取設(shè)備描述符,并使用printk()函數(shù)將設(shè)備信息記錄到內(nèi)核日志中。

當(dāng)驅(qū)動(dòng)程序?qū)⒄{(diào)用設(shè)備初始化函數(shù)并將其注冊到內(nèi)核,但是由于設(shè)備初始化和注冊的過程因設(shè)備而異,因此這里省略了這部分代碼。

3.4 設(shè)備訪問

一旦設(shè)備已經(jīng)被注冊到內(nèi)核,用戶空間程序就可以通過設(shè)備節(jié)點(diǎn)來訪問設(shè)備。在Linux系統(tǒng)中,設(shè)備節(jié)點(diǎn)是一種特殊的文件,可以通過標(biāo)準(zhǔn)文件I/O函數(shù)來訪問。下面是一個(gè)示例代碼,演示如何打開并讀取USB存儲設(shè)備:

#include
#include
#include

intmain(){
//打開設(shè)備節(jié)點(diǎn)
intfd=open("/dev/sdb",O_RDONLY);
if(fd

這段代碼使用了標(biāo)準(zhǔn)的文件I/O函數(shù)來訪問設(shè)備節(jié)點(diǎn)。在這個(gè)例子中,設(shè)備節(jié)點(diǎn)的路徑是/dev/sdb,這是一個(gè)典型的USB存儲設(shè)備節(jié)點(diǎn)。接下來,程序?qū)⒃O(shè)備節(jié)點(diǎn)作為文件打開,并使用read()函數(shù)從設(shè)備中讀取數(shù)據(jù)。一旦完成數(shù)據(jù)的讀取,程序?qū)㈥P(guān)閉設(shè)備節(jié)點(diǎn)并退出。

四、結(jié)語

Linux系統(tǒng)識別USB設(shè)備的過程可以分為四個(gè)步驟:設(shè)備連接、驅(qū)動(dòng)匹配、設(shè)備注冊和設(shè)備訪問。當(dāng)用戶將USB設(shè)備插入計(jì)算機(jī)時(shí),內(nèi)核將通過USB總線來檢測設(shè)備的插入事件,并嘗試查找與設(shè)備匹配的驅(qū)動(dòng)程序。一旦找到了匹配的驅(qū)動(dòng)程序,驅(qū)動(dòng)程序?qū)⒈患虞d并啟動(dòng),它將嘗試對設(shè)備進(jìn)行初始化,并將其注冊到內(nèi)核。一旦設(shè)備已經(jīng)被注冊到內(nèi)核,用戶空間程序就可以通過設(shè)備節(jié)點(diǎn)來訪問設(shè)備。

在Linux系統(tǒng)中,驅(qū)動(dòng)程序是非常重要的組成部分,它們負(fù)責(zé)管理和控制系統(tǒng)中的各種設(shè)備。對于USB設(shè)備而言,內(nèi)核提供了一個(gè)通用的USB驅(qū)動(dòng)框架,它可以自動(dòng)檢測和加載驅(qū)動(dòng)程序,并為用戶提供了一個(gè)簡單而強(qiáng)大的USB設(shè)備訪問接口。通過深入理解USB驅(qū)動(dòng)程序的工作原理,我們可以更好地理解Linux系統(tǒng)中設(shè)備管理的內(nèi)部機(jī)制,這對于開發(fā)和調(diào)試設(shè)備驅(qū)動(dòng)程序非常有幫助。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16031

    瀏覽量

    176652
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    7846

    瀏覽量

    263306
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11170

    瀏覽量

    208469
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    588

    瀏覽量

    27265
  • 電腦
    +關(guān)注

    關(guān)注

    15

    文章

    1671

    瀏覽量

    68523
收藏 人收藏

    評論

    相關(guān)推薦

    Linux和Windows系統(tǒng)啟動(dòng)過程的簡單分析

    AT PPC.....bootloader特性:以命令為基礎(chǔ)。一旦引導(dǎo)啟動(dòng)系統(tǒng)后,bootloader就不存在。Linux和Windows啟動(dòng)過程中,基本的原理都差不多,都先加載一個(gè)
    發(fā)表于 08-28 11:27

    嵌入式Linux下的USB設(shè)備驅(qū)動(dòng)

    ,而且所有的配置過程都由系統(tǒng)自動(dòng)完成,無須用戶干預(yù)。1 Linux下的USB設(shè)備驅(qū)動(dòng)
    發(fā)表于 12-07 10:29

    怎么讓LinuxUSB設(shè)備識別以太網(wǎng)68053?

    我們正在考慮使用CyPress 68053作為我們的板的USB接口。我們希望董事會(huì)在Linux作為一個(gè)以太網(wǎng)接口(如我們的董事會(huì)是一個(gè)USB /以太網(wǎng)狗)。有沒有辦法讓Linux
    發(fā)表于 12-25 15:45

    基于USB接口的移動(dòng)存儲設(shè)備構(gòu)建微型操作系統(tǒng)

    文件系統(tǒng)的掛載,然后執(zhí)行系統(tǒng)的/***in/init 進(jìn)程。與普通IDE、SATA 硬盤相比,USB 接口存儲設(shè)備從驅(qū)動(dòng)模塊
    發(fā)表于 06-10 05:00

    PC沒有正確識別USB設(shè)備

    有人知道司機(jī)USB PC側(cè)嗎?有人用PIC32 MZ家族MPLABX運(yùn)行插件引導(dǎo)加載程序嗎?我用HARMONY編譯了基本的應(yīng)用程序引導(dǎo)程序,但是PC沒有正確
    發(fā)表于 09-27 15:05

    基于LinuxUSB設(shè)備驅(qū)動(dòng)方法有什么優(yōu)點(diǎn)?

    嵌入式linux系統(tǒng)環(huán)境以其易于移植裁減、內(nèi)核小、效率高、完整、原代碼開放及性能優(yōu)異等特點(diǎn),嵌入式領(lǐng)域得到了非常廣泛的應(yīng)用。LinuxUSB
    發(fā)表于 11-07 08:31

    全志H5芯片開發(fā)板香橙派PC2Linux系統(tǒng)下連接USB攝像頭的使用方法

    --no-banner 用于去除照片的水印c. -r 選項(xiàng)用于指定照片的分辨率d. -S 選項(xiàng)用設(shè)置于跳過前面的幀數(shù)6) 服務(wù)器版的 Linux 系統(tǒng),拍完照后可以使用 scp
    發(fā)表于 11-16 11:41

    為什么要配置Linux系統(tǒng)嵌入式設(shè)備的串口通信?

    Linux系統(tǒng)嵌入式設(shè)備的串口通信一. 為什么要配置串口通信? 嵌入式開發(fā)或者物聯(lián)網(wǎng)開發(fā)過程中,串口輸出數(shù)據(jù)是開發(fā)
    發(fā)表于 12-16 07:24

    USB設(shè)備端驅(qū)動(dòng)系統(tǒng)與嵌入式linux系統(tǒng)的實(shí)現(xiàn)

    嵌入式 linux 系統(tǒng)環(huán)境以其易于移植裁減、內(nèi)核小、效率高、完整、原代碼開放及性能優(yōu)異等特點(diǎn),嵌入式領(lǐng)域得到了非常廣泛的應(yīng)用。LinuxU
    發(fā)表于 10-31 16:15 ?4次下載
    <b class='flag-5'>USB</b><b class='flag-5'>設(shè)備</b>端驅(qū)動(dòng)<b class='flag-5'>系統(tǒng)</b>與嵌入式<b class='flag-5'>linux</b><b class='flag-5'>系統(tǒng)</b>的實(shí)現(xiàn)

    win7系統(tǒng)無法識別USB設(shè)備的解決辦法

    使用win7系統(tǒng)過程中,有時(shí)會(huì)遇到電腦無法識別USB設(shè)備的問題,遇到此問題的用戶,請來看看下面的解決方案吧。
    的頭像 發(fā)表于 08-10 16:14 ?1.2w次閱讀
    win7<b class='flag-5'>系統(tǒng)</b>無法<b class='flag-5'>識別</b><b class='flag-5'>USB</b><b class='flag-5'>設(shè)備</b>的解決辦法

    嵌入式Linux操作系統(tǒng)引導(dǎo)加載程序BootLoarder

    BootLoarder是什么Linux操作系統(tǒng)分層一個(gè)嵌入式Linux系統(tǒng)從軟件的角度看通??梢苑譃樗膫€(gè)層次:引導(dǎo)加載程序。包括固化
    發(fā)表于 11-01 17:05 ?8次下載
    嵌入式<b class='flag-5'>Linux</b>操作<b class='flag-5'>系統(tǒng)</b>引導(dǎo)<b class='flag-5'>加載</b>程序BootLoarder

    從軟件角度分析linux內(nèi)核USB系統(tǒng)的熱插拔過程

    本文從軟件角度分析linux內(nèi)核USB系統(tǒng)的熱插拔過程,以實(shí)際分析思路和過程行文,基于linux
    的頭像 發(fā)表于 01-15 09:28 ?5287次閱讀

    看一下USB識別和加載過程

    不知道大家在學(xué)習(xí)Linux的時(shí)候有沒有過這樣的疑問,為什么我們通過同一個(gè)接口接入的不同USB設(shè)備,我們的電腦都可以識別到呢?
    的頭像 發(fā)表于 05-10 11:54 ?5561次閱讀

    MATLAB如何保存和加載消息

    到MAT文件。 save ( 'posedata.mat' , 'posedata' ) 將文件加載回工作空間之前,清除posedata變量。 clear posedata 現(xiàn)在可以通過調(diào)用load
    的頭像 發(fā)表于 11-15 15:17 ?344次閱讀

    linux驅(qū)動(dòng)程序如何加載進(jìn)內(nèi)核

    Linux系統(tǒng),驅(qū)動(dòng)程序是內(nèi)核與硬件設(shè)備之間的橋梁。它們允許內(nèi)核與硬件設(shè)備進(jìn)行通信,從而實(shí)現(xiàn)
    的頭像 發(fā)表于 08-30 15:02 ?287次閱讀