usb中的endpoint(端点)和传输模式

端点

端点位于USB 外设内部,所有通信数据的来源或目的都基于这些端点,是一个可寻址的FIFO。

每个USB 外设有一个唯一的地址,可能包含最多十六个端点。主机通过发出器件地址和每次数据传输的端点号,向一个具体端点(FIFO)发送数据。

每个端点的地址为0 到15,一个端点地址对应一个方向。所以,端点2-IN 与端点2-OUT 完全不同。 每个器件有一个默认的双向控制端点0,因此不存在端点0-IN 和端点0-OUT。

USB四种传输模式

控制传输、批量传输、中断传输、同步传输

USB 有上述四种传输类型。枚举期间外设告诉主机每个端点支持哪种传输类型。

USB设备驱动向USB控制器驱动请求的每次传输被称为一个事务(Transaction),

事务有四种类型:Bulk TransactionControl TransactionInterrupt TransactionIsochronous Transaction

数据包包含部分

每次事务都会分解成若干个数据包在USB总线上传输。每次传输必须历经两个或三个部分,第一部分——USB控制器向USB设备发出命令,

第二部分——USB控制器和USB设备之间传递读写请求,其方向主要看第一部分的命令是读还是写,第二部分有时候可以没有。

第三部分——握手信号。

批量(Bulk)传输事务

作用:主要应用在数据大量数据传输和接受数据上同时又没有带宽和间隔时间要求的情况下;

特点:要求保证传输。打印机和扫描仪属于这种类型这种类型的设备

适合于传输非常慢和大量被延迟的传输,可以等到所有其它类型的数据的传输完成之后再传输和接收数据。

批量数据传输分三个阶段:

第一部分——令牌阶段。

Host端发出一个Bulk的令牌请求。

如果令牌是IN请求 ,则是从Device到Host的请求;

如果令牌是OUT请求,则是从Host到Device端的请求。

第二部分——传送数据的阶段。

根据先前请求的令牌的类型,数据传输有可能是IN方向,也有可能是OUT方向。传输数据的时候用DATA0和DATA1令牌携带着数据交替传送。

数据传输格式DATA1和DATA0,这两个是重复数据,确保在1数据丢失时0可以补上,不至于数据丢失。

第三部分——握手阶段。

如果数据是IN 方向,握手信号应该是Host端发出;

如果数据是OUT方向,握手信号应该是Device端发出。

握手信号可以为ACK, 表示正常响应,

NAK, 表示没有正确传送。

STALL,表示出现主机不可预知的错误。

如图所示。

图Bulk传输

图 Bulk传输时的令牌

控制(Control)传输

作用:USB系统软件用来主要进行查询配置和给USB设备发送通用的命令;

特点:控制传输是双向传输,数据量通常较小;数据传送是无损性的。

数据宽度:控制传输方式可以包括8、16、32和64字节的数据,这依赖于设备和传输速度。

控制传输典型地用在主计算机和USB外设之间的端点0(EP0)之间的传输

控制传输也分为三个阶段,即令牌阶段、数据传送阶段、握手阶段,如下图所示。

图 控制传输事务

中断(Interrupt)传输事务

作用:主要用于定时查询设备是否有中断数据要传输;

特点:设备的端点模式器的结构决定了它的查询频率从1到255ms之间。

典型的应用在少量的分散的不可预测数据的传输键盘操纵杆和鼠标就属于这一类型

(数据量很小)

中断方式传输是单向的并且对于host 来说只有输入(IN)的方式

在中断事务中,也分为三个阶段,即令牌阶段、数据传输阶段、握手阶段,如下图所示。

中断传输事务

同步(Isochronous)传输事务

作用:用于时间严格并具有较强容错性的流数据传输,或者用于要求恒定的数据传输率的即时应用中。例如执行即时通话的网络电话。

特点:保证传输的同步性。保证每秒有固定的传输量。

(与Bulk传输不同)同步传输允许有一定的误码率。(这样符合视频会议等传输的需求,因为视频会议首先要保证实时性,在一定条件下,允许有一定的误码率。)

同步传输事务有只有两个阶段,即令牌阶段、数据阶段,因为不关心数据的正确性,故没有握手阶段,

如下图所示:

图 同步传输事务

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要增加Zynq的USB端点传输能力,可以按照以下步骤进行: 1. 修改设备树 在设备树添加USB控制器节点的属性,例如增加端点数量等。设备树是系统启动时用来描述硬件结构的一种数据结构,需要修改设备树来增加USB控制器节点的属性。例如,可以增加如下设备树节点: ``` usb@e0002000 { compatible = "xlnx,zynq-usb-2.0"; reg = <0xe0002000 0x1000>; interrupts = <0x0 0x1c 0x4>; interrupt-parent = <0x3>; xlnx,num-ep-out = <4>; xlnx,num-ep-in = <4>; xlnx,usb-mode = <0>; xlnx,dr_mode = <1>; }; ``` 其,xlnx,num-ep-out和xlnx,num-ep-in分别表示USB控制器的输出端点和输入端点数量。 2. 修改驱动程序 根据USB控制器节点的属性,修改USB驱动程序,增加端点的处理能力。驱动程序是系统运行时用来管理硬件的程序,需要修改驱动程序来增加端点处理能力。例如,在驱动程序可以增加如下代码: ``` #define MAX_EP 8 struct xusb_ep { struct usb_ep ep; struct xusb_dev *dev; u32 num; u32 dir; u32 type; u32 maxpacket; u32 interval; u32 flags; u8 *buf; }; static struct xusb_ep xusb_eps[MAX_EP]; ``` 其,xusb_eps数组用来存储USB控制器的端点信息。 3. 配置USB控制器寄存器 通过配置USB控制器寄存器,设置端点的属性,例如端点类型、缓冲区大小等。USB控制器的寄存器用来控制USB传输和处理,需要根据需要来配置寄存器。例如,在驱动程序可以增加如下代码: ``` #define USB_EP_TYPE_BULK 2 #define USB_EP_TYPE_INT 3 #define XUSB_EP_CFG_TYPE_MASK 0x03 static void xusb_ep_configure(struct xusb_ep *ep) { u32 cfg = 0; if (ep->dir == USB_DIR_IN) { cfg |= XUSB_EP_CFG_DIR_IN; } else { cfg |= XUSB_EP_CFG_DIR_OUT; } if (ep->type == USB_EP_TYPE_BULK) { cfg |= XUSB_EP_CFG_TYPE_BULK; } else if (ep->type == USB_EP_TYPE_INT) { cfg |= XUSB_EP_CFG_TYPE_INT; } else { cfg |= XUSB_EP_CFG_TYPE_CTRL; } cfg |= XUSB_EP_CFG_EN; xusb_write32(XUSB_EP_CONFIG(ep->num), cfg); } ``` 其,xusb_ep_configure函数用来配置USB控制器的端点寄存器,包括端点的方向、类型和使能等。 4. 增加USB传输通道 根据需要,增加USB传输通道,例如增加Bulk、Interrupt等传输通道。USB传输通道用来实现具体的数据传输功能,需要根据需要来增加传输通道。例如,在驱动程序可以增加如下代码: ``` static struct usb_ep_ops xusb_ep_ops = { .enable = xusb_ep_enable, .disable = xusb_ep_disable, .queue = xusb_ep_queue, .dequeue = xusb_ep_dequeue, .set_halt = xusb_ep_set_halt, .clear_halt = xusb_ep_clear_halt, .set_wedge = xusb_ep_set_wedge, .clear_stall = xusb_ep_clear_stall, }; static struct usb_endpoint_descriptor xusb_ep_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT | 1, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(512), .bInterval = 0, }; static struct usb_endpoint_descriptor xusb_ep_bulk_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN | 2, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(512), .bInterval = 0, }; static struct usb_endpoint_descriptor xusb_ep_int_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT | 3, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(16), .bInterval = 10, }; static struct usb_endpoint_descriptor xusb_ep_int_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN | 4, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(16), .bInterval = 10, }; static struct usb_endpoint_descriptor *xusb_ep_descs[] = { &xusb_ep_bulk_out_desc, &xusb_ep_bulk_in_desc, &xusb_ep_int_out_desc, &xusb_ep_int_in_desc, NULL, }; ``` 其,xusb_ep_ops结构体用来定义USB控制器的端点操作函数;xusb_ep_bulk_out_desc、xusb_ep_bulk_in_desc、xusb_ep_int_out_desc和xusb_ep_int_in_desc结构体用来定义USB控制器的Bulk和Interrupt传输通道的端点描述符。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值