usb是我們常用的介面,它有四條引腳線:5v、d+、d-、gnd。pc的usb口的d+、d-接有下拉電阻,平時處於低電平狀態。usb裝置的usb口內部,d-或d+接有1.5k的上拉電阻;它一接入pc,就會把pc的usb口的d-或d+拉高,從硬體的角度通知pc有新裝置接入。所以usb能夠自動監測裝置。
簡單來說,usb驅動分為兩塊,一塊是usb匯流排驅動,這個在linux核心裡已經給我們做好了。當接入usb裝置時,它能察覺到usb裝置的接入,給usb裝置分配編號(位址),並告訴usb裝置給它分配的編號(位址)是多少,和獲取usb裝置的描述符。然後通過裝置描述符的資訊找打對應的usb裝置驅動程式,並給usb裝置驅動程式提供讀寫函式。第二塊就是usb裝置驅動程式,我們需要做的就是這一塊。usb裝置驅動程式用通過usb匯流排驅動程式提供的讀寫函式,根據不同的資料做不同的事情。
其他的一些概念:
1、usb是主從結構的,所有的usb傳輸都是從usb主機這方發起的,usb裝置沒有」主動」通知usb主機的能力。例子:usb滑鼠滑動一下立刻產生資料,但是它沒有能力通知pc機來讀資料,只能被動地等得pc機來讀。
2、 usb的傳輸型別:
a. 控制傳輸:可靠,時間***,比如:usb裝置的識別過程
b. 批量傳輸: 可靠, 時間沒***, 比如:u盤
c. 中斷傳輸:可靠,實時,比如:usb滑鼠
d. 實時傳輸:不可靠,實時,比如:usb攝像頭
3、usb傳輸的物件:端點(endpoint)
我們說」讀u盤」、」寫u盤」,可以細化為:把資料寫到u盤的端點1,從u盤的端點2裡讀出資料。除了端點0外,每乙個端點只支援乙個方向的資料傳輸,端點0用於控制傳輸,既能輸出也能輸入。
4、 每乙個端點都有傳輸型別,傳輸方向。
5、 術語裡、程式裡說的輸入(in)、輸出(out) 「都是」 基於usb主機的立場說的。比如滑鼠的資料是從滑鼠傳到pc機, 對應的端點稱為」輸入端點」。
6、usb匯流排驅動程式的作用
a. 識別usb裝置
b. 查詢並安裝對應的裝置驅動程式
c. 提供usb讀寫函式
uhci: intel, 低速(1.5mbps)/全速(12mbps)
ohci: microsoft 低速/全速
ehci: 高速(480mbps)
從上面你的圖可知道當我們寫乙個usb 裝置驅動時,我們最主要的目的是解釋usb傳輸資料的含義(即要根據資料的內容去做事情)。在接受資料之前需要讓我們的usb裝置驅動程式和usb裝置建立乙個連線,它是怎麼連線的呢?通過向上註冊乙個usb_driver結構體,當裝置插入時,通過得到的裝置描述符與這個結構體進行比較匹配,當匹配時就建立聯絡,詳細的匹配過程很複雜,這裡就不深入了。當裝置和驅動建立連線時,將呼叫註冊的結構裡的probe函式。為了能完成驅動的一些事務,我們需要在這個函式內進行一些裝置相關操作。比如,設定資料傳輸的3要素(usb的源,資料長度,目的),使用3要素(urb),提交urb。
總結usb裝置的驅動的框架:
1、分配usb_driver結構體;
struct usb_driver ;
2、設定usb_driver結構體;
3、註冊usb_driver結構體;int usb_register(struct usb_driver *driver)
4、在插入時呼叫probe函式;在probe函式裡進行裝置相關的操作。比如:
a、設定資料傳輸3要素(usb的源,資料長度,目的)。
b、使用三要素:分配乙個urburb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
填充urb:
/*填充usb中斷型別urb*/
static
inline
void usb_fill_int_urb (struct urb *urb,
struct usb_device *dev,
unsigned
int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,//接收到資料時呼叫的函式
void *context,
int interval)
完成這些步驟,我們就能寫出簡單的usb裝置驅動程式了。
usb滑鼠裝置驅動,將滑鼠當做按鍵,左鍵輸入l,右鍵輸入s,中間輸入回車。
#include
#include
#include
#include
#include
#include
static
struct input_dev *uk_dev;
static
char *usb_buf;
static dma_addr_t usb_buf_phys;
static
int len;
static
struct urb *uk_urb;
static
void my_usb_mouse_irq(struct urb *urb)
if((pre_val & (1
<<1)) != (usb_buf[0] & (1
<<1)))
if((pre_val & (1
<<2)) != (usb_buf[0] & (1
<<2)))
pre_val = usb_buf[0];
usb_submit_urb(uk_urb, gfp_kernel);
}static
int my_usb_mouse_probe (struct usb_inte***ce *intf,const
struct usb_device_id *id)
static
void my_usb_mouse_disconnect (struct usb_inte***ce *intf)
static
struct usb_device_id my_usb_mouse_id_table = ,
/* terminating entry */
};static
struct usb_driver my_usb_mouse_driver = ;
static
int __init my_usb_mouse_init(void)
static
void __exit my_usb_mouse_exit(void)
module_init(my_usb_mouse_init);
module_exit(my_usb_mouse_exit);
module_license("gpl");
linux裝置驅動 USB
系統核心中有usb匯流排驅動程式,作用是識別裝置,查詢並安裝裝置驅動程式,提供讀寫函式 當乙個usb裝置插入時,會有以下操作 1.某條線被拉低,硬體感知有裝置接入 2.usb匯流排驅動程式為裝置分配新位址,並告訴usb裝置 3.獲取描述符 4.根據獲取的裝置描述符中的資訊在usb匯流排中新增devi...
USB裝置驅動
1.linux usb架構 usb通訊都是由host端發起的。usb裝置驅動程式分配並初始化乙個urb發給usb core,usb core改一改,發給usb主機控制器驅動,usb主機控制器驅動把它解析成包,在匯流排上進行傳送。usb core是由核心實現的,其實也就是把host control d...
USB裝置驅動
把usb裝置接到pc 右下角彈出 發現android phone 跳出乙個對話方塊,提示你安裝驅動程式 問1.既然還沒有 驅動程式 為何能知道是 android phone 答1.windows裡已經有了usb的匯流排驅動程式,接入usb裝置後,是 匯流排驅動程式 知道你是 android phon...