微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > USB驱动程序框架搭建

USB驱动程序框架搭建

时间:12-15 来源:互联网 点击:
1.首先我们先从理论上浅谈一下USB驱动的框架

app:

-------------------------------------------

USB设备驱动程序 // 知道数据含义

内核 --------------------------------------

USB总线驱动程序 // 1. 识别, 2. 找到匹配的设备驱动, 3. 提供USB读写函数 (它不知道数据含义)

-------------------------------------------

USB主机控制器

UHCI OHCI EHCI

硬件 -----------

USB设备

UHCI: intel, 低速(1.5Mbps)/全速(12Mbps)

OHCI: microsoft 低速/全速

EHCI: 高速(480Mbps)

也就是说最底层是usb设备,往上是USB总线控制器、USB总线驱动程序、USB驱动程序,最后是应用程序。其中USB总线控制器包括三种:UHCI OHCI EHCI

2. USB总线驱动程序的作用

1. 识别USB设备

1.1 分配地址

1.2 并告诉USB设备(set address)

1.3 发出命令获取描述符

描述符的信息可以在includelinuxusbCh9.h看到

2. 查找并安装对应的设备驱动程序

3. 提供USB读写函数

3、我们开始正式构建linux usb框架了,小心了!!!

首先我们需要从开发板获得一些信息:

把USB设备接到开发板上,看输出信息:

usb 1-1: new full speed USB device using s3c2410-ohci and address 2

usb 1-1: configuration #1 chosen from 1 choice

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

接着我们就可以根据这些信息进行分析了:

首先我们在内核的dirvers目录下搜索:“USB device using

grep "USB device using" * -nR

结果搜到了下面这条信息:usb/core/hub.c:2186: "%s %s speed %sUSB device using %s and address %d",

那么我们就从usb/core/hub.c这个文件开始分析:

"%s %s speed %sUSB device using %s and address %d"这句话在hub_port_init 函数中被调用

hub_port_init 在函数hub_port_connect_change中被调用

hub_port_connect_change在函数hub_events中被调用

hub_events在函数hub_thread中被调用

hub_thread函数里有这么一句:

wait_event_interruptible(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());

说明进程会在khubd_wait这个等待队列里休眠,那么谁把它唤醒呢?我们搜索一下

在kick_khubd函数里有这么一句:wake_up(&khubd_wait);把进程唤醒了

kick_khubd被函数hub_irq调用,根据注释信息我们知道当连接发生变化或则出现措施就会发生中断,从而进入这个函数。

那么我们大致可以总结出了框架:

hub_irq //发生接口状态变化或出现错误时调用

kick_khubd

wake_up//唤醒进程

hub_thread//进程在这个函数里休眠了,被wake up唤醒后会继续执行

hub_port_connect_change //我们重点来分析它

udev = usb_alloc_dev(hdev, hdev->bus, port1);

dev->dev.bus = &usb_bus_type;//指定设备总线是usb类型的

choose_address(udev);//在0到128之间找到一个设备地址,至于为什么是128我们之前已经讲过了

hub_port_init

hub_set_address//将上面找到的地址告诉usb设备

usb_get_device_descriptor(udev, 8);//获取设备描述符

usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);//再次获取设备描述符,我们在 //usb协议分析里面有谈到过的

usb_new_device//把所有的描述符都读出来并解析

usb_get_configuration(udev);//获取配置信息

usb_cache_string(udev, udev->descriptor.iProduct);//读取产品信息

usb_cache_string(udev,udev->descriptor.iManufacturer);//读取制造商信息

usb_cache_string(udev, udev->descriptor.iSerialNumber);//读取序列号信息

__usb_get_extra_descriptor//获得一些额外的信息

device_add(&udev->dev);// 把device放入usb_bus_type的dev链表,

// 从usb_bus_type的driver链表里取出usb_driver,

// 把usb_interface和usb_driver的id_table比较

// 如果能匹配,调用usb_driver的probe

我们来总结一下上面的框架:首先接上usb设备时会发 生中断,然后唤醒进程。接着先设置usb设备的地址,然后获取设备描述符和配置描述符等各种描述符,这是为了寻找驱

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top