USB學習之二 USB匯流排驅動程式

2021-09-11 18:19:36 字數 4648 閱讀 7944

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.因為 太多且關係複雜這裡僅僅列出呼叫的函式 沒有寫引數 ...