1、usb描述信息
struct usb_interface_descriptor
{
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
}
/*
接口描述信息
重要的几个字段
bLength:一般填USB_DT_INTERFACE_SIZE
bInterfaceNumber: 一般填USB_DT_INTERFACE
bNumEndpoints:根据自己的需求填需要的端点数量
bInterfaceClass:接口类型,根据自己需求选择一个,如果不知道可以填USB_CLASS_VENDOR_SPEC
以上4个字段为必填。
*/
2、端点描述
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
__u8 bRefresh;
__u8 bSynchAddress;
}
/*
bLength:一般填USB_DT_ENDPOINT_SIZE
bDescriptorType:一般填USB_DT_ENDPOINT
bEndpointAddress:可填USB_DIR_IN或USB_DIR_OUT
bmAttributes:可填USB_ENDPOINT_XFER_ISOC,USB_ENDPOINT_XFER_BULK,USB_ENDPOINT_XFER_INT
*/
3、注册USB function
在init函数中调用usb_function_register注册功能。
在struct usb_function_driver中必须实现alloc_inst和alloc_func回调函数。
在alloc_inst中,需要返回struct usb_function_instance指针,需要填充
free_func_inst回调函数,该函数在功能被移除时调用。所以可以将所有的资源
回收过程在此函数中实现。
并且可以把一些需要在功能被创建时实现的功能在此处实现。
在函数返回前需要调用config_group_init_type_name对group进行初始化。
这个可以实现给功能添加其它功能的目的。
调用config_group_init_type_name后就可以将struct usb_function_instance指针返回。
alloc_func回调函数返回struct usb_function指针,在struct usb_function指针返回前
需要填充name, bind,set_alt,get_alt,disable,setup,free_func。
name是这个功能的名字,在通过configfs创建功能时会用到。
bind是核心功能,用于分配ep端点,协商速率等待,此函数是在中断被调用的,所有在中断不能做的,当然也不能在此实现。
set_alt在该回调中主要是配置速率,开启端点。
4、数据交互
数据是通过在bind时协商的端点进行传输。
先调用usb_ep_alloc_request 分配request,
struct usb_request {
void *buf;
unsigned length;
dma_addr_t dma;
struct scatterlist *sg;
unsigned num_sgs;
unsigned num_mapped_sgs;
unsigned stream_id:16;
unsigned is_last:1;
unsigned no_interrupt:1;
unsigned zero:1;
unsigned short_not_ok:1;
unsigned dma_mapped:1;
void (*complete)(struct usb_ep *ep,
struct usb_request *req);
void *context;
struct list_head list;
unsigned frame_number;
int status;
unsigned actual;
}
/*
我们只需要填充buf, length, complete, context
buf:需要传输或作为接收缓冲区
length: buf的长度,
complete是一个回调函数,在发送或接收完成时调用。
context:上下文,在complete回调函数中可以使用。
actual:接收收到的数据大小。
填充好上面4个字段后调用usb_ep_queue发起传输
*/