视频监控—根据虚拟驱动vivi的使用过程彻底分析摄像头驱动
- 硬件平台:韦东山嵌入式Linxu开发板(S3C2440.v3)
- 软件平台:运行于VMware Workstation 12 Player下UbuntuLTS16.04_x64 系统
- 参考资料:Video for Linux Two - Driver Writer’s Guide、《Android驱动开发权威指南》
- 开发环境:Linux 3.4.2内核、arm-linux-gcc 4.3.2工具链
- 源码仓库:https://gitee.com/d_1254436976/Embedded-Linux-Phase-3
一、虚拟驱动vivi测试
- 在Ubuntu虚拟机上安装xawtv,执行
uname -a
确实ubuntu的内核版本; - 去www.kernel.org下载同版本的内核,解压后把
/drivers/media/video
目录取出,修改它的Makefile为:
KERN_DIR = /usr/src/linux-headers-"内核版本"-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
- 执行
make
进行编译 - 加载驱动
sudo modprobe vivi
、sudo rmmod vivi
、sudo insmod ./vivi.ko
- 查看对应的设备节点
ls /dev/video*
- 执行
xawtv -c /dev/videoX
,启动测试vivi
二、根据log分析摄像头驱动
执行,打印出vivi使用时的xawtv.log
,从中彻底分析摄像头驱动。
由于log信息过多,只挑选出对应部分,由于vivi对应的设备节点为/dev/event0
,在日志搜索/dev/event0
,得到以下有用信息。
open("/dev/video0", O_RDWR|O_LARGEFILE) = 4
ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0xbfaccd44) = 0
ioctl(4, VIDIOC_G_FMT or VT_SENDSIG, 0xbfaccc78) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0
ioctl(4, 0xc02c564a, 0xbfaccb58) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0
ioctl(4, 0xc02c564a, 0xbfaccb58) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0
ioctl(4, 0xc02c564a, 0xbfaccb58) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbfaccbec) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0xbfaccb84) = 0
ioctl(4, VIDIOC_G_INPUT, 0xbfacca2c) = 0
ioctl(4, VIDIOC_ENUMINPUT, 0xbfacca2c) = 0
fstat64(4, {
st_mode=S_IFCHR|0660, st_rdev=makedev(81, 0), ...}) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0xbfacca78) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0x9b40998) = 0
fcntl64(4, F_SETFD, FD_CLOEXEC) = 0
ioctl(4, VIDIOC_ENUMINPUT, 0x9b40acc) = 0
ioctl(4, VIDIOC_ENUMINPUT, 0x9b40b18) = 0
ioctl(4, VIDIOC_ENUMINPUT, 0x9b40b64) = 0
ioctl(4, VIDIOC_ENUMINPUT, 0x9b40bb0) = 0
ioctl(4, VIDIOC_ENUMINPUT, 0x9b40bfc) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_ENUMSTD, 0x9b40f8c) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b40fcc) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b4100c) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b4104c) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b4108c) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b410cc) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b4110c) = 0
ioctl(4, VIDIOC_ENUMSTD, 0x9b4114c) = -1 EINVAL (Invalid argument)
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4138c) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b413cc) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4140c) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4144c) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b4148c) = 0
ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x9b414cc) = 0
ioctl(4, VIDIOC_G_PARM, 0x9b40a00) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41b8c) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41bd0) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41c14) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41c58) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41c9c) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41ce0) = 0
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41d24) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41d68) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41dac) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41df0) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41e34) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41e78) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41ebc) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41f00) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41f44) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41f88) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b41fcc) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42010) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42054) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42098) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b420dc) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42120) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b42164) = -1 EINVAL (Invalid argument)
ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x9b421a8) = -1 EINVAL (Invalid argument