Linux摄像头驱动1——vivid

优快云仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2018/03/08/Linux摄像头驱动1——vivid/#more

Linux摄像头驱动学习第一篇,对虚拟视频驱动Virtual Video Driver(vivid)进行测试、分析、编写。

V4L2(Video for Linux two)是Linux内核中关于视频设备的内核驱动框架,为上层的访问底层的视频设备提供了统一的接口。

V4L2可以支持多种设备,它可以有以下几种接口:

  1. Video capture interface(视频采集接口):从摄像头等设备上获取视频数据,是V4L2设计最初功能;
  1. Video output interface(视频输出接口):驱动计算机的外围视频、图像显示设备;
  2. Video overlay interface(直接传输视频接口):把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过CPU;
  3. Video output overlay device(视频输出覆盖设备):也被称为OSD(On-Screen Display),即在显示画面上叠加一层显示,比如菜单设置界面;
  4. VBI interface(视频间隔消隐信号接口):提供对VBI(Vertical Blanking Interval)数据的控制,它可以使应用可以访问传输消隐期的视频信号;
  5. Radio interface(收音机接口):处理从AM或FM高频头设备接收来的音频流;

1.V4L2框架分析

2.测试vivid

这里目的先加载vivid驱动,然后运行应用程序调用vivid驱动,初步体验效果。

2.1加载驱动

先在Ubuntu16.04上输入uname -a,可以得到当前Ubuntu内核版本号:

Linux ubuntu 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

当前内核版本是4.4.0-116-generic,然后去Linux内核官网下载对应的内核,提取出其中的linux-4.13.9/drivers/media/文件夹。

修改media/platform/vivid/下的Makefile:

KERN_DIR = /usr/src/linux-headers-4.4.0-116-generic

vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
		vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
		vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
		vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \
		vivid-osd.o vivid-tpg.o vivid-tpg-colors.o
		
all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-$(CONFIG_VIDEO_VIVID) += vivid.o

然后执行make编译,获得vivid.ko
此时加载模块sudo insmod vivid.ko,发现报错如下:

insmod: ERROR: could not insert module vivid.ko: Unknown symbol in module

原因是模块中的一些依赖函数的模块,没有加载,通过dmesg命令,可以看到很多函数:

[  488.786285] vivid: Unknown symbol vb2_queue_init (err 0)
[  488.786295] vivid: Unknown symbol v4l2_ctrl_poll (err 0)
[  488.786304] vivid: Unknown symbol v4l2_enum_dv_timings_cap (err 0)
[  488.786314] vivid: Unknown symbol video_ioctl2 (err 0)
[  488.786364] vivid: Unknown symbol v4l2_get_timestamp (err 0)
[  488.786389] vivid: Unknown symbol v4l2_device_put (err 0)
[  488.786418] vivid: Unknown symbol vb2_ioctl_streamoff (err 0)
…………

需要先加载这些函数所在的模块才行。
这里有两个方法:
一是找到函数对应的文件,修改Makefile,编译出来,先加载。
二是找到函数对应的文件,其实模块都已经编译好了,路径在/lib/modules/4.4.0-116-generic/kernel/drivers/media/v4l2-core/里面,直接加载即可。

这两种方式都需要慢慢找对应的文件,比较麻烦,直接:

sudo modprobe vivid     //安装自带vivid及依赖
sudo rmmod vivid        //卸载自带的vivid
sudo insmod ./vivid.ko  //安装自己编译的vivid.ko 

这里先使用modprobr加载vivid,会将其依赖一并加载,然后再卸载vivid,最后加载上我们编译的vivid.ko

这里为什么使用自己编译的vivid.ko,而不使用自带的?
因为后面修改vivid源码后,重新加载修改后的驱动,才知道修改后的效果。

2.2应用程序

Linux摄像头测试软件webcam、spcaview、luvcview、xawtv等,经测试,luvcviewxawtv比较靠谱。

luvcview -h             //帮助信息
luvcview -d /dev/videoX //指定设备
luvcview -L             //查询当前摄像头所支持的所有数据格式以及分辨率信息 
luvcview                //运行摄像头
xawtv -h                //帮助信息
xawtv -c /dev/videoX    //指定设备
xawtv -noalsa           //关闭声卡启动
xawtv                   //运行摄像头

这里加载vivid驱动后,运行xawtv效果如下:

3.分析vivid

第一次接触V4L2,直接对内核提供的Virtual Video Driver(vivid)进行分析,只要熟悉了vivid,后续再对摄像头再进行分析,就会轻松很多。

vivid是内核提供的一个虚拟机的视频设备驱动,内核提供的vivid源码在linux-4.13.9/drivers/media/platform/vivid/

3.1 初始化、注册分析

vivid_init()里分别注册了vivid_pdevvivid_pdrv,注册后,由于两者name一致,则会调用probe()。在probe()里面主要进行初始化、注册等相关流程。

可以看到,在probe()里,会调用vivid_create_instance(),让后在里面先分配一个video_device,然后设置video_device,包括操作函数opsioctl操作函数,设备等。
然后对ctrl属性进行详细的设置,最后注册video_device,和进行常规的字符设备注册。

因此,写摄像头驱动程序的流程如下:

  1. 分配video_device:video_device_alloc()kzalloc()
  1. 设置video_device:.fops.ioctl_opsdev
  2. 注册video_device: video_register_device()

3.2 操作函数分析

再来看看操作函数是如何调用的:

当应用层open()/read()/write()操作/dev/videox时,先找到v4l2_fops
然后调用v4l2_open/v4l2_read/v4l2_write(driver

### 如何在Linux系统中配置和使用工业摄像头 要在Linux系统中成功配置和使用工业摄像头,通常需要完成以下几个方面的设置: #### 1. 安装必要的软件包和支持库 对于大多数工业摄像头来说,`V4L2`(Video for Linux 2)是一个重要的接口标准。可以通过安装 `v4l-utils` 工具来测试和调试摄像头设备[^1]。 ```bash sudo apt-get update sudo apt-get install v4l-utils ``` 如果目标是特定品牌的工业摄像头(如 Imaging Source),可能还需要额外的支持库或工具链。例如,在某些情况下,需要通过 `tcambin` 和 GStreamer 来管理摄像头流数据[^3]。 #### 2. 下载并编译合适的驱动程序 现代Linux内核已经内置了许多常见硬件的驱动支持。然而,针对一些专用工业摄像头,可能仍需手动下载并编译对应的驱动模块。以下是通用流程: - **获取最新源码** 访问官方文档或者社区资源页面,找到适用于当前内核版本的驱动代码。 - **准备开发环境** ```bash sudo apt-get install build-essential linux-headers-$(uname -r) ``` - **编译与加载驱动** 假设已获得名为 `vivid.ko` 的虚拟摄像头驱动文件,则可通过以下命令动态加载: ```bash insmod vivid.ko dmesg | grep vivid ``` 注意:从早期的Linux 2.6.x升级至较新的4.x系列时,部分API定义可能会发生变化,因此务必仔细阅读更新日志以及迁移指南[^1]。 #### 3. 测试摄像头连接状态 利用之前提到过的 `v4l-utils` 提供的小型应用程序验证物理链接是否正常工作。 ```bash v4l2-ctl --list-devices ffmpeg -f video4linux2 -i /dev/video0 output.mp4 ``` #### 4. 实现图像采集与处理逻辑 当基本通信路径建立完毕之后,下一步就是编写具体应用层代码来进行实时捕获、编码传输等功能实现了。这里推荐借助开源多媒体框架——GStreamer简化这一过程[^3]。 示例脚本如下所示: ```python import gi gi.require_version('Gst', '1.0') from gi.repository import Gst def main(): Gst.init(None) pipeline = Gst.parse_launch(""" tcambin name=source ! videoconvert ! autovideosink """) source = pipeline.get_by_name("source") ret = source.set_property("serial", "your_camera_serial_number_here") if not ret: print("Failed to set property.") exit(-1) pipeline.set_state(Gst.State.PLAYING) if __name__ == "__main__": main() ``` 以上Python片段展示了如何结合GStreamer插件创建简单的视频预览窗口[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值