报错记录1:imx6ull适配ov2640摄像头报错unknown mbus:xxx或rgb取流异常

报错内容

[  376.346236] unknown mbus:0x1007
[  376.350166] mx6s-csi 21c4000.csi: mbus (0x00001007) invalid.

报错代码

在mx6s_capture.c文件中,找到此行报错的调用路径。

static int mx6s_vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
				       struct v4l2_fmtdesc *f)
/* 省略部分代码 */
	fmt = format_by_mbus(code);
	if (!fmt) {
		dev_err(csi_dev->dev, "mbus (0x%08x) invalid.\n", code);
		return -EINVAL;
	}
/* 省略部分代码 */
}
struct mx6s_fmt *format_by_mbus(u32 code)
{
	int i;

	for (i = 0; i < NUM_FORMATS; i++) {
		if (formats[i].mbus_code == code)
			return formats + i;
	}

	pr_err("unknown mbus:0x%x\n", code);
	return NULL;
}

static struct mx6s_fmt formats[] = {
	{
		.name		= "UYVY-16",
		.fourcc		= V4L2_PIX_FMT_UYVY,
		.pixelformat	= V4L2_PIX_FMT_UYVY,
		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
		.bpp		= 2,
	}, {
/* 省略部分代码 */
};

报错原因

unknown mbus报错的原因是由于上层代码在调用ioctl(fd, VIDIOC_ENUM_FMT, fmtdesc)后,
mx6s_capture驱动会调用ov2640驱动的ov2640_enum_fmt接口,
但ov2640接口返回的格式类型在mx6s_capture中未定义。

/* ov2640支持的图像格式类型 */
static u32 ov2640_codes[] = {
	MEDIA_BUS_FMT_YUYV8_2X8,
	MEDIA_BUS_FMT_UYVY8_2X8,
	MEDIA_BUS_FMT_RGB565_2X8_BE,
	MEDIA_BUS_FMT_RGB565_2X8_LE,
};

/* mx6s_capture中定义的格式类型中没有 下面这两项*/
#define MEDIA_BUS_FMT_RGB565_2X8_BE		0x1007
#define MEDIA_BUS_FMT_RGB565_2X8_LE		0x1008

解决

在mx6s_capture.c中找到以下结构体,添加ov2640所需的两个格式类型参数。

static struct mx6s_fmt formats[] = {
/* 省略部分代码 */
	{
		.name		= "RGB565_LE",
		.fourcc		= V4L2_PIX_FMT_RGB565,
		.pixelformat	= V4L2_PIX_FMT_RGB565,
		.mbus_code	= MEDIA_BUS_FMT_RGB565_2X8_LE,
		.bpp		= 2,
	}, {
		.name		= "RGB565_BE",
		.fourcc		= V4L2_PIX_FMT_RGB565X,
		.pixelformat	= V4L2_PIX_FMT_RGB565X,
		.mbus_code	= MEDIA_BUS_FMT_RGB565_2X8_BE,
		.bpp		= 2,
	}
};

解决RGB取流异常或取流时LCD花屏

异常现象

使用OV2640取流时,如果同时使用了LCD屏幕,则可能在取流时,LCD花屏。
原因是由于设置RGB565格式的配置时,CSI接口配置没有RGB565相关的配置,因此造成了内存分配异常,可能与LCD的显存出现重叠现象,因此取帧时,显存遭到破坏,LCD会花屏。

解决方法

找到static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev)接口,添加两个switch的case

static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev)
{

/* 省略部分代码 */

	switch (csi_dev->fmt->pixelformat) {

/* 省略部分代码 */
	case V4L2_PIX_FMT_UYVY:
	case V4L2_PIX_FMT_YUYV:
	
	/* 添加下面这两行 */
	case V4L2_PIX_FMT_RGB565:
	case V4L2_PIX_FMT_RGB565X:
	/***********************/
	case V4L2_PIX_FMT_JPEG:
		if (csi_dev->csi_mux_mipi == true)
			width = pix->width;
		else
			/* For parallel 8-bit sensor input */
			width = pix->width * 2;
		break;
	default:
全志R16平台 parrotv1.1(Android4.4.2) /* * Store information about the video data format. */ static struct sensor_format_struct { __u8 *desc; //__u32 pixelformat; enum v4l2_mbus_pixelcode mbus_code;//linux-3.0 struct regval_list *regs; int regs_size; int bpp; /* Bytes per pixel */ } sensor_formats[] = { //{ // .desc = "YUYV 4:2:2", // .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,//linux-3.0 // .regs = sensor_fmt_yuv422_yuyv, // .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yuyv), // .bpp = 2, //}, //{ // .desc = "YVYU 4:2:2", // .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,//linux-3.0 // .regs = sensor_fmt_yuv422_yvyu, // .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yvyu), // .bpp = 2, //}, { .desc = "UYVY 4:2:2", .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,//linux-3.0 .regs = sensor_fmt_yuv422_uyvy, .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_uyvy), .bpp = 2, }, //{ // .desc = "VYUY 4:2:2", // .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,//linux-3.0 // .regs = sensor_fmt_yuv422_vyuy, // .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_vyuy), // .bpp = 2, //}, //{ // .desc = "Raw RGB Bayer", // .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,//linux-3.0 // .regs = sensor_fmt_raw, // .regs_size = ARRAY_SIZE(sensor_fmt_raw), // .bpp = 1 //}, }; #define N_FMTS ARRAY_SIZE(sensor_formats) /* * Then there is the issue of window sizes. Try to capture the info here. */ static struct sensor_win_size sensor_win_sizes[] = { // /* UXGA */ // { // .width = UXGA_WIDTH, // .height = UXGA_HEIGHT, // .hoffset = 0, // .voffset = 0, // .regs = sensor_uxga_regs, // .regs_size = ARRAY_SIZE(sensor_uxga_regs), // .set_size = NULL, // }, //// /* 720p */ //// { //// .width = HD720_WIDTH, //// .height = HD720_HEIGHT, //// .hoffset = 0, //// .voffset = 0, //// .regs = Gc2015_sensor_hd720_regs, //// .regs_size = ARRAY_SIZE(Gc2015_sensor_hd720_regs), //// .set_size = NULL, //// }, // /* SVGA */ // { // .width = SVGA_WIDTH, // .height = SVGA_HEIGHT, // .hoffset = 0, // .voffset = 0, // .regs = sensor_svga_regs, // .regs_size = ARRAY_SIZE(sensor_svga_regs), // .set_size = NULL, // }, // /* VGA */ // { // .width = VGA_WIDTH, // .height = VGA_HEIGHT, // .hoffset = 0, // .voffset = 0, // .regs = sensor_vga_regs, // .regs_size = ARRAY_SIZE(sensor_vga_regs), // .set_size = NULL, // }, /* VGA */ { .width = VGA_WIDTH, .height = VGA_HEIGHT, .hoffset = 0, .voffset = 0, .regs = sensor_default_regs, .regs_size = ARRAY_SIZE(sensor_default_regs), .set_size = NULL, }, };
你好!对于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、付费专栏及课程。

余额充值