报错记录3:imx6ull适配ov2640摄像头无法获取默认摄像头分辨率与格式参数

报错现象1

应用在设备启动后首次调用ioctl(fd, VIDIOC_G_FMT, &dev->cur_fmt);获取摄像头默认参数时,获取到的值全为零

报错原因

mx6s_capture驱动中,VIDIOC_G_FMT命令对应的接口为mx6s_vidioc_g_fmt_vid_cap,此接口中,参数从csi_dev 中获取,但首次启动,在没有调用VIDIOC_S_FMT前,csi_dev 参数中关于分辨率与视频格式的参数初始为0,因此函数返回的数据都为0。

static int mx6s_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
				    struct v4l2_format *f)
{
	struct mx6s_csi_dev *csi_dev = video_drvdata(file);
	WARN_ON(priv != file->private_data);
	f->fmt.pix = csi_dev->pix;
	return 0;
}

解决方法

解决方法就是在此接口中,调用ov2640驱动中的ov2640_g_fmt接口,获取当前真实的参数信息,并将其返回给上层应用。
修改后的函数如下

static int mx6s_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
				    struct v4l2_format *f)
{
	struct mx6s_csi_dev *csi_dev = video_drvdata(file);
	struct v4l2_subdev *sd = csi_dev->sd;
	struct v4l2_mbus_framefmt mbus_fmt;
	struct mx6s_fmt *fmt;
	int ret;

	WARN_ON(priv != file->private_data);

	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
	if (ret == 0) {
		csi_dev->pix.width     = mbus_fmt.width;
		csi_dev->pix.height    = mbus_fmt.height;
		csi_dev->pix.field     = mbus_fmt.field;

		fmt = format_by_mbus(mbus_fmt.code);
		if (!fmt) {
			dev_err(csi_dev->dev, "mbus (0x%08x) invalid.\n", mbus_fmt.code);
		} else {
			csi_dev->pix.pixelformat = fmt->pixelformat;
		}
	}

	f->fmt.pix = csi_dev->pix;

	return 0;
}

报错现象2

应用层在调用ioctl(fd, VIDIOC_G_FMT, &dev->cur_fmt);接口时,无法返回修改后的视频流格式pixelformat参数,pixelformat参数会被清零。

原因

其原因为应用层调用VIDIOC_S_FMT命令后,没有将当前的格式信息更新到csi_dev 参数中,造成VIDIOC_G_FMT命令无法获取到真实的参数信息,VIDIOC_S_FMT对应的驱动层调用接口为mx6s_vidioc_s_fmt_vid_cap, 此接口在mx6s_vidioc_try_fmt_vid_cap中,设置摄像头的分辨率与格式等参数,同时会将设置后的参数值通过实参f反出来,但是调用完成后,代码并没有将pixelformat的数据写入。

解决方法

修改mx6s_vidioc_s_fmt_vid_cap函数,将真实的格式参数更新到csi_dev 中,修改后的函数如下。

static int mx6s_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
				    struct v4l2_format *f)
{
	struct mx6s_csi_dev *csi_dev = video_drvdata(file);
	int ret;

	ret = mx6s_vidioc_try_fmt_vid_cap(file, csi_dev, f);
	if (ret < 0)
		return ret;

	csi_dev->fmt           = format_by_fourcc(f->fmt.pix.pixelformat);
	csi_dev->mbus_code     = csi_dev->fmt->mbus_code;
	csi_dev->pix.width     = f->fmt.pix.width;
	csi_dev->pix.height    = f->fmt.pix.height;
	csi_dev->pix.sizeimage = f->fmt.pix.sizeimage;
	csi_dev->pix.field     = f->fmt.pix.field;
	csi_dev->type          = f->type;
	dev_dbg(csi_dev->dev, "set to pixelformat '%4.6s'\n",
			(char *)&csi_dev->fmt->name);

	/* Config csi */
	mx6s_configure_csi(csi_dev);

	return 0;
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你好!对于imx6ull摄像头驱动ov2640,您可以按照以下步骤进行配置和驱动: 1. 首先,确保您的imx6ull开发板已经正确连接了ov2640摄像头模块。 2. 在Linux系统中,您需要检查并确保i2c总线已经启用。可以通过命令`ls /dev/i2c*`来查看是否存在i2c设备。 3. 安装v4l2工具包,可以通过以下命令安装: ``` sudo apt-get install v4l-utils ``` 4. 下载并编译ov2640驱动源码。您可以从官方网站或GitHub上找到适用于imx6ullov2640驱动源码。 5. 在编译驱动之前,您需要为imx6ull配置适当的内核选项。打开内核配置文件(位于`/path/to/linux/source/.config`),确保以下选项已启用: ``` CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_VIDEO_V4L2=y CONFIG_V4L2_MEM2MEM_DEV=y CONFIG_VIDEOBUF2_DMA_CONTIG=y CONFIG_VIDEOBUF2_DMA_SG=y ``` 6. 编译驱动代码并生成ko文件。根据驱动源码提供的说明进行编译,并生成ov2640.ko文件。 7. 将生成的ov2640.ko文件复制到imx6ull开发板上。 8. 使用`insmod`命令加载驱动: ``` sudo insmod ov2640.ko ``` 9. 确认驱动已成功加载并工作。您可以使用v4l2-ctl命令来测试摄像头: ``` v4l2-ctl -d /dev/video0 --list-formats-ext ``` 以上是一般的步骤,具体的驱动配置和编译过程可能因您使用的Linux发行版和驱动源码而有所不同。请确保在操作之前参考相关文档和指南。祝您成功驱动imx6ull摄像头ov2640!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌新程序猿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值