LDD3 USB驱动程序章节笔记

来源:互联网 发布:淘宝认证审核中 编辑:程序博客网 时间:2024/04/28 07:13

Linux下的USB 驱动

    USB分为:USB host驱动程序和USB device驱动程序。
    USB 驱动程存在于不同的内核子系统(块设备/网络设备/字符设备等)和USB硬件控制器中。
    USB核心为USB驱动程序提供了一个用于访问和控制USB硬件的接口,而不必考虑系统当前存在的各种不同类型的USB硬件控制器。
   
    VFS层
    块设备
    网络设备
    字符设备

    USB设备驱动程序
    USB核心
    USB主控制器


用户可以通过上层驱动来访问USB驱动程序。

对于USB的特性,在STM32时候已经研究的很清楚了,所以这里不在赘述端点/接口/描述字等一些特性。
特性对应的结构体:
端点->struct usb_host_endpoint
接口->struct usb_interface
配置->struct usb_host_config
整个USB设备由usb_device来描述

USB和sysfs,sysfs列出的usb信就有点类似于windows设备管理器下一样,可以查看usb的信息。


USB urb


linux内核中的USB代码通过urb和所有的usb设备通信。
urb的结构体描述:struct urb 位于 /include/linux/usb.h

urb用来以一种异步的的方式往/从USB设备上的特定USB端点发送/接收数据
设备中的每个端点都可以处理一个urb队列,所以多个urb可以在队列为空之前发送到同一个端点。一个urb的典型生命周期如下:
1、由USB驱动程序创建
2、分配给一个特定USB设备的端点
3、由USB设备驱动程序递交到USB核心
4、由USB控制器驱动程序处理,它从设备进行USB传送
5、当urb结束后,USB主控制器驱动程序通知USB设备驱动程序
 
创建和销毁urb

创建:
    struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)

iso_packets: 包含等时数据包的数量,如果不打算创建等时urb,该值为0
mem_flags:  和kmalloc函数的标志有相同的类型。

返回值:如果是NULL则分配错误,驱动程序要适当清理。如果不是NULL,那么就申请了一个urb。

释放:
    void usb_free_urb(struct urb *urb)
urb:就是成功申请的urb。

初始化:

不同的USB端点类型拥有不同初始化函数,


中断传输端点的初始化:
    static inline void usb_fill_int_urb (struct urb *urb,
                     struct usb_device *dev,
                     unsigned int pipe,
                     void *transfer_buffer,
                     int buffer_length,
                     usb_complete_t complete_fn,
                     void *context,
                     int interval)


urb:使用usb_alloc_urb成功申请的urb指针;
dev:urb发送的目标USB设备;
pipe: urb发送的目标USB设备的特定端点,使用usb_sndintpipe或usb_rcvintpipe函数来创建
    (一个urb对应一个端点,一个dev又多个接口,一个接口有多个端点)
transfer_buffer:用于保存外发数据或接收数据得的缓冲区指针,不能是静态的缓冲区,必须使用kmalloc             来创建;
buffer_length:transfer_buffer缓冲区的大小
complete_fn:urb结束后的处理函数指针
context:指向一个小数据块,该块添加到urb结构体中以便进行结束处理hanshu后面的查找
interval:urb被调用的间隔,

批量传输端点的初始化:
    static inline 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)
参数和中断传输端点函数的参数一样,pipe使用usb_sndbulkpipe或usb_rcvbulkpipe函数来创建
批量传输没有时间间隔。

控制传输端点的初始化:
    static inline 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)
参数和中断传输端点函数的参数一样,新增的 unsigned char *setup_packet参数:指向即将被发送到端点的设置数据包的数据,参数和中断传输端点函数的参数一样,pipe使用usb_sndctrlpipe或usb_rcvctrlpipe函数来创建

等时传输端点的初始化:
    等时传输urb被提交到USB核心之前,必须手动初始化,即手动初始化urb结构体的每一个成员变量。


创建和初始化urb后,就可以提交到usb核心了,提交函数:
     int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
参数:
     urb:成申请并初始化的urb指针,mem_flags:  和kmalloc函数的标志有相同的类型。用于告诉 USB核心如何在此时及时地分配缓冲区



0 0
原创粉丝点击