linux usb urb,usb中urb接口函数

linux usb urb,usb中urb接口函数一 简介 usb 总线是一种轮询式总线 协议规定所有的数据传输都必须由主机发起 usb 主机与设备之间是通过管道 pipe 传输的 管道两边分别对应主机中的数据缓冲区和设备侧的端点 endpoint 端点是通信的发送和接收点 要发送数据 只要把数据发到对应的端点就可以 而这个数据发送的动作由 usb 主机实现 驱动中只需确定接收端点 然后把数据提交给主机控制器 主机会把数据发送给接收端点 原理同 i2c

一. 简介

usb总线是一种轮询式总线,协议规定所有的数据传输都必须由主机发起,usb主机与设备之间是通过管道(pipe)传输的,管道两边分别对应主机中的数据缓冲区和设备侧的端点(endpoint),端点是通信的发送和接收点,要发送数据,只要把数据发到对应的端点就可以,而这个数据发送的动作由usb主机实现,驱动中只需确定接收端点,然后把数据提交给主机控制器,主机会把数据发送给接收端点,原理同i2c,uart类似。每个usb设备中都存在一个特殊端点endpoint0,在usb设备枚举过程里,就是通过endpoint0来获取usb设备信息。

USB按传输类型分可以分为控制传输(control),中断传输(interrupt),等时传输(isochronous),批量传输(bulk),其中控制传输和批量传输又称为非周期性传输方式(nonperiodic),而中断传输和等时传输称为周期性传输方式(periodic);

USB控制器和设备之间的传输数据结构由urb表示,urb具体内容如下所示:

struct urb {

struct kref kref;

void *hcpriv;

atomic_t use_count;

atomic_t reject;

int unlinked;

struct list_head urb_list;

struct list_head anchor_list; * the URB may be

anchored */

struct usb_anchor *anchor;

struct usb_device *dev;

struct usb_host_endpoint *ep;

unsigned int pipe;

unsigned int stream_id;

int status;

unsigned int transfer_flags;

void *transfer_buffer;

dma_addr_t transfer_dma ;

struct scatterlist *sg;

int num_sgs;

u32 transfer_buffer_length;

u32 actual_length;

unsigned char *setup_packet;

dma_addr_t setup_dma;

int start_frame;

int number_of_packets;

int interval;

int error_count;

void *context;

usb_complete_t complete;

struct usb_iso_packet_descriptor iso_frame_desc[0];

};

二. urb操作接口函数

usb 用urb发送数据时分三个步骤:申请urb, 填充urb,向usb控制器提交urb.

1.申请和释放urb

struct urb *usb_alloc_urb(int  iso_packets,

gfp_t mem_flags)

iso_paskets为等时传输时变长数组iso_frame_desc的元素个数,对于中断,控制和批量传输应该为0,mem_flags为申请内存空间时所需的标志位。

void usb_free_urb(struct urb *urb)

{

if (urb)

kref_put(&urb->kref, urb_destroy)

}

urb和端点不是一一对应的关系,一个urb可以被发向多个不同的端点,这里通过urb->kref来统计某个urb被使用次数,当使用urb时,kref加1,调用usb_free_urb时urb减1,当kref为0时,调用urb_destroy来释放urb中的transfer_buffer和urb。

2. 填充urb结构数据

对于usb的四种不同传输方式,usb驱动中已经实现control,bulk,interrupt三种传输类型传输填充函数。

void usb_fill_control_urb(struct urb *urb, struct usb_device

*dev, unsigned int pipe, unsigned char *setup_packet, void

*transfer_buffer, int buffer_length, usb_complete_t complete_fn,

void *context)

其中urb为要初始化的控制类型urb,dev为USB设备,pipe为管道,setup_packet专门用于发送control的usb_contrlrequest的setup包,transfer_buffer发送缓冲区,

buffer_length传输长度,

complete_fn为urb递交给hcd后将会运行的回调函数,comtext为回调函数参数。

与control填充函数相比,bulk传输方式的初始化少了setup_packet设置,bulk函数接口为:

void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev,

unsigned int pipe, void *transfer_buffer, int

buffer_length, usb_complete_t complete_fn, void *context)

对于interrupt而言,还需设置定时查询时间间隔interval, 函数接口为:

void usb_fill_int_urb(struct urb*urb, struct usb_device *dev,

unsinged int pipe, void *transfer_buffer, int buffer_length,

usb_complete_t complete_fn ,void *context, int interval)

对于等时传输,urb里是可以指定多次传输的,所以必须一个一个的对变长数组iso_frame_esc内容进行初始化。

3.urb递交给主机控制器

经过前面的创建、初始化和填充数据后,urb需要提交给usb

core,让它移交给主机控制器驱动进行处理,然后等待hcd的反馈结果,用于提交urb函数接口为:

int usb_submit_urb(struct urb*urb, gfp_t mem_flags)

其中urb即为提交给hcd的urb,mem_flags为申请urb中的hcprv,endpoint

descripotr和 transfer descriptor时要用到的申请内存标志。

将urb提交给控制器后,由控制器进行处理,并通过回调函数返回urb发送结果。

4. urb的取消

如果想取消之前提交的urb,可以用usb_unlink_urb来实现:

int usb_unlink_urb(struct urb *urb);

5.  urb其它接口

用前面的方式提交urb或取消urb时,程序不会阻塞,属于异步方式。除了异步方式外,usb还可用同步方式来提交和取消urb。同样由于isochronous中发送数据包个数不确定性,驱动只实现了control,interrupt和bulk三种方式

的同步方式操作urb接口。

int usb_control_msg(struct

usb_device *dev, unsigned int pipe, u8 request, u8 requesttype, u16

value, u16 index, void *data, u16 size, int

timeout)

usb_control_msg用于发送control类数据,对于control类型,除发送正常数据外,还要发送一个setup

transaction, request,

requesttype指定请求包的类型和属性,data为要发送的数据,size为发送数据长度,timeout为发送超时时间。

int usb_interrupt_msg(struct

usb_device *usb_dev, unsigned int pipe, void *data, int len, int

*actual_length, int timeout)

int usb_bulk_msg(struct

usb_device *usb_dev, unsigned int pipe, void *data, int len, int

*actual_length, int timeout)

上面三个接口函数都已经将之前提到过的申请urb,填充urb和提交urb过程封装在一起,在使用时只要指定对应该数据,数据长度及超时时间就可以。在使用上面三个接口提交urb时,程序阻塞,直到超时或urb提交成功并通过回调函数返回结果并唤醒等待队列。

在同步方式下对应的urb取消函数接口为:

void usb_kill_urb(struct urb

*urb)

usb_kill_urb提交取消urb申请后,会一直等待urb取消完成才会退出,里面的等待也是通过等待队列实现的。

原文:http://www.360doc.com/content/15/0202/19/13640092_445777054.shtml

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222431.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:49
下一篇 2026年3月17日 下午3:49


相关推荐

  • 强烈推荐android studio用的几个插件[通俗易懂]

    强烈推荐android studio用的几个插件

    2022年1月30日
    60
  • 百度秒哒Skill上线,打通“龙虾”创收最后一公里

    百度秒哒Skill上线,打通“龙虾”创收最后一公里

    2026年3月16日
    1
  • ANT如何安装?

    ANT如何安装?1、安装Ant之前首先的安装好JAVA环境,ant的官网下载:https://ant.apache.org/manualdownload.cgi(注意:要选择与自己JDK相匹配的ant.这里我选择的是

    2022年7月4日
    32
  • 计算机病毒的分类

    计算机病毒的分类病毒与木马病毒:指编制或在计算机程序中插入的破坏计算机功能或破坏数据,影响计算机使用并且能够自我复制的一组计算机指令或程序代码。木马:是一种后门程序,被黑客用作控制远程计算机的工具。木马与病毒不同的是,木马不会自我繁殖,并不会刻意地感染其他文件,它的作用就是为黑客打开远程计算机的门户,从而可以让黑客来远程控制计算机,使黑客获取有用的信息。病毒是自动破坏目标计算机,而木马需要人为的去操控…

    2022年5月3日
    48
  • mysql日志分析工具之mysqlsla

    mysql日志分析工具之mysqlsla一 前言当我们使用自己搭建的 mysql 的时候 如何排查慢日志呢 如何对慢日志进行分析呢 下面介绍两款常用的慢日志分析工具 mysqldumpslo 二 mysqldumpslo 这是一款 mysql 自带的慢查询工具 个人使用下来发现 可以满足在很多慢日志中找到有问题的慢的 sql 并且可以进行 sql 排序 属于一种短小精干的工具 得到返回记录集最多的 10 个 SQL mysqldumpslo sr t10 var lib mysql test mysql slow

    2026年3月19日
    2
  • idea配置tomcat启动web项目

    idea配置tomcat启动web项目配置 tomcat1 点击 runconfigura 选择 tomcatlocal3 配置 tomcat4 部署 web 项目部署有 2 种方式 war 包 打成 war 置于服务器运行 这种方式我们比较常见 warexploded 将 web 工程以当前文件夹的位置关系上传到服务器 就是直接把文件夹 jsp 页面 classes 等移到 Tomcat 部署文件夹里面 进行加载部署 因此这种方

    2026年3月17日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号