1、构造一个usb_driver
2、设置
probe
2.1、分配video_device:video_device alloc
2.2、设置
.fops
.ioctl_ops(里面需要设置11项)
如果要内核提供缓冲区操作函数,还需要构造一个videobuf queue ops
2.3、注册 :video_register_device
id_table:表示支持哪些USB设备
3、注册
UVC:USB Video Class
Makefile: 在/media/video/uvc/Makefile脚本有
uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o \
uvc_ctrl.o uvc_status.o uvc_insight.o
obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
重要结构体:
*****************************************
/drivers/media/video/uvc/uvc_driver.c
struct uvc_driver uvc_driver = {
.driver = {
.name = "uvcvideo",
.probe = uvc_probe,
.disconnect = uvc_disconnect,
.suspend = uvc_suspend,
.resume = uvc_resume,
.reset_resume = uvc_reset_resume,
.id_table = uvc_ids,
.supports_autosuspend = 1,
},
}
// /drivers/media/video/uvc/uvcvideo.h
struct uvc_driver {
struct usb_driver driver;
};
->// /include/linux/usb.h
struct usb_driver={
const char * name; //驱动名
int (*probe) (struct usb_interface *intf,const struct usb_device_id *id);//即插即用
void (*disconnect) (struct usb_interface *intf);
int (*unlocked_ioctl) (struct usb_interface *intf,unsigned int code, void buf);
int (*suspend) (struct usb_interface *intf, pm_message_t message);
....
const struct usb_device_id *id_table;
....
}
/drivers/media/video/uvc/uvcvideo.h
struct uvc_device {
struct usb_device *udev;
struct usb_interface *inf;
....
struct v4l2_device vdev;
__u16 uvc_version;
__u32 clock_frequency;
struct list_head entities;
struct list_head chains;
/* Video Streaming interfaces */
struct list_head streams;
atomic_t nstreams;
/* Status Interrupt Endpoint */
struct usb_host_endpoint *int_ep;
struct urb *int_urb;
....
}
// /include/linux/usb.h
->struct usb_device {
int devnum;
char devpath[16];
u32 route;
....
struct usb_device *parent;
struct usb_bus *bus;
struct usb_host_endpoint ep0;
struct device dev;
struct usb_device_descriptor descriptor;
struct usb_host_bos *bos;
struct usb_host_config *config;
struct usb_host_config *actconfig;
struct usb_host_endpoint *ep_in[16];
struct usb_host_endpoint *ep_out[16];
....
}
*************************************************
uvc_driver.c函数分析:
static int __init uvc_init(void)
{
uvc_debugfs_init();
ret = usb_register(&uvc_driver.driver);
--->
// inlcude/linux/usb.h
#define usb_register(driver) \ usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
--->
/drivers/usb/core/driver.c
int usb_register_driver(struct usb_driver *new_driver,...)
{
new_driver->drvwrap.for_devices = 0;
new_driver->drvwrap.driver.name = (char *) new_driver->name;
new_driver->drvwrap.driver.bus = &usb_bus_type;
new_driver->drvwrap.driver.probe = usb_probe_interface;
new_driver->drvwrap.driver.remove = usb_unbind_interface;
new_driver->drvwrap.driver.owner = owner;
....
INIT_LIST_HEAD(&new_driver->dynids.list);
....
retval = driver_register(&new_driver->drvwrap.driver);
....
usbfs_update_special();
retval = usb_create_newid_files(new_driver);
}
}
2、设置
probe
2.1、分配video_device:video_device alloc
2.2、设置
.fops
.ioctl_ops(里面需要设置11项)
如果要内核提供缓冲区操作函数,还需要构造一个videobuf queue ops
2.3、注册 :video_register_device
id_table:表示支持哪些USB设备
3、注册
UVC:USB Video Class
Makefile: 在/media/video/uvc/Makefile脚本有
uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o \
uvc_ctrl.o uvc_status.o uvc_insight.o
obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
重要结构体:
*****************************************
/drivers/media/video/uvc/uvc_driver.c
struct uvc_driver uvc_driver = {
.driver = {
.name = "uvcvideo",
.probe = uvc_probe,
.disconnect = uvc_disconnect,
.suspend = uvc_suspend,
.resume = uvc_resume,
.reset_resume = uvc_reset_resume,
.id_table = uvc_ids,
.supports_autosuspend = 1,
},
}
// /drivers/media/video/uvc/uvcvideo.h
struct uvc_driver {
struct usb_driver driver;
};
->// /include/linux/usb.h
struct usb_driver={
const char * name; //驱动名
int (*probe) (struct usb_interface *intf,const struct usb_device_id *id);//即插即用
void (*disconnect) (struct usb_interface *intf);
int (*unlocked_ioctl) (struct usb_interface *intf,unsigned int code, void buf);
int (*suspend) (struct usb_interface *intf, pm_message_t message);
....
const struct usb_device_id *id_table;
....
}
/drivers/media/video/uvc/uvcvideo.h
struct uvc_device {
struct usb_device *udev;
struct usb_interface *inf;
....
struct v4l2_device vdev;
__u16 uvc_version;
__u32 clock_frequency;
struct list_head entities;
struct list_head chains;
/* Video Streaming interfaces */
struct list_head streams;
atomic_t nstreams;
/* Status Interrupt Endpoint */
struct usb_host_endpoint *int_ep;
struct urb *int_urb;
....
}
// /include/linux/usb.h
->struct usb_device {
int devnum;
char devpath[16];
u32 route;
....
struct usb_device *parent;
struct usb_bus *bus;
struct usb_host_endpoint ep0;
struct device dev;
struct usb_device_descriptor descriptor;
struct usb_host_bos *bos;
struct usb_host_config *config;
struct usb_host_config *actconfig;
struct usb_host_endpoint *ep_in[16];
struct usb_host_endpoint *ep_out[16];
....
}
*************************************************
uvc_driver.c函数分析:
static int __init uvc_init(void)
{
uvc_debugfs_init();
ret = usb_register(&uvc_driver.driver);
--->
// inlcude/linux/usb.h
#define usb_register(driver) \ usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
--->
/drivers/usb/core/driver.c
int usb_register_driver(struct usb_driver *new_driver,...)
{
new_driver->drvwrap.for_devices = 0;
new_driver->drvwrap.driver.name = (char *) new_driver->name;
new_driver->drvwrap.driver.bus = &usb_bus_type;
new_driver->drvwrap.driver.probe = usb_probe_interface;
new_driver->drvwrap.driver.remove = usb_unbind_interface;
new_driver->drvwrap.driver.owner = owner;
....
INIT_LIST_HEAD(&new_driver->dynids.list);
....
retval = driver_register(&new_driver->drvwrap.driver);
....
usbfs_update_special();
retval = usb_create_newid_files(new_driver);
}
}