ov5640设备树修改
i2ctool的一些使用
文件:drivers/media/platform/mxc/capture/mx6s_capture.c是芯片CSI控制器驱动
drivers/media/platform/mxc/capture/ov5640_v2.c是摄像头配置驱动
模块安装 linux-kernel-6.12.y的ov5640驱动默认编译成的是模块,需要进行安装,当然也可直接单独运行模块或者直接编译进内核,这里使用较为正规的方式。使用如下命令会将模块自动安装到INSTALL_MOD_PATH的bin目录下,linux也会自动加载,无需手动加载。
#!/bin/sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- M=drivers/media/platform/mxc/capture modules # 编译模块 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install INSTALL_MOD_PATH=/your/rootfs/path # 安装模块 最小改动的移植,使用自带驱动的YUYV格式(不完美) 驱动部分,只需要将旧的正点原子驱动中的屏幕配置加入到新的驱动中即可,也可直加入自己屏幕对应的配置部分。一般需要在ov5640_mode添加内容,相应的添加reg_value结构体对应的数据,然后还有ov5640_mode_info_data结构体内添加对应内容。而应用层部分,需要做较大的修改,需要修改成YUYV格式的配置,并且需要进行YUYV->RGB565的转换。显示的不完美,屏幕会被分成两部分,并且左右部分进行了互换。改动部分已在注释中标出。
详细代码:https://github.com/ydteng/ov5640-driver/tree/main/YUYV
尽量跟正点原子官方原版一样的 这个改动较多,最需要注意的是ov5640_subdev_video_ops和ov5640_subdev_pad_ops的区别,别的其实还好移植。这两个的区别主要是新版本将ov5640_subdev_video_ops的一些接口放到了ov5640_subdev_pad_ops里面,并且删除了try_mbus_fmt,合并到了set_fmt使用fmt->which进行判断,具体如下:
查看代码
static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = { .g_parm = ov5640_g_parm, .s_parm = ov5640_s_parm, .g_std = ov5640_g_std, /* 也算是一个过时接口,写的很简单 */ /* 旧版本驱动这里有下面这些 .s_mbus_fmt = ov5640_s_fmt, .g_mbus_fmt = ov5640_g_fmt, .try_mbus_fmt = ov5640_try_fmt, .enum_mbus_fmt = ov5640_enum_fmt, */ }; static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = { .enum_frame_size = ov5640_enum_framesizes, .enum_frame_interval = ov5640_enum_frameintervals, /* 新版本的从v4l2_subdev_video_ops移动到了v4l2_subdev_pad_ops,变成了下面这些接口 */ .enum_mbus_code = ov5640_enum_code, /* 对应旧版本enum_mbus_fmt */ .set_fmt = ov5640_set_fmt, /* 对应旧版本s_mbus_fmt*/ .get_fmt = ov5640_get_fmt, /* 对应旧版本g_mbus_fmt */ /* 删除了try_mbus_fmt,合并到了set_fmt使用fmt->which == V4L2_SUBDEV_FORMAT_TRY进行判断, if (format->which == V4L2_SUBDEV_FORMAT_TRY){这里可以写旧版本的ov5640_try_fmt函数中的内容} */ };