内核文档: V4L2-framework.txt
一、测试虚拟驱动vivi
准备工作:安装xawtv
sudo apt-get install xawtv
源码xawtv-3.95.tar.gz
http://www.kraxel.org/releases/xawtv/
在这个网站创建新的sources.list
http://repogen.simplylinux.ch/
1. 选择国家
2.选择相邻的ubuntu版本
3. 选择"Ubuntu Branches"
4. 生成sources.list
5. 把得到内容替换到/etc/apt/sources.list
deb http://cn.archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse
6. sudo apt-get update
sudo apt-get install xawtv
测试USB摄像头:
1.让VMWAER处于前台,接上USB摄像头,可以看到生成了/dev/video0
2.执行 xawtv 即可看到图像
测试虚拟摄像头vivi:
1. 确实ubuntu的内核版本
uname -a
Linux book-desktop 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:04:26 UTC 2009 i686 GNU/Linux
2. 去www.kernel.org下载同版本的内核
解压后把drivers/media/video目录取出
修改它的Makefile为:
KERN_DIR = /usr/src/linux-headers-2.6.31-14-generic
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += vivi.o
obj-m += videobuf-core.o
obj-m += videobuf-vmalloc.o
obj-m += v4l2-common.o
3. make
4. sudo modprobe vivi
sudo rmmod vivi
sudo insmod ./vivi.ko
5. ls /dev/video*
6. xawtv -c /dev/videoX
如何才能知道vivi涉及到哪些系统调用
strace -o xawtv.log xawtv
二:UVC驱动框架:
UVC:usb video controll
system call: open read write
-------------------------------------------------
核心层:
source: v4l2_dev.c
struct: v4l2_device
operation: 1.分配 file_operations (v4l2_file_operations)
2.设置 file_operations (v4l2_file_operations)
2.注册 1.cdev_alloc
2.cdev->ops = v4l2_file_operations
3.cdev_add
----------------------------------------------------
硬件层:
source: uvc_driver.c
struct: video_device
operation: 1.初始化 v4l2_driver_register
2.分配 video_device_alloc
3.设置 video_device
4.注册 video_register_device
----------------------------------------------------
如何写一个v4l2驱动:
1.分配,设置,注册 v4l2_device
2.分配 video_device
3.设置
1. 将自己的video_device与v4l2核心层连接起来
video_device->v4l2_dev = v4l2_device
2. 设置自己的video_device的fops操作函数
video_device->fops = xxx_fops
video_device->ioctl_ops = xxx_ioctl
3. 设置自己的video_device的v4l2_ctrl_handler,并提交给核心层
1.v4l2_ctrl_handler_init
2.v4l2_ctrl_new_std
v4l2_ctrl_new_custom
3.v4l2_device->ctr_handler = v4l2_ctrl_handler
vivi.c 驱动框架分析:
---------------------------------------------------------------
核心层:
source: v4l2_dev.c
struct: v4l2_device
v4l2_ops(file_operations)
----------------------------------------------------------------
设备层:
source: uvc_driver.c
struct: video_device
-----------------------------------------------------------------
虚拟设备层:
source: vivi.c
struct: vivi_dev
vivi_ops(v4l2_file_operations)
vivi_ioctl_ops(v4l2_ioctl_ops)
----------------------------------------------------------------
应用程序开启摄像头,驱动ioctl被调用流程:
//可以省略的ioctl
3. ioctl(VIDIOC_G_FMT)
4. for() ioctl(VIDIOC_ENUM_FMT)
5. ioctl(VIDIOC_QUERYCAP) // 列举性能
6. ioctl(VIDIOC_G_INPUT) // 获得当前使用输入源
7. ioctl(VIDIOC_ENUMINPUT) // 列举输入源
8. ioctl(VIDIOC_QUERYCTRL) // 查询属性,比如亮度、对比度
9. ioctl(VIDIOC_QUERYCAP)
10. ioctl(VIDIOC_ENUMINPUT)
// 打开设备节点
1. fd = open
2. ioctl(fd,VIDIOC_QUERYCAP)
// 获得设备容量
3. for() ioctl(VIDIOC_ENUMINPUT) // 列举输入源,VIDIOC_ENUMINPUT/VIDIOC_G_INPUT/VIDIOC_S_INPUT不是必需的
4. for() ioctl(VIDIOC_ENUMSTD) // 列举标准(制式), 不是必需的
5. for() ioctl(VIDIOC_ENUM_FMT) // 列举格式
6. ioctl(VIDIOC_G_PARM)
7. for() ioctl(VIDIOC_QUERYCTRL) // 查询属性(比如说亮度值最小值、最大值、默认值)
// 读取属性
8. ioctl(VIDIOC_G_STD) // 获得当前使用的标准(制式), 不是必需的
9. ioctl(VIDIOC_G_INPUT)
10. ioctl(VIDIOC_G_CTRL ) // 获得当前属性, 比如亮度是多少
11. ioctl(VIDIOC_TRY_FMT) // 试试能否支持某种格式
12. ioctl(VIDIOC_S_FMT) // 设置摄像头使用某种格式
// 启动摄像头 streamon
13. ioctl(VIDIOC_REQBUFS ) // 请求系统分配缓冲区
14. for() ioctl(VIDIOC_QUERYBUF) // 查询所分配的缓冲区
mmap()
15. for() ioctl(VIDIOC_QBUF) // 把缓冲区放入队列
16. ioctl(VIDIOC_STREAMON) // 启动摄像头
// 设置属性
17. for () ioctl(VIDIOC_S_CTRL) // 设置属性
ioctl(VIDIOC_S_INPUT ) // 设置输入源
ioctl(VIDIOC_S_STD) // 设置标准(制式), 不是必需的
// 不断地读取缓冲区数据 v4l2_nextframe > v4l2_waiton
18. v4l2_queue_all
v4l2_waiton
for ()
{
select(5, [4], NULL, NULL, {5, 0}) = 1 (in [4], left {4, 985979})
ioctl(4, VIDIOC_DQBUF // de-queue, 把缓冲区从队列中取出
// 处理, 之以已经通过mmap获得了缓冲区的地址, 就可以直接访问数据
ioctl(4, VIDIOC_QBUF // 把缓冲区放入队列
}
xawtv的几大函数:
1. v4l2_open //xawtv/libng/plugins/drv0-v4l2.c
2. v4l2_read_attr/v4l2_write_attr
3. v4l2_start_streaming
4. v4l2_nextframe/v4l2_waiton
摄像头驱动程序必需的11个ioctl:
// 表示它是一个摄像头设备
.vidioc_querycap = vidioc_querycap,
/* 用于列举、获得、测试、设置摄像头的数据的格式 */
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = v
jz2440 的Linux内核vivi.c框架分析
最新推荐文章于 2021-05-06 17:39:58 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)