usb匯流排驅動程式的作用
1. 識別usb裝置
1.1 分配位址
1.2 並告訴usb裝置(set address)
1.3 發出命令獲取描述符
描述符的資訊可以在include\linux\usb\ch9.h看到
2. 查詢並安裝對應的裝置驅動程式
3. 提供usb讀寫函式
將乙個usb裝置接到開發板上,看輸出資訊:
usb 1-1: new full speed usb device using s3c2410-ohci and address 2
usb 1-1: configuration #1 chosen from 1 choi ce
scsi0 : scsi emulation for usb mass storage devices
scsi 0:0:0:0: direct-access htc android phone 0100 pq: 0 ansi: 2
sd 0:0:0:0: [sda] attached scsi removable disk
拔掉usb 1-1: usb disconnect, address 2
再接上:
usb 1-1: new full speed usb device using s3c2410-ohci and address 3
usb 1-1: configuration #1 chosen from 1 choice
scsi1 : scsi emulation for usb mass storage devices
scsi 1:0:0:0: direct-access htc android phone 0100 pq: 0 ansi: 2
sd 1:0:0:0: [sda] attached scsi removable disk
全域性搜尋 grep "usb device using" * -nr 在2.6的核心中可以搜到相關資訊。
我用的是3.0的核心,usb裝置插入後,會有如下資訊列印出來
[ 465.520759] usb 1-2.3: new high speed usb device number 22 using s5p-ehci
因此可以搜尋:grep "usb device number" -nr .
找到在linux-3.0.86/drivers/usb/core/hub.c 中hub_port_init函式中,因此我們可以通過hub_port_init函式找出usb匯流排驅動程式的呼叫關係。先上一張圖。
接著從**的角度做一些分析:
drivers/usb/core/usb.c
struct bus_type usb_bus_type = ;
static int __init usb_init(void)
static struct usb_driver hub_driver = ;
int usb_hub_init(void)
khubd_task = kthread_run(hub_thread, null, "khubd");//初始化乙個hub 執行緒,這個執行緒在usb裝置插入後會跑,後面會分析到。
}//接著分析usb_register函式
usb_register(&hub_driver)
usb_register_driver(driver, this_module, kbuild_modname)
driver_register(&new_driver->drvwrap.driver)
bus_add_driver(drv)
driver_attach(drv)
bus_for_each_dev(drv->bus, null, drv, __driver_attach)
__driver_attach
driver_match_device(drv, dev)
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
//因此最後是呼叫的是上文中提到的usb_bus_type中提供的
usb_device_match(struct device *dev, struct device_driver *drv)函式。該函式是通過比較usb_driver中的id_table來確定的是否匹配並呼叫probe函式。
這些是跟核心的匯流排裝置框架有關。
裝置和驅動匹配到之後就會呼叫probe函式,即hub_probe
static int hub_probe(struct usb_inte***ce *intf, const struct usb_device_id *id)
hub_configure(hub, endpoint)
hub->urb = usb_alloc_urb(0, gfp_kernel); //分配hub->urb
usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,
hub, endpoint->binterval);//註冊hub中斷 hub_irq,當usb裝置被插入時,hub_irq會被呼叫
當由usb裝置插入hub,hub埠的d+或者d-會由原來的低電平被拉高到3v高電平,觸發hub中斷,hub_irq
static void hub_irq(struct urb *urb)
static int hub_thread(void *__unused)
while (!kthread_should_stop() || !list_empty(&hub_event_list));
}//接著呼叫到hub_events
hub_events
hub_port_connect_change(hub, i,
portstatus, portchange);
udev = usb_alloc_dev(hdev, hdev->bus, port1);//分配乙個usb dev裝置
choose_devnum(udev);//設定這個dev的編號
hub_port_init(hub, udev, port1, i);
在hub_port_init中做了很多事情
hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
int retry_counter)
if (udev->speed != usb_speed_super)
dev_info(&udev->dev,
"%s %s speed %susb device number %d using %s\n", //識別到usb裝置後就會列印這句資訊
(udev->config) ? "reset" : "new", speed, type,
devnum, udev->bus->controller->driver->name);
for (i = 0; i < get_descriptor_tries; (++i, msleep(100)))
/** if device is wusb, we already assigned an
* unauthorized address in the connect ack sequence;
* authorization will assign the final address.
*/if (udev->wusb == 0)
if (udev->speed == usb_speed_super)
}retval = usb_get_device_descriptor(udev, 8);//獲取裝置描述符,第8個位元組是裝置描述符的最大包長
i = udev->descriptor.bmaxpacketsize0;
if (le16_to_cpu(udev->ep0.desc.wmaxpacketsize) != i)
retval = usb_get_device_descriptor(udev, usb_dt_device_size);//在上文中獲取到了裝置描述符的最大包長,因此這裡一次把裝置描述符讀取
if (retval < (signed)sizeof(udev->descriptor))
}
hub_port_init初始化完成以後呼叫usb_new_device(udev),將usb裝置新增到裝置鍊錶中去。
int usb_new_device(struct usb_device *udev)
device_add(&udev->dev); // 把device放入usb_bus_type的dev鍊錶,
// 從usb_bus_type的driver煉表裡取出usb_driver,
// 把usb_inte***ce和usb_driver的id_table比較
// 如果能匹配,呼叫usb_driver的probe
至此usb匯流排驅動程式框架已經分析完了。 USB學習之二 USB PHY
usb phy負責最底層的訊號轉換,作用類似於網口的phy。有兩種介面,一種是ulpi,一種是utmi。前者pin少,後者pin多,所以如果用ulpi,phy一般外部另接 用utmi,pin多,一般內建。phy內建或者外接要看晶元資料。powerpc的p2010,晶元資料裡面定義是ulpi,需要外接...
Linux下的USB匯流排驅動 01 USB理論
1.usb概念概述 usb1.0版本速度1.5mbps 低速usb usb1.1版本速度12mbps 全速usb usb2.0版本速度480mbps 高速usb usb驅動由usb主機控制器驅動和usb裝置驅動組成。usb主機控制器是用來控制usb裝置和cpu之間通訊的,usb主機控制器驅動主要用來...
大話USB驅動之匯流排驅動程式
匯流排驅動是不用改的。核心都幫我們做好了。為了了解整個usb驅動的體系,我們來分析一下匯流排驅動程式。一.匯流排框圖 匯流排的圖畫的已經很清楚了,這篇部落格我們分析的是左邊的程式,在下篇我們想通過usb鍵盤這一實際樣例來解說。二.程式實現 1.因為 太多且關係複雜這裡僅僅列出呼叫的函式 沒有寫引數 ...