嵌入式linux uvc,Linux摄像头驱动学习之:(四)UVC-摄像头驱动框架分析

UVC: USB Video Class

UVC驱动:drivers\media\video\uvc\

uvc_driver.c分析:

1. usb_register(&uvc_driver.driver);

2. uvc_probe

uvc_register_video

vdev = video_device_alloc();

vdev->fops = &uvc_fops;

video_register_device

在www.usb.org下载 uvc specification,

UVC 1.5 Class specification.pdf : 有详细描述

USB_Video_Example 1.5.pdf    : 有示例

通过VideoControl Interface来控制,

通过VideoStreaming Interface来读视频数据,

VC里含有多个Unit/Terminal等功能模块,可以通过访问这些模块进行控制,比如调亮度

分析UVC驱动调用过程:

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,

};

1. open:

uvc_v4l2_open

2. VIDIOC_QUERYCAP   // video->streaming->type 应该是在设备被枚举时分析描述符时设置的

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;

3. VIDIOC_ENUM_FMT // format数组应是在设备被枚举时设置的

format = &video->streaming->format[fmt->index];

4. 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;

5. VIDIOC_TRY_FMT

uvc_v4l2_try_format

/* Check if the hardware supports the requested format. */

/* Find the closest image size. The distance between image sizes is

* the size in pixels of the non-overlapping regions between the

* requested size and the frame-specified size.

*/

6. VIDIOC_S_FMT  // 只是把参数保存起来,还没有发给USB摄像头

uvc_v4l2_set_format

uvc_v4l2_try_format

video->streaming->cur_format = format;

video->streaming->cur_frame = frame;

7. VIDIOC_REQBUFS

uvc_alloc_buffers

for (; nbuffers > 0; --nbuffers) {

mem = vmalloc_32(nbuffers * bufsize);

if (mem != NULL)

break;

}

8. VIDIOC_QUERYBUF

uvc_query_buffer

__uvc_query_buffer

memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf);  // 复制参数

9. mmap

uvc_v4l2_mmap

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(video, 1)  // 把所设置的参数发给硬件,然后启动摄像头

/* Commit the streaming parameters. */

uvc_commit_video

uvc_set_video_ctrl  /* 设置格式fromat, frame */

ret = __uvc_query_ctrl(video->dev /* 哪一个USB设备 */, SET_CUR, 0,

video->streaming->intfnum  /* 哪一个接口: VS */,

probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,

uvc_timeout_param);

/* 启动:Initialize isochronous/bulk URBs and allocate transfer buffers. */

uvc_init_video(video, GFP_KERNEL);

uvc_init_video_isoc / uvc_init_video_bulk

urb->complete = uvc_video_complete; (收到数据后此函数被调用,它又调用video->decode(urb, video, buf); ==> uvc_video_decode_isoc/uvc_video_encode_bulk => uvc_queue_next_buffer => wake_up(&buf->wait);)

usb_submit_urb

12. poll

uvc_v4l2_poll

uvc_queue_poll

poll_wait(file, &buf->wait, wait);  // 休眠等待有数据

13. VIDIOC_DQBUF

uvc_dequeue_buffer

list_del(&buf->stream);

14. VIDIOC_STREAMOFF

uvc_video_enable(video, 0);

usb_kill_urb(urb);

usb_free_urb(urb);

分析设置亮度过程:

ioctl: VIDIOC_S_CTRL

uvc_ctrl_set

uvc_ctrl_commit

__uvc_ctrl_commit(video, 0);

uvc_ctrl_commit_entity(video->dev, entity, rollback);

ret = uvc_query_ctrl(dev  /* 哪一个USB设备 */, SET_CUR, ctrl->entity->id  /* 哪一个unit/terminal */,

dev->intfnum /* 哪一个接口: VC interface */, ctrl->info->selector,

uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),

ctrl->info->size);

总结:

1. UVC设备有2个interface: VideoControl Interface, VideoStreaming Interface

2. VideoControl Interface用于控制,比如设置亮度。它内部有多个Unit/Terminal(在程序里Unit/Terminal都称为entity)

可以通过类似的函数来访问:

ret = uvc_query_ctrl(dev  /* 哪一个USB设备 */, SET_CUR, ctrl->entity->id  /* 哪一个unit/terminal */,

dev->intfnum /* 哪一个接口: VC interface */, ctrl->info->selector,

uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),

ctrl->info->size);

3. VideoStreaming Interface用于获得视频数据,也可以用来选择fromat/frame(VS可能有多种format, 一个format支持多种frame, frame用来表示分辨率等信息)

可以通过类似的函数来访问:

ret = __uvc_query_ctrl(video->dev /* 哪一个USB设备 */, SET_CUR, 0,

video->streaming->intfnum  /* 哪一个接口: VS */,

probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,

uvc_timeout_param);

4. 我们在设置FORMAT时只是简单的使用video->streaming->format[fmt->index]等数据,

这些数据哪来的?

应是设备被枚举时设置的,也就是分析它的描述符时设置的。

5. UVC驱动的重点在于:

描述符的分析

属性的控制: 通过VideoControl Interface来设置

格式的选择:通过VideoStreaming Interface来设置

数据的获得:通过VideoStreaming Interface的URB来获得

(---end---)

Linux内核驱动学习(四)Platform设备驱动模型

Linux platform设备驱动模型 文章目录 Linux platform设备驱动模型 前言 框架 设备与驱动的分离 设备(device) 驱动(driver) 匹配(match) 参考 前言 ...

Linux内核驱动学习(八)GPIO驱动模拟输出PWM

文章目录 前言 原理图 IO模拟输出PWM 设备树 驱动端 调试信息 实验结果 附录 前言 上一篇的学习中介绍了如何在用户空间直接操作GPIO,并写了一个脚本可以产生PWM.本篇的学习会将写一个驱动操 ...

Linux音频驱动学习之:(1)ASOC分析

一.音频架构概述 (1)ALSA是Advanced Linux Sound Architecture 的缩写,目前已经成为了linux的主流音频体系结构,想了解更多的关于ALSA的这一开源项目的信息和 ...

linux驱动学习(八) i2c驱动架构(史上最全) davinc dm368 i2c驱动分析【转】

转自:http://blog.csdn.net/ghostyu/article/details/8094049 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 预备知识 lin ...

嵌入式Linux驱动学习之路(十一)按键驱动-中断机制

轮询方式: 和led驱动不同的是在配置IO引脚的时候,把LED的输出引脚换成输入,在read函数中向外发送io的状态.必须由应用程序不断的来查询当前IO口的状态来判断. 中断方式: /* file n ...

Linux运维学习第四周记

古木阴中系短篷 杖藜扶我过桥东 沾衣欲湿杏花雨 吹面不寒杨柳风 *不要辜负绵绵春意 第四周学记 第四周主要学习了文件查找和打包压缩的相关工具,以及软件包管理工具 文件查找相关命令 1.locate 在 ...

嵌入式Linux驱动学习之路(十三)按键驱动-异步通知

之前的按键方式: 查询: 极度占用CPU资源 中断: 在读的时候产生休眠,在没有信号的时候永远不会返回. poll机制: 在中断的基础上加上超时时间. 异步通知就是通过信号来传送. 首先在应用程序中有 ...

嵌入式Linux驱动学习之路(五)u-boot启动流程分析

这里说的u-boot启动流程,值得是从上电开机执行u-boot,到u-boot,到u-boot加载操作系统的过程.这一过程可以分为两个过程,各个阶段的功能如下. 第一阶段的功能: 硬件设备初始化. 加 ...

linux基础命令学习(四)计划任务

一.计划任务 crond服务简介 linux任务调度的工作主要分为以下两类: *系统执行的工作:系统周期性所要执行的工作,如备份系统数据.清理缓存 *个人执行的工作:某个用户定期要做的工作,例如每隔1 ...

鸟哥的linux私房菜学习-(四)linux命令的基本概念

一.命令格式及使用方式 注意到上面的说明当中,『第一个被输入的数据绝对是命令或者是可运行的文件』! 这个是很重要的概念喔!还有,按下[Enter]键表示要开始运行此一命令的意思. 如下效果一样: 二. ...

随机推荐

pip安装 exception记录

在下载p4c-bm的时候,执行 sudo pip install -r requirements.txt 时,出现exception: Exception: Traceback (most recen ...

android ScrollView滚动距离和判断滚动停止状态

今天很高兴,自己解决了判断ScrollView滚动停止的监听,现在分享给大家. 因为ScrollView没有像listView中的setOnScrollListener()监听,当然也就没有SCROL ...

java 不可变类型

1. java不可变性初探 我们先看下面一个例子:代码如下: import java.math.BigInteger; public class BigProblem { public static ...

CoreMotion(加速计)

加速计的作用 用于检测设备的运动(比如摇晃) 加速计的经典应用场景 摇一摇 计步器 ********************************** Core Motion获取数据的两种方式 pu ...

MFC让控件随窗口大小而改变

转载自http://blog.csdn.net/chw1989/article/details/7488711 大小和位置都改变(亲测可行) 1.首先为窗体类添加CRect m_rect,该成员变量用 ...

Spring Boot jar包linux服务器部署

Spring Boot 部署 一.使用命令行java -jar 常驻 nohup java -jar spring-boot-1.0-SNAPSHOT.jar > log.file 2>& ...

VS2017 C/C++输入密码显示*星号

VS2017  C/C++输入密码显示*星号 _getch()函数使用时遇到的坑 参考: https://blog.csdn.net/guin_guo/article/details/46237905 ...

jenkins 多版本 jdk

最近又开始使用jenkins了,遇到一个问题,开发本地使用的jdk是1.7,而我们jenkins由于需要对docker的插件的支持必须使用1.8. 这样就导致了有的开发的代码在jenkins去代码库c ...

sugarCRM文档翻译1

2018-3-9 14:42:14 星期五 本文分两部分: 第一部分是从index.php入口开始的代码执行的部分流程 第二部分是对官方文档的翻译 第一部分: 流程: 入口文件: index.php ...

JavaScript实现页面显示倒计时功能

下面是用JS中的日期函数和定时器完成的一个倒计时的例子,效果如图: 代码如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值