一、写一个USB摄像头驱动程序
uvc_driver.c分析
uvc_driver.c分析
uvc_probe
uvc_register_video
video_device_alloc
vdev->parent = &dev->intf->dev;
vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = video_device_release;
video_register_device(vdev, VFL_TYPE_GRABBER, -1)
重要的结构体:
const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open = uvc_v4l2_open,
.release = uvc_v4l2_release,
.ioctl = uvc_v4l2_ioctl,
.read = uvc_v4l2_read,
.mmap = uvc_v4l2_mmap,
.poll = uvc_v4l2_poll,
};
usb摄像头的主要框图:
- 从上图可知usb摄像头主要由VideoControl Interface、VideoStreaming Interface两大部分组成VC的主要作用是控制设备,VS的主要作用是用于传输.
- VC内部主要由两部分组成unit和terminal,CT指的是camera terminal、IT指input terminal、su指select unit 、pu指process unit
- PU主要作用如下:
-
调用过程: 1. open uvc_v4l2_open 2. ioctrl uvc_v4l2_ioctl video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl); uvc_v4l2_do_ioctl 3. VIDIOC_QUERYCAP if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; else cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; 4. VIDIOC_ENUM_FMT format = &video->streaming->format[fmt->index]; // 设置的格式从这个数组里获取 5. VIDIOC_G_FMT uvc_v4l2_get_format // USB摄像头支持多种格式fromat, 每种格式下有多种frame(比如分辨率) struct uvc_format *format = video->streaming->cur_format; struct uvc_frame *frame = video->streaming->cur_frame; 6. VIDIOC_TRY_FMT uvc_v4l2_try_format 7. VIDIOC_S_FMT uvc_v4l2_set_format video->streaming->cur_format = format; video->streaming->cur_frame = frame; 8. VIDIOC_REQBUFS uvc_alloc_buffers for (; nbuffers > 0; --nbuffers) { mem = vmalloc_32(nbuffers * bufsize); if (mem != NULL) break; } 9. VIDIOC_QUERYBUF uvc_query_buffer __uvc_query_buffer memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf); 10. VIDIOC_QBUF uvc_queue_buffer list_add_tail(&buf->stream, &queue->mainqueue); list_add_tail(&buf->queue, &queue->irqqueue); 11. VIDIOC_STREAMON uvc_video_enable // 把设置的参数发给硬件,然后启动摄像头 uvc_commit_video uvc_set_video_ctrl __uvc_query_ctrl uvc_init_video uvc_init_video_isoc urb->complete = uvc_video_complete; usb_submit_urb 12. poll uvc_v4l2_poll poll_wait(file, &buf->wait, wait); 13. VIDIOC_DQBUF uvc_dequeue_buffer list_del(&buf->stream); 14. VIDIOC_STREAMOFF uvc_video_enable usb_kill_urb(urb); usb_free_urb(urb); 15: VIDIOC_S_CTRL uvc_ctrl_set uvc_ctrl_commit __uvc_ctrl_commit uvc_ctrl_commit_entity uvc_query_ctrl(dev, SET_CUR, ctrl->entity->id, dev->intfnum, ctrl->info->selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), ctrl->info->size);