1.USB协议简介

article/2025/9/21 7:36:52

         最近学习usb相关的知识,一直感觉入不了门,看《linux那些事儿之我是usb》,对usb协议也不是很熟悉,没能坚持看下去,直到看了《圈圈教你玩usb》一书,把自己的兴趣立马提了起来,大牛圈圈用51单片机实现了usb鼠标键盘等设备,让人非常佩服,51单片机自己还是很熟悉,大学玩了四年单片机,单片机来实现立马感觉亲切了许多,决定先从单片机入手学,后面再看linux那些事儿之我是usb,深入学习linux内核下usb,以下先介绍usb协议,内容整理来自usb spec、网络和圈圈书中,文中也大量引用STM32官方的USB2.0协议文档,欢迎批评指正。另外学习《圈圈教你玩usb》动手调试实现了单片机usb鼠标功能,源码在mcu_project/USB at master · lisongze2016/mcu_project · GitHub,源码中结合使用了linux kernel ch9.h中对描述符的结构体定义,对usb协议有了深入的理解。

        对裸机的usb协议有一定熟悉后,建议可以学习tinyusb开源协议栈(GitHub - hathach/tinyusb: An open source cross-platform USB stack for embedded system),支持rtos,样例比较丰富,对usb相关开发有一定帮助。
        USB(Universal Serial Bus)全称通用串口总线,USB为解决即插即用需求而诞生,支持热插拔。USB协议版本有USB1.0、USB1.1、USB2.0、USB3.1等,USB2.0目前比较常用,以下以2.0为主介绍。由于USB是主从模式的结构,设备与设备之间、主机与主机之间不能互连,为解决这个问题,扩大USB的应用范围,出现了USB OTG,全拼 ON The Go。USB OTG 同一个设备,在不同的场合下可行在主机和从机之间切换。

1.1 USB特点:

USB1.0和USB1.1支持1.5Mb/s的低速模式和12Mb/bs的全速模式。在USB2.0以上支持480Mb/s的高速模式。应用如下:

1.2 USB设备供电方式:
USB设备有两种供电方式 
自供电设备:设备从外部电源获取工作电压 
总线供电设备:设备从VBUS(5v) 取电 
  对总线供电设备,区分低功耗和高功耗USB设备 
低功耗总线供电设备:最大功耗不超过100mA 
高功耗总线供电设备: 枚举时最大功耗不超过100mA,枚举完成配置结束后功耗不超过500mA 
设备在枚举过程中,通过设备的配置描述符向主机报告它的供电配置(自供电/总线供电)以及它的功耗要求
如下 USB 配置描述符(以Joystick为例),后面具体介绍:

1.3 USB总线信号:
USB使用的是差分传输模式,两个数据线D+和D- 
        差分信号1:D+ > VOH(min) (2.8V) 且D- < VOL(max)(0.3V) 
        差分信号0:D- > VOH and D+ < VOL

J状态(高电平):D+ 高,D- 低
K状态(低电平):D+低,D- 高
SEO状态:D+ 低,D- 高
Reset信号:D+ and D- < VOL for >= 10ms 
主机在要和设备通信之前会发送Reset信号来把设备设置到默认的未配置状态。即主机拉低两根信号线(SE0状态)
并保持10ms 
Idle状态:J状态数据发、送前后总线的状态 
Suspend状态:3ms以上的J状态 
SYNC: 3个KJ状态切换,后跟随2位时间的K状态(看到的波形变化是总线上发送0000 0001经过NRZI编码后的波形)

Resume信号:20ms的K状态+低速EOP 
主机在挂起设备后可通过翻转数据线上的极性并保持20ms来唤醒设备,并以低速EOP信号结尾 
带远程唤醒功能的设备还可自己发起该唤醒信号;前提是设备已进入idle状态至少5ms,然后发出唤醒K信号,维持1ms到15ms并由主机在1ms内接管来继续驱动唤醒信号 
SOP:从IDLE状态切换到K状态 
EOP:持续2位时间的SE0信号,后跟随1位时间的J状态 
Keep alive即低速EOP信号

1.4 USB插入检测和速度检测:

主机通过设备在D+或D-上的1.5K上拉来检测设备的连接和断开事件,并由此判别设备的速度 
主机先把高速设备检测为全速设备,然后再通过“Chirp序列”的总线握手机制来识别高速和全速设备
USB连接和断开连接:
设备连上主机时(连接)
当主机检测到某一个数据线电平拉高并保持了一段时间,就认为有设备连上来了
主机必需在驱动SE0状态以复位设备之前,立刻采样总线状态来判断设备的速度 

没有设备连上主机时(断开)
D+和D-数据线上的下拉电阻起作用,使得二者都在低电平;主机端看来就是个SE0状态;同样地,当数据线上的SE0状态持续一段时间了,就被主机认为是断开状态

1.5 数据编解码和位填充 
USB采用NRZI(非归零编码)对发送的数据包进行编码 
输入数据0, 编码成“电平翻转” 
输入数据1, 编码成“电平不变” 
编码出来的序列,高电平:J状态;低电平:K状态 

位填充是为了保证发送的数据序列中有足够多的电平变化 
填充的对象是(输入数据),即先填充再编码 
数据流中每6个连续的“1”,就要插入1个“0”,从而保证编码
数据出现电平变化 
接收方赋值解码NRZI码流,然后识别出填充位,并丢弃它们

2. USB传输
一个传输有多个事务组成,一个事务由2/3个包组成。
传输又分为四种类型:批量传输、等时(同步)传输、中断传输、控制传输。
注意:USB传输数据先发数据低位再发高位数据

2.1 包
包的组成:

包的内容:

Packet分四大类: 命令 (Token) 、Packet 帧首 (Start of Frame) 、Packet 数据 (Data) 、Packet 握手 (Handshake) Packet

不同类型包,以上的组成部件有所不同

PID:

这里只用(PID0~4),PID4~7是PID0~4的取反,用来校验PID
PID1~0:01 令牌包、11 数据包、10 握手包、00 特殊包

地址:

帧号:

数据:

CRC:

四种Packet类型之令牌包(Token Packet):
令牌包用来启动一次USB传输。
输出(OUT)令牌包:用来通知设备将要输出一个数据包
输入(IN)令牌包:用来通知设备返回一个数据包
建立(SETUP)令牌包:只用在控制传输中,和输出令牌包作用一样,也是通知设备将要输出一个数据包,两者区别在于:
SETUP令牌包后只使用DATA0数据包,且只能发送到设备的控制端点,并且设备必须要接收,而OUT令牌包没有这些限制

例子:

四种Packet类型之SOF Packet
帧起始包:在每帧(或微帧)开始时发送,以广播的形式发送,所有USB全速设备和高速设备都可以接收到SOF包。

例子:

0xA5:1010 0101:对应上面PID表可知是帧起始包
四种Packet类型之Data Packet

例子:

四种Packet类型之Handshake Packet 

例子:

2.2 事务
Transaction可以分成三类 
Setup transaction:主机用来向设备发送控制命令 
Data IN transaction:主机用来从设备读取数据 
Data OUT transaction:主机用来向设备发送数据 
Transaction的packet组成 
Token packet:总是由主机发出 
Data packet:包含此次transaction的数据负载 
可选的Handshake packet 
例子:

2.3 传输
USB协议定义了四种传输类型: 
批量(大容量数据)传输(Bulk Transfers): 非周期性,突发  
大容量数据的通信,数据可以占用任意带宽,并容忍延迟 。如USB打印机、扫描仪、大容量储存设备等 
中断传输(Interrupt Transfers): 周期性,低频率
允许有限延迟的通信 如人机接口设备(HID)中的鼠标、键盘、轨迹球等
等时(同步)传输(Isochronous Transfers): 周期性 
持续性的传输,用于传输与时效相关的信息,并且在数据中保存时间戳的信息 ,如音频视频设备
控制传输(Control Transfers): 非周期性,突发
用于命令和状态的传输
2.3.1 批量传输
批量输出事务,(1)主机先发出一个OUT令牌包(包含设备地址,端点号),(2)然后再发送一个DATA包,这时地址和端点匹配的设备就会收下这个数据包,主机切换到接收模式,等待设备返回握手包,(3)设备解码令牌包,数据包都准确无误,并且有足够的缓冲区来保存数据后就会使用ACK/NYET握手包来应答主机(只有高速模式才有NYET握手包,他表示本次数据成功接收,但是没有能力接收下一次传输),如果没有足够的缓冲区来保存数据,就返回NAC,告诉主机目前没有缓冲区可用,主机会在稍后时间重新该批量传输事务。如果设备检查到数据正确,但端点处于挂起状态,返回STALL。如果检测到有错误(如校验错误,位填充错误),则不做任何响应,让主机等待超时。
批量输入事务,(1)主机首先发送一个IN令牌包(包含设备地址,端点号),(2)主机切换到接收数据状态等待设备返回数据。如果设备检测到错误,不做任何响应,主机等待超时。如果此时有地址和端点匹配的设备,并且没有检测到错误,则该设备作出反应:设备有数据需要返回,就将一个数据包放在总线上;如果没有数据需要返回,设备返回NAK响应主机;如果该端点处于挂起状态,设备返回STALL。如果主机收到设备发送的数据包并解码正确后,使用ACK握手包应答设备。如果主机检测到错误,则不做任何响应,设备会检测到超时。注意:USB协议规定,不允许主机使用NAK来拒绝接收数据包。主机收到NAK,知道设备暂时没有数据返回,主机会在稍后时间重新该批量输入事务。

PING令牌包,它不发送数据,直到等待设备的握手包。

2.3.2 中断传输
中断传输是一种保证查询频率的传输。中断端点在端点描述符中要报告它的查询间隔,主机会保证在小于
这个时间间隔的范围内安排一次传输。

2.3.3 等时传输
等时(同步)传输用在数据量大、对实时性要求高的场合,如音频设备,视频设备等,这些设备对数据的延迟很敏感。对于音频或视频设备数据的100%正确性要求不高,少量的数据错误是可以容忍的,主要是保证数据不能停顿,所以等时传输是不保证数据100%正确的。当数据错误时,不再重传操作。因此等时传输没有应答包,数据是否正确,由数据的CRC校验来确认。

2.3.4 控制传输
控制传输可分为三个过程:(1)建立过程 (2)数据过程(可选) (3)状态过程
 特性:  
每个USB设备都必须有控制端点,支持控制传输来进行命令和状态的传输。USB主机驱动将通过控制传输与USB设备的控制端点通信,完成USB设备的枚举和配置 
方向:  
控制传输是双向的传输,必须有IN和OUT两个方向上的特定端点号的控制端点来完成两个方向上的控制传输 

数据的拆分和数据传输完毕的判定 
以高速设备的最大数据包长度64字节为例 
要传输250字节,拆分成4个packet 

要传输正好256字节,通过最后一个0字节包告诉设备传输完成

各种传输特性比较

3. USB标准请求
3.1 USB标准请求的数据结构

3.2 USB 设备枚举及描述符介绍 
当一个USB设备插入主机后,会有以下活动: 

include/uapi/linux/usb/ch9.h
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {__u8  bLength;__u8  bDescriptorType;__le16 bcdUSB;__u8  bDeviceClass;__u8  bDeviceSubClass;__u8  bDeviceProtocol;__u8  bMaxPacketSize0;__le16 idVendor;__le16 idProduct;__le16 bcdDevice;__u8  iManufacturer;__u8  iProduct;__u8  iSerialNumber;__u8  bNumConfigurations;
} __attribute__ ((packed));#define USB_DT_DEVICE_SIZE        18

struct usb_config_descriptor {__u8  bLength;__u8  bDescriptorType;__le16 wTotalLength;__u8  bNumInterfaces;__u8  bConfigurationValue;__u8  iConfiguration;__u8  bmAttributes;__u8  bMaxPower;
} __attribute__ ((packed));#define USB_DT_CONFIG_SIZE        9

/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {__u8  bLength;__u8  bDescriptorType;__u8  bInterfaceNumber;__u8  bAlternateSetting;__u8  bNumEndpoints;__u8  bInterfaceClass;__u8  bInterfaceSubClass;__u8  bInterfaceProtocol;__u8  iInterface;
} __attribute__ ((packed));#define USB_DT_INTERFACE_SIZE        9


/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {__u8  bLength;__u8  bDescriptorType;__u8  bEndpointAddress;__u8  bmAttributes;__le16 wMaxPacketSize;__u8  bInterval;/* NOTE:  these two are _only_ in audio endpoints. *//* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */__u8  bRefresh;__u8  bSynchAddress;
} __attribute__ ((packed));#define USB_DT_ENDPOINT_SIZE        7
#define USB_DT_ENDPOINT_AUDIO_SIZE    9    /* Audio extension */

/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {__u8  bLength;__u8  bDescriptorType;__le16 wData[1];        /* UTF-16LE encoded */
} __attribute__ ((packed));/* note that "string" zero is special, it holds language codes that* the device supports, not Unicode characters.*/


http://chatgpt.dhexx.cn/article/nw1aNQHI.shtml

相关文章

USB协议基础篇

初次接触USB的同学&#xff0c;可能会被里面各种名词给搞晕&#xff0c;下面就来梳理一下这些知识&#xff0c;希望能帮助大家理解USB。 目录 一&#xff0c;从最常见的名词说起 1.1 什么是USB 1.2 USB协议版本 1.3 USB接口分类 1.4 PIPE 1.5 endpoint 1.6 管道通信方式…

USB协议简介

1.USB协议简介 https://blog.csdn.net/songze_lee/article/details/77658094 2017年08月28日 23:20:16 songze_lee 阅读数&#xff1a;22978 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/songze_lee/article/details/7…

USB协议详解

本博客整理自网络&#xff0c;仅供学习参考&#xff0c;如有侵权&#xff0c;联系删除。邮箱&#xff1a;rom100163.com 一个transfer(传输)由一个或多个transaction(事务)构成&#xff0c;一个transaction(事务)由一个或多个packet(包)构成&#xff0c;一个packet(包)由一个或…

简单说说USB协议(一)

目录 USB是什么 USB协议的传输结构 USB的电气特性 拓扑结构 编码方式 描述符 USB是什么 USB&#xff0c;通用串行总线&#xff0c;是一种计算机与外围设备进行数据交互的通信协议。 任何东西的出现都是有理可循的&#xff0c;在以前计算机刚兴起的时候&#xff0c;要连接…

USB协议介绍

目录 前言 1、概述 1.1 USB协议 1.2 USB充电协议 1.3 USB接口 1.3.1 type-a 1.3.2 Type-C 1.3.3 USB2.0/3.0/3.1/3.2速率 1.3.4 ULPI/UTMI 前言 开始整理USB相关基础概念&#xff0c;仅用于基础介绍、USB概念入门。更深入的内容请参考USB协议手册。部分图文来自参考文…

usb 传输协议

USB&#xff0c;是英文Universal Serial Bus&#xff08;通用串行总线&#xff09;、支持设备的即插即用和热插拔功能。在1994年底由英特尔、IBM、Microsoft等公司联合提出的&#xff0c;在此之前PC的接口杂乱&#xff0c;扩展能力差&#xff0c;热拔插不支持等。USB正是为了解…

USB协议(1)USB基础知识

USB&#xff08;Universal Serial Bus&#xff09;是通用串行总线的缩写&#xff0c;它是连接计算机系统与外部设备的一种串口总线标准&#xff0c;也是一种输入输出接口的技术规范&#xff0c;被广泛地应用于个人电脑和移动设备等信息通讯产品&#xff0c;并扩展至摄影器材、数…

linux免费的内网穿透

参考&#xff1a;https://www.cpolar.com/blog/how-to-install-cpolar-under-android-termux-hyper-terminal 下载包:https://www.cpolar.com/download 由于我的linux版本是装在安卓手机上的Alpine linux&#xff0c;所以下载的是如下图版本 下载后使用xftp工具上传到服务器&…

钉钉内网穿透 免费内网穿透工具 让你的电脑成为web服务器

什么是内网穿透&#xff1f; 就是让你个人电脑内建立的网站&#xff0c;在外网可以访问&#xff0c;例如你的手机&#xff0c;其他电脑等。 例如你在电脑部署了一个web服务器&#xff0c;你在浏览器访问127.0.0.1可以打开这个网站&#xff0c;但是你用手机访问127.0.0.1却打不…

免费的内网穿透(钉钉)

1.简介 阿里钉钉提供的免费内网穿透&#xff0c;是基于ngrok 的&#xff0c;可以实现 Http 穿透&#xff0c;可以将我们本地服务暴露给外部访问&#xff0c;可以用作我们调试一些回调接口&#xff0c;或者共享一些文件。 优点&#xff1a;网速快&#xff0c;估计是台带宽为100…

免费 内网穿透工具 实测好用

花生壳&#xff1a;已卸载 免费的版本根本不支持http协议&#xff0c;只支持TCP。 星空内网穿透&#xff1a;已卸载 需要注册账号 需要加入QQ群 需要实名认证&#xff0c;填写身份证号 钉钉内网穿透&#xff1a; 没试验&#xff0c;只记录在此 Utools中的内网穿透&#x…

推荐一款真正永久免费的内网穿透

神卓互联内网穿透&#xff0c;是一款真正的永久免费的内网穿透&#xff0c;每月不限流量、访问地址固定不变。 目录 1. 安装神卓互联内网穿透工具 神卓互联内网穿透客户端 控制台-界面清洁-一目了然 2.添加本地web项目-创建映射规则 3.神卓互联-增加通道检测功能&#xff0…

(不打广告)推荐这款永久免费内网穿透软件-神卓互联

内网穿透是一种将内部网络中的应用程序公开到公共网络上的技术。在许多情况下&#xff0c;由于网络安全限制或配置问题&#xff0c;内部网络中的应用程序可能无法通过公共网络访问。这时&#xff0c;内网穿透技术就可以解决这个问题&#xff0c;使得我们可以在没有公共 IP 地址…

内网穿透工具(全免费)

文章目录 前言一、NATAPP是什么&#xff1f;二、使用步骤1.访问官网注册2.客户端下载3 登录,配置参数1 登录,购买免费隧道2 配置参数3 根据authtoken 运行 natapp.exe 4 试试效果 总结 前言 平时开发微信公众号,小程序, 或者给他人演示项目等,难免会遇到需要开通外网的情况,作…

无需设置路由器,无需公网ip 实现永久免费内网穿透

用网云穿在 N1 盒子上实现 Openwrt 的内网穿透 软路由器情况 N1(已经刷入 Armbian) 中使用 docker 创建 Openwrt 容器作为旁路由。 我的内网 ip 信息 内网 IP 因人而异,以下是我自己的设置 Armbian:192.168.123.2 Openwrt:192.168.123.10 思路 N1 的 Armbian 中部…

如何免费使用内网穿透

背景&#xff1a; 疫情期间公司不能上班&#xff0c;工作又不能落下&#xff0c;所以只能选择在家办公&#xff5e;&#xff1b;公司的部分网站是内网的&#xff0c;所以得想办法内网穿透。经过众多对比后选择了小蝴蝶内网穿透&#xff01; 网址: www.npsvip.com 准备工作&…

永久免费的内网穿透

名称:DPFRP内网穿透 注册赠送30000GB流量&#xff0c;流量用完还可以用! 官网:frpc.cc 官网:fwqcz.com 1.打开官方网&#xff0c;注册账号 2.登录账号 3.个人中心 4.创建隧道 5.下载客户端 6.修改frpc.ini文件 在配置文件页面选择你刚才创建的服务器隧道&#xff0c;复制配…

钉钉免费实现内网穿透

场景&#xff1a; 有时候开发者想把私有电脑作为服务器&#xff0c;需要把开发机电脑上的项目暴露到公网&#xff0c;方便远程访问和调试&#xff0c;这时候就需要使用内网穿透&#xff0c;这里介绍一下阿里巴巴旗下钉钉内网穿透工具的使用 一、下载钉钉穿透工具&#xff0c;官…

【免费内网穿透】公网环境下,Windows系统远程桌面控制树莓派

系列文章 【免费内网穿透】公网环境下&#xff0c;Windows系统远程桌面控制树莓派【无需公网IP】为远程桌面树莓派配置固定的公网TCP端口地址 远程桌面控制树莓派&#xff0c;我们可以用xrdp协议来实现&#xff0c;它内部使用的是windows远程桌面的协议。我们只需要在树莓派上…

【群晖NAS】真·免费内网穿透方案 及踩坑合集

一.介绍 一篇科普贴&#xff0c;帮助那些刚入门NAS的朋友尽量避免踩坑。因为本人实践了其中几种穿透方案&#xff0c;也积攒了一些经验&#xff0c;跟大家分享一下。 在这里想说一句&#xff0c;现在网上充斥着各种《内网穿透方案对比》&#xff0c;可以负责任地说一下&#xf…