现象:把USB设备接到PC
1. 右下角弹出"发现android phone"
2. 跳出一个对话框,提示你安装驱动程序

问1. 既然还没有"驱动程序",为何能知道是"android phone"
答1. windows里已经有了USB的总线驱动程序,接入USB设备后,是"总线驱动程序"知道你是"android phone"
     提示你安装的是"设备驱动程序"
     
     USB总线驱动程序负责:识别USB设备, 给USB设备找到对应的驱动程序

问2. USB设备种类非常多,为什么一接入电脑,就能识别出来?
答2. PC和USB设备都得遵守一些规范。
     比如:USB设备接入电脑后,PC机会发出"你是什么"?
           USB设备就必须回答"我是xxx", 并且回答的语言必须是中文
     USB总线驱动程序会发出某些命令想获取设备信息(描述符),
     USB设备必须返回"描述符"给PC
     
问3. PC机上接有非常多的USB设备,怎么分辨它们?
     USB接口只有4条线: 5V,GND,D-,D+
答3. 每一个USB设备接入PC时,USB总线驱动程序都会给它分配一个编号
     接在USB总线上的每一个USB设备都有自己的编号(地址)
     PC机想访问某个USB设备时,发出的命令都含有对应的编号(地址)

问4. USB设备刚接入PC时,还没有编号;那么PC怎么把"分配的编号"告诉它?
答4. 新接入的USB设备的默认编号是0,在未分配新编号前,PC使用0编号和它通信。

问5. 为什么一接入USB设备,PC机就能发现它?
答5. PC的USB口内部,D-和D+接有15K的下拉电阻,未接USB设备时为低电平
     USB设备的USB口内部,D-或D+接有1.5K的上拉电阻;它一接入PC,就会把PC USB口的D-或D+拉高,从硬件的角度通知PC有新设备接入

其他概念:
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读写函数

USB驱动程序框架:

app:   
-------------------------------------------
          USB设备驱动程序      // 知道数据含义
内核 --------------------------------------
          USB总线驱动程序      // 1. 识别, 2. 找到匹配的设备驱动, 3. 提供USB读写函数 (它不知道数据含义)
-------------------------------------------
           USB主机控制器
           UHCI OHCI EHCI
硬件        -----------
              USB设备

UHCI: intel,     低速(1.5Mbps)/全速(12Mbps)
OHCI: microsoft  低速/全速
EHCI:            高速(480Mbps)

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 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

在内核目录下搜:
grep "USB device using" * -nR
drivers/usb/core/hub.c:2186:              "%s %s speed %sUSB device using %s and address %d\n",

hub_irq
    kick_khubd
        hub_thread
            hub_events
                hub_port_connect_change
                
                    udev = usb_alloc_dev(hdev, hdev->bus, port1);
                                dev->dev.bus = &usb_bus_type;
                
                    choose_address(udev); // 给新设备分配编号(地址)
                    
                    
                    hub_port_init   // usb 1-1: new full speed USB device using s3c2410-ohci and address 3
                        
                        hub_set_address  // 把编号(地址)告诉USB设备
                        
                        usb_get_device_descriptor(udev, 8); // 获取设备描述符
                        retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
                        
                        usb_new_device(udev)   
                            err = usb_get_configuration(udev); // 把所有的描述符都读出来,并解析
                            usb_parse_configuration
                            
                            device_add  // 把device放入usb_bus_type的dev链表,
                                        // 从usb_bus_type的driver链表里取出usb_driver,
                                        // 把usb_interface和usb_driver的id_table比较
                                        // 如果能匹配,调用usb_driver的probe
                            
<LINUX内核源代码情景分析>

怎么写USB设备驱动程序?
1. 分配/设置usb_driver结构体
        .id_table
        .probe
        .disconnect
2. 注册

测试1th/2th:
1. make menuconfig去掉原来的USB鼠标驱动
-> Device Drivers
  -> HID Devices
  <> USB Human Interface Device (full HID) support

2. make uImage 并使用新的内核启动

3. insmod usbmouse_as_key.ko
4. 在开发板上接入、拔出USB鼠标

测试3th:
1. insmod usbmouse_as_key.ko
2. ls /dev/event*
3. 接上USB鼠标
4. ls /dev/event*
5. 操作鼠标观察数据

测试4th:
1. insmod usbmouse_as_key.ko
2. ls /dev/event*
3. 接上USB鼠标
4. ls /dev/event*
5. cat /dev/tty1    然后按鼠标键
6. hexdump /dev/event0

USB设备驱动程序学习笔记(一)的更多相关文章

  1. USB设备驱动程序学习笔记(二)

    一.usbmouse_as_key.c /* * drivers\hid\usbhid\usbmouse.c */ #include <linux/kernel.h>#include &l ...

  2. USB驱动程序之USB总线驱动程序学习笔记

    USB总线驱动程序的作用 1. 识别USB设备 1.1 分配地址 1.2 并告诉USB设备(set address) 1.3 发出命令获取描述符 描述符的信息可以在include\linux\usb\ ...

  3. USB设备类学习笔记

    usb audio class 版本目前有3个版本  分别是1.0,2.0,3.0:1.0针对各个厂家的设备具有不同的描述符,而2.0则将它们统一简化,3.0则是最新的,还没有与2.0作进一步比较:因 ...

  4. Linux设备驱动程序学习----目录

    目录 设备驱动程序简介 1.设备驱动程序简介 构造和运行模块 2.内核模块和应用程序的对比 3.模块编译和装载 4.模块的内核符号表  5.模块初始化和关闭  6.模块参数  7.用户空间编写驱动程序 ...

  5. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  6. 基于STM32的USB枚举过程学习笔记

    源:基于STM32的USB枚举过程学习笔记 基于STM32的USB枚举过程学习笔记(一) 基于STM32的USB枚举过程学习笔记(二) 基于STM32的USB枚举过程学习笔记(三) 基于STM32的U ...

  7. USB设备驱动程序(一)

    USB驱动编程原理: 当我们把USB设备插入USB口时会提示需要安装相对应的驱动,如USB鼠标.USB键盘等,这些电脑自己自身已经自带有相对于的驱动程序, 当电脑检查到该USB设备类型相同就去帮你安装 ...

  8. 12、USB设备驱动程序

    linux-3.4.2\driver\hid\usbhid\usbmouse.c 内核只带USB驱动程序 (hub和usb是两个不同的设备,hub在内核上电的过程中在usb_hub_init函数中调用 ...

  9. Linux设备驱动程序学习----1.设备驱动程序简介

    设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介   Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...

随机推荐

  1. eclipse 显示特殊符号

    windows --> Preferences --> General --> Editors --> Text Editors 右边 show white space let ...

  2. 微服务(Microservices)

    说在前面     好久没写博文了,心里痒痒(或许是换工作后,有点时间了吧). 近期好像谈论微服务的人比較多,也開始学习一下.可是都有E文.看起来半懂不懂的.     Martinfowler的< ...

  3. windows 批处理设置环境变量

      windows通过批处理设置环境变量 CreateTime--2017年8月4日11:28:11Author:Marydon 参考链接:https://wenku.baidu.com/view/a ...

  4. exception ORA-00918: 未明确定义列

      exception ORA-00918: 未明确定义列 CreateTime--2018年5月9日16:08:48 Author:Marydon 1.错误代码展示 SELECT G.* FROM ...

  5. Linux安装SQLite轻量级数据库

    SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在很多嵌入式产 ...

  6. HDUOJ-------1753大明A+B(大数之小数加法)

    大明A+B Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. access database in a helper function ?

    <?php if(! function_exists('get_user_info')){ function get_user_info($field) { $ci = & get_in ...

  8. Android学习系列(5)--App布局初探之简单模型

    人类科技的进步源自探索,探索来自于发现本原,当然App布局没这么先进,本文也只是一个归类总结.这篇文章是Android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. Androi ...

  9. Android开发之探秘蓝牙隐藏API

    这次讲得深入些,探讨下蓝牙方面的隐藏API.用过Android系统设置(Setting)的人都知道蓝牙搜索之后可以建立配对和解除配对,但是这两项功能的函数没有在SDK中给出,那么如何去使用这两项功能呢 ...

  10. 采用异步来实现重新连接服务器或者重新启动服务 C#中类的属性的获取 SignalR2简易数据看板演示 C#动态调用泛型类、泛型方法 asp .net core Get raw request. 从壹开始前后端分离[.NetCore 不定期更新] 38 ║自动初始化数据库

    采用异步来实现重新连接服务器或者重新启动服务 开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端! #region 检测断线并重连OPC服务 ...