首页 > 编程知识 正文

mipi协议详细介绍,USB传输协议

时间:2023-05-05 18:31:40 阅读:44369 作者:2259

最近学习了usb相关知识,一直摸不着头脑,看了《linux那些事儿之我是usb》,对usb协议不熟悉,没能继续读下去。 读了《sqdxf教你玩usb》这本书,很快就提起了自己的兴趣。 愤怒的鞋垫sqdxf在51单片机上实现了usb鼠标键盘等设备,非常佩服。 51单片机自己还很熟悉,在大学里玩了四年单片机。 单片机实现后很快就变得亲切了。 我决定先从单片机开始学习。 之后,看到linux的事我是usb。 深入学习linux内核下的usb。 以下介绍usb协议。 内容从usb spec、网络和sqdxf的书开始整理。 本文也大量引用了STM32官方的USB2.0协议文档。 欢迎批评。 另外,学习《sqdxf教你玩usb》用手调试实现了单片机的usb鼠标功能。 源代码为https://github.com/lisong ze 2016/MCU _ project/tree/master/USB,源代码中有linux kernel ch9.h用于描述符

通用串行总线(USB )是一条完整的通用串行总线,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:dvoh(min ) ) 2.8V (且d-vol (max ) ) 0.3V ) )。

差动信号0:D- VOH and D VOL

j状态(pgfh ) 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信号退出

带远程唤醒功能的设备还可以自己启动唤醒信号。 假设设备至少进入5msidle状态后,发出唤醒k信号,保持1ms到15ms,主机在1ms内交接,并继续驱动唤醒信号

sop :从空闲状态切换到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,

编码成“电平不变” 
编码出来的序列,pgfh: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. */

 

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。