LDD3 USB驱动程序章节笔记

本文深入探讨了Linux下的USB驱动架构,包括USBhost和USBdevice驱动程序,并详细解释了USB核心提供的接口及其与不同内核子系统的交互方式。此外,还介绍了urb在Linux内核中的作用及其生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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核心如何在此时及时地分配缓冲区



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

john_liqinghan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值