本文共 1364 字,大约阅读时间需要 4 分钟。
1、 Usb总线:
USB总线是一种轮询方式的总线。 协议规定所有的数据传输都必须由主机发起, host controller初始化所有的数据传输,各种设备紧紧围绕在主机周围。
2、DMA 映射:
一般来说,都是驱动里提供了 kmalloc 等分配的缓冲区,HCD 做一定的 DMA 映射处理,从而外设和内存之间进行数据交换的目的;外设是通过各种总线连到主机里边儿的,使用的是总线地址,而内存使用的是虚拟地址,它们之间本来就是两条互不相交的平行线,要让它们中间产生连接点,必须得将一个地址转化为另一个地址,这样才能找得到对方,才能互通有无,而 DMA 映射就是干这个的。URB_NO_TRANSFER_DMA_MAP,还有 URB_NO_SETUP_DMA_MAP这里的两个标志,告诉 HCD 不要再自己做 DMA 映射了,驱动提供的 urb 里已经提供有 DMA 缓冲区地址;(transfer_buffer,transfer_dma,setup_packet,setup_dma)
2、 transfer_buffer,transfer_dma,transfer_buffer_length
前面说过管道的一端是主机上的缓冲区,一端是设备上的端点,这三个家伙就是描述主机上的那个缓冲区的。transfer_buffer 是使用 kmalloc 分配的缓冲区,transfer_dma 是使用
usb_buffer_alloc分配的 dma 缓冲区,HCD 不会同时使用它们两个,如果你的 urb自带了 transfer_dma,就要同时设置URB_NO_TRANSFER_DMA_MAP 来告诉 HCD 一声,不用它再费心做 DMA 映射了。transfer_buffer 是必须要设置的,因为不是所有的主机控制器都能够使用 DMA 的,万一遇到这样的情况,也好有个备用。transfer_buffer_length指的就是 transfer_buffer或 transfer_dma的长度。
setup_packet,setup_dma,同样是两个缓冲区,一个是kmalloc分
配的,一个是用usb_buffer_alloc分配的,不过,这两个缓冲区是控制传输专用的,记得struct usb_ctrlrequest不?它们保存的就是一个struct usb_ctrlrequest结构体,如果你的urb设置了setup_dma, 同样要设置URB_NO_SETUP_DMA_MAP标志来告诉HCD。如果进行的是控制传输,setup_packet是必须要设置的,也是为了防止出现主机控制器不能使用DMA的情况。
3、 interval,等时和中断传输专用,端点希望主机轮询自己的时间间隔;
对于中断传输,全速时,这个范围为1~255ms,低速是为 10~255ms,高速时为 1~16,这个 1~16 只是 bInterval可以取的值,实际的间隔时间需要计算一下,为 2 的(bInterval-1)次方乘以 125 微妙,也就是 2 的(bInterval-1)次方个微帧。对于等时传输,没有低速了
本文转自 曾永刚 51CTO博客,原文链接:http://blog.51cto.com/zyg0227/560129
转载地址:http://umcix.baihongyu.com/