亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? linux_usb_driver.txt

?? 基于LINUX操作系統下的各種詳細配置(如FTP
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
linux usb 驅動


我們知道了在Linux下如何去使用一些最常見的USB設備。但對于做系統設計的程序員來說,這是遠遠不夠的,我們還需要具有驅動程序的閱讀、修改和開發能力。在此下篇中,就是要通過簡單的USB驅動的例子,隨您一起進入USB驅動開發的世界。 

USB骨架程序(usb-skeleton),是USB驅動程序的基礎,通過對它源碼的學習和理解,可以使我們迅速地了解USB驅動架構,迅速地開發我們自己的USB硬件的驅動。 

USB驅動開發 

在掌握了USB設備的配置后,對于程序員,我們就可以嘗試進行一些簡單的USB驅動的修改和開發了。這一段落,我們會講解一個最基礎USB框架的基礎上,做兩個小的USB驅動的例子。 

USB骨架 

在Linux kernel源碼目錄中driver/usb/usb-skeleton.c為我們提供了一個最基礎的USB驅動程序。我們稱為USB骨架。通過它我們僅需要修改極少的部分,就可以完成一個USB設備的驅動。我們的USB驅動開發也是從她開始的。 

那些linux下不支持的USB設備幾乎都是生產廠商特定的產品。如果生產廠商在他們的產品中使用自己定義的協議,他們就需要為此設備創建特定的驅動程序。當然我們知道,有些生產廠商公開他們的USB協議,并幫助Linux驅動程序的開發,然而有些生產廠商卻根本不公開他們的USB協議。因為每一個不同的協議都會產生一個新的驅動程序,所以就有了這個通用的USB驅動骨架程序, 它是以pci 骨架為模板的。 

如果你準備寫一個linux驅動程序,首先要熟悉USB協議規范。USB主頁上有它的幫助。一些比較典型的驅動可以在上面發現,同時還介紹了USB urbs的概念,而這個是usb驅動程序中最基本的。 

Linux USB 驅動程序需要做的第一件事情就是在Linux USB 子系統里注冊,并提供一些相關信息,例如這個驅動程序支持那種設備,當被支持的設備從系統插入或拔出時,會有哪些動作。所有這些信息都傳送到USB 子系統中,在usb骨架驅動程序中是這樣來表示的: 


static struct usb_driver skel_driver = { 
name: "skeleton", 
probe: skel_probe, 
disconnect: skel_disconnect, 
fops: &skel_fops, 
minor: USB_SKEL_MINOR_BASE, 
id_table: skel_table, 
}; 



變量name是一個字符串,它對驅動程序進行描述。probe 和disconnect 是函數指針,當設備與在id_table 中變量信息匹配時,此函數被調用。 

fops和minor變量是可選的。大多usb驅動程序鉤住另外一個驅動系統,例如SCSI,網絡或者tty子系統。這些驅動程序在其他驅動系統中注冊,同時任何用戶空間的交互操作通過那些接口提供,比如我們把SCSI設備驅動作為我們USB驅動所鉤住的另外一個驅動系統,那么我們此USB設備的read、write等操作,就相應按SCSI設備的read、write函數進行訪問。但是對于掃描儀等驅動程序來說,并沒有一個匹配的驅動系統可以使用,那我們就要自己處理與用戶空間的read、write等交互函數。Usb子系統提供一種方法去注冊一個次設備號和file_operations函數指針,這樣就可以與用戶空間實現方便地交互。


USB骨架程序的關鍵幾點如下: 

USB驅動的注冊和注銷 
Usb驅動程序在注冊時會發送一個命令給usb_register,通常在驅動程序的初始化函數里。 

當要從系統卸載驅動程序時,需要注銷usb子系統。即需要usb_unregister 函數處理: 


static void __exit usb_skel_exit(void) 
{ 
/* deregister this driver with the USB subsystem */ 
usb_deregister(&skel_driver); 
} 
module_exit(usb_skel_exit); 




當usb設備插入時,為了使linux-hotplug(Linux中PCI、USB等設備熱插拔支持)系統自動裝載驅動程序,你需要創建一個MODULE_DEVICE_TABLE。代碼如下(這個模塊僅支持某一特定設備): 


/* table of devices that work with this driver */ 
static struct usb_device_id skel_table [] = { 
{ USB_DEVICE(USB_SKEL_VENDOR_ID, 
USB_SKEL_PRODUCT_ID) }, 
{ } /* Terminating entry */ 
}; 

MODULE_DEVICE_TABLE (usb, skel_table); 




USB_DEVICE宏利用廠商ID和產品ID為我們提供了一個設備的唯一標識。當系統插入一個ID匹配的USB設備到USB總線時,驅動會在USB core中注冊。驅動程序中probe 函數也就會被調用。usb_device 結構指針、接口號和接口ID都會被傳遞到函數中。 


static void * skel_probe(struct usb_device *dev, 
unsigned int ifnum, const struct usb_device_id *id) 




驅動程序需要確認插入的設備是否可以被接受,如果不接受,或者在初始化的過程中發生任何錯誤,probe函數返回一個NULL值。否則返回一個含有設備驅動程序狀態的指針。通過這個指針,就可以訪問所有結構中的回調函數。 

在骨架驅動程序里,最后一點是我們要注冊devfs。我們創建一個緩沖用來保存那些被發送給usb設備的數據和那些從設備上接受的數據,同時USB urb 被初始化,并且我們在devfs子系統中注冊設備,允許devfs用戶訪問我們的設備。注冊過程如下: 


/* initialize the devfs node for this device 
and register it */ 
sprintf(name, "skel%d", skel->minor); 
skel->devfs = devfs_register 
(usb_devfs_handle, name, 
DEVFS_FL_DEFAULT, USB_MAJOR, 
USB_SKEL_MINOR_BASE + skel->minor, 
S_IFCHR | S_IRUSR | S_IWUSR | 
S_IRGRP | S_IWGRP | S_IROTH, 
&skel_fops, NULL); 




如果devfs_register函數失敗,不用擔心,devfs子系統會將此情況報告給用戶。 

當然最后,如果設備從usb總線拔掉,設備指針會調用disconnect 函數。驅動程序就需要清除那些被分配了的所有私有數據、關閉urbs,并且從devfs上注銷調自己。





/* remove our devfs node */ 
devfs_unregister(skel->devfs); 




現在,skeleton驅動就已經和設備綁定上了,任何用戶態程序要操作此設備都可以通過file_operations結構所定義的函數進行了。首先,我們要open此設備。在open函數中MODULE_INC_USE_COUNT 宏是一個關鍵,它的作用是起到一個計數的作用,有一個用戶態程序打開一個設備,計數器就加一,例如,我們以模塊方式加入一個驅動,若計數器不為零,就說明仍然有用戶程序在使用此驅動,這時候,你就不能通過rmmod命令卸載驅動模塊了。 



/* increment our usage count for the module */ 
MOD_INC_USE_COUNT; 
++skel->open_count; 
/* save our object in the file's private structure */ 
file->private_data = skel; 




當open完設備后,read、write函數就可以收、發數據了。 

skel的write、和read函數 
他們是完成驅動對讀寫等操作的響應。 

在skel_write中,一個FILL_BULK_URB函數,就完成了urb 系統callbak和我們自己的skel_write_bulk_callback之間的聯系。注意skel_write_bulk_callback是中斷方式,所以要注意時間不能太久,本程序中它就只是報告一些urb的狀態等。 

read 函數與write 函數稍有不同在于:程序并沒有用urb 將數據從設備傳送到驅動程序,而是我們用usb_bulk_msg 函數代替,這個函數能夠不需要創建urbs 和操作urb函數的情況下,來發送數據給設備,或者從設備來接收數據。我們調用usb_bulk_msg函數并傳提一個存儲空間,用來緩沖和放置驅動收到的數據,若沒有收到數據,就失敗并返回一個錯誤信息。 

usb_bulk_msg函數 
當對usb設備進行一次讀或者寫時,usb_bulk_msg 函數是非常有用的; 然而, 當你需要連續地對設備進行讀/寫時,建議你建立一個自己的urbs,同時將urbs 提交給usb子系統。 

skel_disconnect函數 
當我們釋放設備文件句柄時,這個函數會被調用。MOD_DEC_USE_COUNT宏會被用到(和MOD_INC_USE_COUNT剛好對應,它減少一個計數器),首先確認當前是否有其它的程序正在訪問這個設備,如果是最后一個用戶在使用,我們可以關閉任何正在發生的寫,操作如下: 



/* decrement our usage count for the device */ 
--skel->open_count; 
if (skel->open_count <= 0) { 
/* shutdown any bulk writes that might be 
going on */ 
usb_unlink_urb (skel->write_urb); 
skel->open_count = 0; 
} 
/* decrement our usage count for the module */ 
MOD_DEC_USE_COUNT;







最困難的是,usb 設備可以在任何時間點從系統中取走,即使程序目前正在訪問它。usb驅動程序必須要能夠很好地處理解決此問題,它需要能夠切斷任何當前的讀寫,同時通知用戶空間程序:usb設備已經被取走。 

如果程序有一個打開的設備句柄,在當前結構里,我們只要把它賦值為空,就像它已經消失了。對于每一次設備讀寫等其它函數操作,我們都要檢查usb_device結構是否存在。如果不存在,就表明設備已經消失,并返回一個-ENODEV錯誤給用戶程序。當最終我們調用release 函數時,在沒有文件打開這個設備時,無論usb_device結構是否存在、它都會清空skel_disconnect函數所作工作。 

Usb 骨架驅動程序,提供足夠的例子來幫助初始人員在最短的時間里開發一個驅動程序。更多信息你可以到linux usb開發新聞組去尋找。



U盤、USB讀卡器、MP3、數碼相機驅動 

對于一款windows下用的很爽的U盤、USB讀卡器、MP3或數碼相機,可能Linux下卻不能支持。怎么辦?其實不用傷心,也許經過一點點的工作,你就可以很方便地使用它了。通常是此U盤、USB讀卡器、MP3或數碼相機在WindowsXP中不需要廠商專門的驅動就可以識別為移動存儲設備,這樣的設備才能保證成功,其他的就看你的運氣了。 

USB存儲設備,他們的read、write等操作都是通過上章節中提到的鉤子,把自己的操作鉤到SCSI設備上去的。我們就不需要對其進行具體的數據讀寫處理了。 

第一步:我們通過cat /proc/bus/usb/devices得到當前系統探測到的USB總線上的設備信息。它包括Vendor、ProdID、Product等。下面是我買的一款雜牌CF卡讀卡器插入后的信息片斷: 



T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 5 Spd=12 MxCh= 0 
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=8 #Cfgs= 1 
P: Vendor=07c4 ProdID=a400 Rev= 1.13 
S: Manufacturer=USB 
S: Product=Mass Storage 
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=70mA 
I: If#= 0 Alt= 0 #EPs= 2 Cls=08(vend.) Sub=06 Prot=50 Driver=usb-storage 
E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl= 0ms 
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl= 0ms 




其中,我們最關心的是Vendor=07c4 ProdID=a400和Manufacturer=USB(果然是雜牌,廠商名都看不到)Product= Mass Storage。 

對于這些移動存儲設備,我們知道Linux下都是通過usb-storage.o驅動模擬成scsi設備去支持的,之所以不支持,通常是usb-storage驅動未包括此廠商識別和產品識別信息(在類似skel_probe的USB最初探測時被屏蔽了)。對于USB存儲設備的硬件訪問部分,通常是一致的。所以我們要支持它,僅需要修改usb-storage中關于廠商識別和產品識別列表部分。 

第二部,打開drivers/usb/storage/unusual_devs.h文件,我們可以看到所有已知的產品登記表,都是以UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, vendor_name, product_name, use_protocol, use_transport, init_function, Flags)方式登記的。其中相應的涵義,你就可以根據命名來判斷了。所以只要我們如下填入我們自己的注冊,就可以讓usb-storage驅動去認識和發現它。 


UNUSUAL_DEV(07c4, a400, 0x0000, 0xffff, 
" USB ", " Mass Storage ", 
US_SC_SCSI, US_PR_BULK, NULL, 
US_FL_FIX_INQUIRY | US_FL_START_STOP |US_FL_MODE_XLATE ) 




注意:添加以上幾句的位置,一定要正確。比較發現,usb-storage驅動對所有注冊都是按idVendor, idProduct數值從小到大排列的。我們也要放在相應位置。 

最后,填入以上信息,我們就可以重新編譯生成內核或usb-storage.o模塊。這時候插入我們的設備就可以跟其他U盤一樣作為SCSI設備去訪問了。



目前很多鍵盤都有飛梭和手寫板,下面我們就嘗試為一款鍵盤飛梭加入一個驅動。在通常情況,當我們插入USB接口鍵盤時,在/proc/bus/usb/devices會看到多個USB設備。比如:你的USB鍵盤上的飛梭會是一個,你的手寫板會是一個,若是你的USB鍵盤有USB擴展連接埠,也會看到。 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩亚洲高清一区二区| 欧美综合亚洲图片综合区| 亚洲福利电影网| 日韩伦理电影网| 亚洲视频中文字幕| 亚洲天堂2014| 亚洲欧美激情一区二区| 亚洲人被黑人高潮完整版| 亚洲精品乱码久久久久| 亚洲综合激情另类小说区| 亚洲婷婷综合久久一本伊一区| 久久精品日产第一区二区三区高清版 | 免费精品视频最新在线| 亚洲成人动漫在线观看| 久久福利资源站| 国产九色精品成人porny| 东方欧美亚洲色图在线| 成人av电影观看| 欧美日韩视频专区在线播放| 欧美一区二区在线免费观看| 精品日韩在线观看| 国产精品区一区二区三区| 综合在线观看色| 奇米在线7777在线精品| 国产激情精品久久久第一区二区 | 亚洲免费观看在线视频| 亚洲成人免费av| 国产尤物一区二区在线| 91猫先生在线| 日韩欧美一二区| 中文字幕一区二区三区精华液 | 丁香亚洲综合激情啪啪综合| 色综合激情久久| 日韩午夜精品电影| 久久久国产午夜精品| 亚洲伦理在线精品| 久久er精品视频| 99精品久久只有精品| 日韩午夜av电影| 亚洲精品成人悠悠色影视| 轻轻草成人在线| 日本韩国精品在线| 欧美精品一区二| 亚洲成人先锋电影| 不卡视频在线看| 精品88久久久久88久久久| 亚洲国产另类av| 成人精品鲁一区一区二区| 日韩精品一区二区三区在线观看| 自拍偷在线精品自拍偷无码专区| 狠狠色丁香婷婷综合久久片| 欧美视频你懂的| 国产精品福利一区二区三区| 激情综合色播五月| 欧美猛男超大videosgay| 国产精品久久久久aaaa樱花 | 欧美三级中文字幕在线观看| 欧美激情在线看| 毛片av一区二区| 欧美日韩视频专区在线播放| 亚洲人快播电影网| av中文字幕不卡| 久久精品亚洲一区二区三区浴池| 日本亚洲最大的色成网站www| 精品视频免费在线| 一区二区免费看| www.欧美色图| 国产精品传媒入口麻豆| 国产成人精品一区二区三区四区| 2023国产精品视频| 看片网站欧美日韩| 欧美va亚洲va在线观看蝴蝶网| 青青草一区二区三区| 欧美久久免费观看| 日本在线不卡一区| 日韩欧美国产综合一区 | 亚洲精品在线网站| 国产一区在线看| 国产欧美精品国产国产专区| 成人免费看视频| 久久久91精品国产一区二区精品| 国产麻豆精品视频| 国产精品视频麻豆| 91小视频在线免费看| 亚洲第一会所有码转帖| 欧美一区二区三区日韩视频| 久久不见久久见免费视频7| 久久一区二区视频| 成人性生交大片免费| 亚洲欧美日韩一区二区 | 久久精品一区二区三区av| 国产美女在线观看一区| 国产拍揄自揄精品视频麻豆| 99久久久国产精品| 亚洲aaa精品| 久久久久久久久岛国免费| 国产a久久麻豆| 亚洲国产aⅴ天堂久久| 日韩欧美国产午夜精品| 成人自拍视频在线| 亚洲超丰满肉感bbw| 精品成人一区二区三区四区| www.日本不卡| 青草av.久久免费一区| 国产精品色一区二区三区| 在线观看日韩高清av| 国产在线国偷精品免费看| 亚洲美女免费在线| 精品久久五月天| 色av成人天堂桃色av| 精品亚洲成a人在线观看| 日韩理论片在线| 日韩欧美高清在线| 色婷婷国产精品| 国产精品一区在线| 亚洲一级二级在线| 国产精品第13页| 26uuu精品一区二区三区四区在线| 在线视频你懂得一区| 国产精品一二三区在线| 亚洲成人综合网站| 亚洲啪啪综合av一区二区三区| 亚洲精品一区二区三区精华液 | 蜜臀久久99精品久久久久久9| 国产精品毛片大码女人| 欧美一区二区三区喷汁尤物| 91日韩精品一区| 国产精品77777| 日韩和欧美一区二区| 亚洲精品综合在线| 国产亚洲制服色| 精品女同一区二区| 欧美人与z0zoxxxx视频| 94-欧美-setu| 99久久精品一区二区| 东方aⅴ免费观看久久av| 国产综合久久久久久久久久久久| 亚洲6080在线| 亚洲一区二区在线视频| 综合久久国产九一剧情麻豆| 欧美极品少妇xxxxⅹ高跟鞋 | 亚洲男女一区二区三区| 国产精品国产三级国产普通话蜜臀| 久久久久青草大香线综合精品| 欧美成人三级在线| 欧美不卡一区二区三区| 91精品国产高清一区二区三区蜜臀| 欧美日韩久久不卡| 777a∨成人精品桃花网| 91精品黄色片免费大全| 久久精品视频网| 国产喂奶挤奶一区二区三区| 久久久欧美精品sm网站| 久久久久青草大香线综合精品| 久久视频一区二区| 国产人妖乱国产精品人妖| 日本一区二区成人在线| 中文字幕亚洲欧美在线不卡| 亚洲色图清纯唯美| 亚洲欧美日韩国产一区二区三区| 自拍偷拍亚洲欧美日韩| 亚洲一区二区三区四区五区中文| 亚洲福中文字幕伊人影院| 秋霞电影网一区二区| 国内精品国产三级国产a久久| 国产在线国偷精品产拍免费yy | 亚洲精品日韩综合观看成人91| 亚洲免费在线观看视频| 亚洲国产精品久久不卡毛片 | 91九色02白丝porn| 欧美区在线观看| 2024国产精品| 亚洲裸体在线观看| 毛片基地黄久久久久久天堂| 国产成人av一区二区| 91精品办公室少妇高潮对白| 91麻豆精品国产自产在线观看一区 | 激情小说亚洲一区| 99久久伊人久久99| 欧美视频一区二区三区四区| 日韩欧美一区在线| 亚洲国产精品成人综合色在线婷婷 | 亚洲综合色视频| 男女男精品视频网| 成人a免费在线看| 欧美日韩亚洲不卡| 日本一区二区免费在线| 亚洲一区二区五区| 韩国三级中文字幕hd久久精品| 成人免费毛片嘿嘿连载视频| 欧美精品在线视频| 中文字幕欧美三区| 视频一区在线视频| 99久久精品国产麻豆演员表| 日韩女优av电影| 亚洲品质自拍视频| 国产精品1区二区.| 日韩一区二区在线看| 一区二区三区影院| 99在线视频精品|