Linux gadget USB设备端驱动程序(kernel 2.6.28)

本文详细介绍了Linux gadget USB设备端驱动的相关结构体,包括`struct usb_gadget`、`struct usb_gadget_driver`、`struct usb_gadget_ops`等,并讲解了Gadget层驱动提供的常用函数以及USB gadget功能驱动的编写要点。通过一个简单的Zero.c驱动示例,展示了如何实现USB设备端的驱动框架。

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

一、几个重要设备端Gadget驱动结构体:

1. struct usb_gadget {//代表一个UDC设备 
        /* readonly to gadget driver */ 
               const struct usb_gadget_ops *ops; //设备的操作集
               struct usb_ep *ep0; //ep0(USB协议中的端点0), 处理setup()请求
               struct list_head ep_list; /* of usb_ep */本设备支持的端点链表
               enum usb_device_speed speed; //如:USB_SPEED_LOW、USB_SPEED_FULL等
               unsigned is_dualspeed:1; //支持full/high speed
               unsigned is_otg:1; //OTG的特性
               unsigned is_a_peripheral:1; //当前是A-peripheral,而不是A-host 
               unsigned b_hnp_enable:1; 
               unsigned a_hnp_support:1; 
               unsigned a_alt_hnp_support:1; 
               const char *name;
               struct device dev; 
        };


2. struct usb_gadget_driver {//代表一个gadget设备driver,如:file_storage.c中的fsg_driver
//又如:如zero.c中的zero_driver
               char *function; //一个字符串,如"Gadget Zero" 
               enum usb_device_speed speed; 
               int (*bind)(struct usb_gadget *);       //常用语将dev 与driver的绑定,类似于probe,会被底层Gadget自动调用
               void (*unbind)(struct usb_gadget *);    //与bind作用相反
               int (*setup)(struct usb_gadget *,    const struct usb_ctrlrequest *);    //用于usb设备setup阶段的USB_REQ_GET_DESCRIPTOR等主机端的请求处理,完成USB设置阶段和具体功能相关的交互
               void (*disconnect)(struct usb_gadget *);
               void (*suspend)(struct usb_gadget *); 
               void (*resume)(struct usb_gadget *)

       /* FIXME support safe rmmod */ 
               struct device_driver driver; 
        };

3. struct usb_gadget_ops {//代表设备的操作集
                       int (*get_frame)(struct usb_gadget *);
                       int (*wakeup)(struct usb_gadget *);
                       int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered);
                       nt (*vbus_session) (struct usb_gadget *, int is_active);
                       int (*vbus_draw) (struct usb_gadget *, unsigned mA);
                       int (*pullup) (struct usb_gadget *, int is_on);
                       int (*ioctl)(struct usb_gadget *,
                       unsigned code, unsigned long param); 
        };

4. struct usb_ep {//代表一个端点
                       void *driver_data // 
                       ...
                       const struct usb_ep_ops *ops; //端点的操作集,如上
                       struct list_head ep_list; //gadget的所有ep的list
                       ...
        };
   5.     struct usb_ep_ops {//表示端点的操作集 
                       ... 
                       int (*queue) (struct usb_ep *ep, struct usb_request *req, 
                       gfp_t gfp_flags); //将一个usb_request提交给endpoint 
                       //是数据传输的关键函数 
                       ...
        };

6.  struct usb_request {//表示一个传输的请求,这与usb host端的urb类似
                       void *buf; 
                       unsigned length; 
                       dma_addr_t dma;
                       unsigned no_interrupt:1;
                       unsigned zero:1;
                       unsigned short_not_ok:1;
                       void (*complete)(struct usb_ep *ep,  struct usb_request *req);   //一个usb请求提交完成后的回调函数
                       void *context;
                       struct list_head list;
                       int status;
                       unsigned actual;
        };

7.  struct usb_ctrlrequest (用在setup函数中)
|-----------------------|
| __u8    bRequestType -|
| __u8    bRequest     -|
| __le16 -wValue       -|
| __le16 -wIndex       -|
| __le16 -wLength      -|
|-----------------------|

这个数据结构就是SETUP信包的内容,而缓冲区的内容,就是随后的数据信包的内容。
---------------------------------------------------------------
bRequestType
    D7     数据的传输方向:0表示从主机到设备; 1表示从设备到主机;
    D6~5   命令的类型:   0表示标准命令;    1表示类命令;      2表示厂商提供的命令; 3保留;
    D4~0   接收对象;     0表示设备;       1表示接口;       2表示端点;         3表示其他;
bRequest
    命令的序号(其实就是命令);所有的命令都是以不同编码值的方式传递给设备的,bRequest就表示USB命令的编码值
wValue, wIndex
    这两个字段对于不同的命令有不同的含义
wLength
    表示在完成命令控制传输的数据阶段,要求传输数据的字节长度。一般不论是输入还是输出都要求给出准确的数字。当命令不需要传输数据时,此字段设为0

二、Gadget层驱动提供的几个常用的函数:

1. usb_gadget_register_driver  注册usb_gadget_driver类型的驱动

2. usb_gadget_unregister_driver 注销usb_gadget_driver类型驱动

3. struct usb_ep * __init usb_ep_autoconfig (
    struct usb_gadget        *gadget,
    struct usb_endpoint_descriptor    *desc
)    用于根据端点描述符及控制器端点情况,分配一个合适的端点。

4. static inline struct usb_request *usb_ep_alloc_request(struct usb_ep *ep,
                               gfp_t gfp_flags)  分配一个usb_request

3. 通过Gadget Core 驱动,向usb_ep发送usb_request, 请求读写

static inline int usb_ep_queue(struct usb_ep *ep,
                   struct usb_request *req, gfp_t gfp_flags);    

三、USB gadget功能驱动

       

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值