=============  本系列参考  =============

《圈圈教你玩USB》、《Linux那些事儿之我是USB》

协议文档:https://www.usb.org/document-library/usb-20-specification  usb_20_20190524/usb_20.pdf

调试工具:Beagle USB 480 逻辑分析仪、sys/kernel/debug/usb/usbmon/

====================================

前言

  USB设备插入端口到底发生了什么? 总线上的波形发生了什么变化?  这一节我们从设备插入前、插入中、插入后三个阶段分析

一、设备插入前

  首先要知道设备插入的端口是hub的端口(port), 外设不直接与Host相连, 而是通过hub这个“代理商”, 所以一个Host必然有一个hub, 这个最基本的hub我们称之root hub,基本上Host和root hub是捆绑一起,

一个hub可以引出多个端口(port), 目前Linux定义hub最多有31个port, 如果你连接超过这个数量可以改下面的定义

linux-4.1./include/uapi/linux/usb/ch11.h
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
*
* Current Wireless USB host hardware (Intel i1480 for example) allows
* up to 22 devices to connect. Upcoming hardware might raise that
* limit. Because the arrays need to add a bit for hub status data, we
* use 31, so plus one evens out to four bytes.
*/
#define USB_MAXCHILDREN 31

 

 已我的电脑为例, 只有一个Host主控器和一个root hub, 所有外设的端口都是一个root hub出来的, 如果你的PC机有多个Host/root hub, 可以让设备分散到各个Host避免电流限制

  

  有个概念非常重要, 就是hub也是一个设备, 跟普通的U盘、鼠标、键盘一样, 在Linux中都用struct usb_device 表示, 只是实现的功能侧重点不一样(比如复位功能只有hub有, 用于复位普通外设)

  设想一下, 当USB设备插入电脑USB端口时, 电脑提示有设备插入, 接着提示安装成功或者失败,  Host怎么知道外设插入这一事件呢? 既然Host不跟外设直连那肯定跟hub有关, 另外, 如果插入端口信号可以传给Host,

可如果Host还连接着其他外设, 必然导致信号串扰, 因为信号可以在Host和所有外设传达, 比如我正在拷贝U盘数据, 此时插入键盘, 并不会干扰我拷贝, 所以可以推测插入键盘这事件(D+/D-状态改变)并没有传到总线上。

总总现象表明, 这个插入的事件只有被插的那个hub知道, 同时hub的port默认是disable的, 信号不会连接到Host总线上!

  hub既然知道这一事件, 它可以告知Host, 或者是Host来询问, 很显然是后者, 因为外设没有权利主动勾搭Host, 所有的通信过程都是Host主动发起的, 设备被动接收!(唯一例外就是设备远程唤醒Host),   所以我们可以反推,

hub不仅是个外设, 同时采用中断传输, 端点描述符里的bIterval间隔时间值告知Host希望多久访问一次, 协议文档11章有定义hub规范, 代码只要每次读取hub的状态寄存器值, 判断是否有外设插入就行了。

  下面是用usbmon工具调试USB Host跟hub通信的log:

 # cat sys/kernel/debug/usb/usbmon/1u
0s 0u 1s 1t 1u ce382380 C Ii::: : =
ce382380 S Ii::: -: <
ce399800 S Ci::: s a3 00 0000 0001 0004 <-----------------------@1
               | | | |__setup令牌包 后面就是请求数据(不会列出PID/CRC5域) 
               | | |__端点地址, 控制传输使用端点0
               | |__设备地址, root hub是第一个设备, 所以是地址1, 0地址表示刚插入设备
               |__主控器/总线
ce399800 C Ci::: =
ce399800 S Co::: s 0 <-------------------@2
ce399800 C Co:::
ce399800 S Ci::: s a3 <-------------------@3
ce399800 C Ci::: =
ce399e80 S Ci::: s a3 <-------------------@4
ce399e80 C Ci::: =
ce399800 S Ci::: s a3 <-------------------@5
ce399800 C Ci::: =
ce399e80 S Ci::: s a3 <-------------------@6
ce399e80 C Ci::: = ce399e80 S Ci::: s a3 <-------------------@7
ce399e80 C Ci::: =
ce399e80 S Co::: s 复位 ce399e80 C Co::: ce399e80 S Ci::: s a3 <------------------@8
ce399e80 C Ci::: =
ce399800 S Co::: s
ce399800 C Co:::
ce399800 S Ci::: s < 获取设备描述符
ce399800 C Ci::: = 0c090010
ce399800 S Co::: s 再次复位 后面是跟外设U盘打交道的log, 放在下一节讲

  @1的a3(1010 0011):表示设备到主机, 是class且other, 说明不是标准的请求(请求有上面4中), 获取的是GET_STATUS DEVICE, 说明这是读取地址为1端点为0的root hub设备的状态, 也可以参考Linux代码:

port_event()
-> hub_port_status(hub, port1, &portstatus, &portchange)
-> get_port_status():
/* #define USB_STS_TIMEOUT 1000
* #define USB_STS_RETRIES 5
* #define   USB_REQ_GET_STATUS 0x00
* #define   USB_DIR_IN 0x80 /* to host */
* #define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
* #define USB_TYPE_CLASS (0x01 << 5)
* #define USB_RECIP_OTHER 0x03
*/
static int get_port_status(struct usb_device *hdev, int port1, struct usb_port_status *data)
{
int i, status = -ETIMEDOUT; for (i = ; i < USB_STS_RETRIES && (status == -ETIMEDOUT || status == -EPIPE); i++) {
status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, ),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, , port1,
data, sizeof(*data), USB_STS_TIMEOUT);
}
return status;
} struct usb_port_status {
__le16 wPortStatus;
__le16 wPortChange;
} __attribute__ ((packed)); 最后 portstatus = portchange = ; /*
* wPortStatus bit field
* See USB 2.0 spec Table 11-21
*/
#define USB_PORT_STAT_CONNECTION 0x0001
#define USB_PORT_STAT_ENABLE 0x0002
#define USB_PORT_STAT_SUSPEND 0x0004
#define USB_PORT_STAT_OVERCURRENT 0x0008
#define USB_PORT_STAT_RESET 0x0010
#define USB_PORT_STAT_L1 0x0020
/* bits 6 to 7 are reserved */
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
#define USB_PORT_STAT_HIGH_SPEED 0x0400
#define USB_PORT_STAT_TEST 0x0800
#define USB_PORT_STAT_INDICATOR 0x1000
/* bits 13 to 15 are reserved */ #define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
#define USB_PORT_STAT_C_SUSPEND 0x0004
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
#define USB_PORT_STAT_C_RESET 0x0010
#define USB_PORT_STAT_C_L1 0x0020

  从返回的四个字节01010100可以看出port状态已经连接了, 但是还是suspend状态, 我们接着看@2的(23 01 0010 0001 0000)  这是个清除hub寄存器操作,

@3~@7五次都是(a3 00 0000 0001 0004) =读取状态0101 0000刚好是代码定义try的次数 #define USB_STS_RETRIES 5 , 既然没有新的状态, 所以Host发送了第一次的复位操作reset

port_event()
-> hub_port_status(hub, port1, &portstatus, &portchange)
.....................
-> hub_port_warm_reset_required(hub, port1, portstatus)
-> hub_port_reset()
-> set_port_feature(hub->hdev, port1, (warm ? USB_PORT_FEAT_BH_PORT_RESET : USB_PORT_FEAT_RESET));
-> hub_port_wait_reset()
-> hub_port_status()
  -> hub_port_connect_change(hub, port1, portstatus, portchange);
    -> hub_port_connect()
      -> usb_alloc_dev() //创建设备
      -> hub_port_init() //获取设备描述符的等各种描述符(注意接口描述符/端点描述符不能单独获取必须跟随配置描述符一块获取,所以第一次先获取9字节的配置描述符, 解析后续还有多少再次获取)
      -> usb_new_device() //注册, 然后会跟usb_generic_driver 进行match 然后再创建真正的执行单元 interface! 后续博文会讲解

  总之, 设备的插入事件是又hub检测到的, Host通过中断控制传输定期获取各个hub的状态, 当检测到有设备connect, 则调用hub_port_connect_change()  创建设备、填充各种描述符、注册设备,

在注册之前hub会设置这个usb_device里的parent指针为本hub, port为插入的port号, 并且分配唯一地址给外设, 更多具体的我们在后面分析hub时再讲解。

  还有个遗漏的细节, 就是Host通过hub获得事件, 那为什么设备插入hub, hub就知道呢? 其实就是改变D+/D-的状态, 我们放到设备插入中解释。

二、设备插入中

  hub的port口D+/D-在默认状态下下拉15kΩ的电阻, 悬空状态电平都为0。 而USB设备在D+或D-上拉一个1.5kΩ的电阻到VBUS, 这也是为何USB接口四根线VBUS和GND比D+/D-长的原因,

如果是FS设备, 上拉电阻接到D+, 插入port分压后D+为高电平, hub认为是FS设备; 如果是LS, 上拉电阻接到D-, 插入port分压后D-为高电平, hub认为是LS设备, 那怎么区分HS设备呢?

目前的做法是HS也是将1.5k的上拉电阻接在D+处, 所以前期HS/FS的表现是一样的, hub不区分是FS还是HS, 都先当做FS设备, 在后面一点, Host会对设备复位, 也即D+/D- 都为0且持续10ms以上,

而这个期间, 如果是高速设备, 会在D-灌入17.78mA电流(设备D+上的1.5k电阻还未撤销), 在hub端会形成45欧姆的等效终端电阻, 导致D-变成电平17.78*45=800mv电平, 且持续1~7ms,

如果hub是支持高速的话, 在复位期间就会自动检测D-有没有这800mv电平, 如果没有则说明外设不是高速的, 如果有持续的800mv的话, 等外设停止驱动D-的17.78mA的100us内, hub也使用自己的电流源

交叉驱动D+/D-形成KJKJKJ...波形,同时将自己内部电路切换到高速模式(hub硬件无法同时支持高速和全速/低速, 靠一个开关切换到哪一路),  设备停止驱动D-后会检测是否有KJ信号, 如果有说明hub是支持

高速的然后自己也切换到高速模式, 切换的具体表现有:断掉1.5K的上拉电阻; 连接新的等效终端电阻;硬件切换到高速模式。 由于新的等效终端电阻是原来的一半22.5欧姆, 所以hub发出的KJKJKJ...波形的

电平变成从原来的800mv变成400mv了, 至此高速握手协商结束。总之在握手协商期间任何一方没有给出该有的响应(设备持续灌电流到D- 800mv、hub交叉灌D+/D-), 则使用默认的全速。

  当然我们这有个前提就是Host也是支持高速的, 否则Host在与hub握手时就会禁止hub的高速能力, 后面自然不会响应高速外设的800mv(即不会发送KJKJKJ...), 其波形如下:

    

    

三、设备插入后

  插入后做如下:

  a. 获取各种描述符(设备描述符、配置描述符、字符串描述符), 丰富struct usb_device结构体的骨骼

  b.  与usb_generic_driver match后设置合适的配置描述符, 并创建 具体的设备(操作对象) struct usb_interface

  c. struct usb_interface 与 struct usb_driver match后进行具体驱动后续的初始化和目的操作

  更详细的流程将在后续博文介绍.....

附完整log:

 # cat sys/kernel/debug/usb/usbmon/1u
0s 0u 1s 1t 1u ce382380 C Ii::: : =
ce382380 S Ii::: -: <
ce399800 S Ci::: s a3 <
ce399800 C Ci::: =
ce399800 S Co::: s
ce399800 C Co:::
ce399800 S Ci::: s a3 <
ce399800 C Ci::: =
ce399e80 S Ci::: s a3 <
ce399e80 C Ci::: =
ce399800 S Ci::: s a3 <
ce399800 C Ci::: =
ce399e80 S Ci::: s a3 <
ce399e80 C Ci::: = ce399e80 S Ci::: s a3 <
ce399e80 C Ci::: =
ce399e80 S Co::: s 复位 ce399e80 C Co::: ce399e80 S Ci::: s a3 <
ce399e80 C Ci::: =
ce399800 S Co::: s
ce399800 C Co:::
ce399800 S Ci::: s < 获取设备描述符
ce399800 C Ci::: = 0c090010
ce399800 S Co::: s 再次复位 ce399800 C Co:::
ce382380 C Ii::: : =
ce382380 S Ii::: -: <
ce399e80 S Ci::: s a3 <
ce399e80 C Ci::: =
ce399800 S Co::: s
ce399800 C Co:::
ce399800 S Co::: s 设置地址
ce399800 C Co:::
ce399e80 S Ci::: s <
ce399e80 C Ci::: = 0c090010
ce399e80 S Ci::: s 0f00 <
ce399e80 C Ci::: = 050f1600
ce399e80 S Ci::: s 0f00 <
ce399e80 C Ci::: = 050f1600 0a100300 0c000204
ce399e80 S Ci::: s <
ce399e80 C Ci::: =
ce399e80 S Ci::: s <
ce399e80 C Ci::: =
ce399800 S Ci::: s 00ff <
ce399800 C Ci::: =
ce399800 S Ci::: s 00ff <
ce399800 C Ci::: = 6c006100
ce399800 S Ci::: s 00ff <
ce399800 C Ci::: = 61006d00 6e006700
ce399800 S Ci::: s 00ff <
ce399800 C Ci::: =
ce399e00 S Co::: s
ce399e00 C Co:::
ce399400 S Ci::: s a3 <
ce399400 C Ci::: =
ce399400 S Co::: s
ce399400 C Co::: ce399600 S Ci::: s a1 fe <
ce399600 C Ci::: =
ce399600 S Bo::: - =
ce399600 C Bo::: >
ce399200 S Bi::: - <
ce399200 C Bi::: = 1f736d69 53616d73 756e6720 466c6173
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - =
ce399600 C Bo::: >
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = 80000a25
ce399600 C Bo::: >
ce39e080 S Bi::: - <
ce39e080 C Bi::: = 03bc3fff
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = c0000000 8000061a 003f00c0
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: - = 051e0000 103f0200 3fff0000
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = c0000000 8000061a 003f00c0
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: - = 051e0000 103f0200 3fff0000
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - =
ce399600 C Bo::: >
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = 0000061e
ce399600 C Bo::: >
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - =
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: = 0000000a
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - =
ce399600 C Bo::: >
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = 0a000000 80000a25
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: = 03bc3fff
ce399600 S Bi::: - <
ce399600 C Bi::: = 0a000000
ce399600 S Bo::: - = 0b000000 c0000000 8000061a 003f00c0
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: - = 051e0000 103f0200 3fff0000
ce399600 S Bi::: - <
ce399600 C Bi::: = 0b000000
ce399600 S Bo::: - = 0c000000 c0000000 8000061a 003f00c0
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: - = 051e0000 103f0200 3fff0000
ce399600 S Bi::: - <
ce399600 C Bi::: = 0c000000
ce399600 S Bo::: - = 0d000000 80000a28
ce399600 C Bo::: >
ce39e900 S Bi::: - <
ce39e900 C Bi::: = eb5e0000 3f00ff00
ce399600 S Bi::: - <
ce399600 C Bi::: = 0d000000
ce399600 S Bo::: - = 0e000000
ce399600 C Bo::: >
ce399600 S Bi::: - <
ce399600 C Bi::: = 0e000000
ce399600 S Bo::: - = 0f000000
ce399600 C Bo::: >
ce399600 S Bi::: - <
ce399600 C Bi::: = 0f000000
ce399600 S Bo::: - = 80000a25
ce399600 C Bo::: >
ce392c80 S Bi::: - <
ce392c80 C Bi::: = 03bc3fff
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = c0000000 8000061a 003f00c0
ce399600 C Bo::: >
ce392c80 S Bi::: - <
ce392c80 C Bi::: - = 051e0000 103f0200 3fff0000
ce399600 S Bi::: - <
ce399600 C Bi::: =
ce399600 S Bo::: - = c0000000 8000061a 003f00c0
ce399600 C Bo::: >
ce392c80 S Bi::: - <
ce392c80 C Bi::: - = 051e0000 103f0200 3fff0000
ce399600 S Bi::: - <
ce399600 C Bi::: = 拔掉U盘...... ce382380 C Ii::: : =
ce382380 S Ii::: -: <
ce392e00 S Ci::: s a3 <
ce392e00 C Ci::: =
ce392e00 S Co::: s
ce392e00 C Co:::
ce392e00 S Co::: s
ce392e00 C Co:::
ce392e00 S Ci::: s a3 <
ce392e00 C Ci::: =
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: = ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce392b00 S Co::: s
ce392b00 C Co:::
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <
ce392b00 C Ci::: =
ce382380 S Ii::: -: <
ce382380 C Ii::: -:
ce392b00 S Ci::: s a3 <

usbmon-U盘log

USB之设备插入波形变化2的更多相关文章

  1. shell判断USB接口是否有设备插入

    #/bin/sh usb_num=$(cat /proc/scsi/scsi | grep "Vendor" | wc -l)if [ $usb_num = 2 ];then    ...

  2. C# 访问USB(HID)设备

    原文:C# 访问USB(HID)设备 二话不说,直接给代码,如果您真想做这方面的东西,还是稍微研究下,没有现成的好类用,就需要自己了解其原理 //引用空间 using System; using Sy ...

  3. 控制器没有足够的带宽可利用为USB大容量存储设备的解决方法

    伴随网盘时代的没落,最近刚入手了一个移动硬盘.现在的移动硬盘都是USB3.0,传输速度比USB2.0要快很多.但是链接笔记本电脑后发现传输速度在20MB/s左右,跟USB2.0速度差不多,并不能达到传 ...

  4. 浅析USB之设备枚举

    当一个USB设备插入主机后,会有以下活动: 配上状态图

  5. usb hub 设备流程图

    在此处负责而来:http://blog.csdn.net/xuelin273/article/details/38646851  下面的转载于:http://blog.csdn.net/qianguo ...

  6. 树莓派-USB存储设备自动挂载

    简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常需要用mount命令手动挂载USB存储 ...

  7. 树莓派USB存储设备自动挂载并通过脚本实现自动拷贝,自动播放视频,脚本自动升级等功能

    需求:首先需要树莓派自动挂载USB设备,然后扫描USB指定目录下文件,将相关文件拷贝至树莓派指定目录,然后通过omxplayer循环播放新拷贝文件视频 1. 树莓派实现USB存储设备自动挂载 树莓派U ...

  8. 如何查找Mac上的USB存储设备使用痕迹

    最近刚好有个案子的证物主机是MBP, OS X版本为El Capitan,案况与营业秘密外泄有关,当中要找有关USB存储设备的使用痕迹. 要提醒大家的是,不同版本的OS X,各种迹证的存放文件名称及路 ...

  9. android usb Host模式下与usb Hid 设备的通信

    做android 与USB HID设备的通信有段时间了,总结一下遇到的问题和解决方法: 1,第一次遇到的问题:android 版本低不支持usb hid, 被要求做相关项目的时候,就从mUsbMana ...

随机推荐

  1. 僵尸进程bug排除方法

    多进程处理存在的问题 直接return 200 子进程 signal.signal(signal.SIGCHLD, signal.SIG_IGN) #不管子进程,不然R的多进程切图会产生僵尸进程

  2. Webpack 4 SplitChunksPlugin配置方案(转)

    通常情况下我们的 WebApp 是有我们的自身代码和第三方库组成的,我们自身的代码是会常常变动的,而第三方库除非有较大的版本升级,不然是不会变的,所以第三方库和我们的代码需要分开打包,我们可以给第三方 ...

  3. 升级go mod采坑录

    为了使用go mod把golang升级到了最新的1.12版本,go mod是1.11版本引入的,go mod的引入极大的方便了golang项目的依赖管理,同时把golang项目从GOPATH中解放了出 ...

  4. Gerrit - 一些基本用法

    1 - 主配置文件 主配置文件位于$GERRIT_SITE/etc/gerrit.config目录 [gerrit@mt101 ~]$ cat gerrit_testsite/etc/gerrit.c ...

  5. leetcode刷题系列(一) 26题 删除排序数组中的重复项

    题干 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示 ...

  6. django:删除表后怎么重新数据迁移生成表

    1.将对应app下的migrations文件夹下面的除了__init__.py文件外全部删除 2.delete from django_migrations where app='app_name' ...

  7. CSS选择符、伪类、层叠

    主题,架子(时间架子,空间架子,三角架),素材. CSS 三种方式 行内样式 嵌入样式 链接样式 上下文选择符 祖父 孙 p em {color:red;} 父 子 p > em {color: ...

  8. 【笔试题】Overloading in Java

    笔试题 Overloading in Java Question 1 以下程序的输出结果为( ). public class Test { public int getData() { return ...

  9. 【笔试题】Java Data Types

    Java 知识测试 Java Data Types Question 1 Predict the output of the following program. class Test { publi ...

  10. Django-09-cookie和session

    1. 简介 <1> cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie的工作原 ...