打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Camera Driver Intro
1.Shark camera driver架构
l  HAL层调用camera_init_internal()对sensor,v4l2,preview,capture等初始化,初始化时创建各自的处理线程。
int (uint32_t camera_id)
{
struct camera_ctrl       *ctrl = &g_cxt->control;
int                      ret = CAMERA_SUCCESS;
CMR_PRINT_TIME;
ret = camera_sensor_init(camera_id);
if (ret) {
CMR_LOGE("Failed to init sensor %d", ret);
goto exit;
}
CMR_PRINT_TIME;
ret = camera_v4l2_init();
if (ret) {
CMR_LOGE("Failed to init V4L2 manager %d", ret);
goto sensor_deinit;
}
ret = camera_cap_thread_init();
if (ret) {
CMR_LOGE("Failed to init capture manager %d", ret);
goto cb_deinit;
}
ret = camera_prev_thread_init();
if (ret) {
CMR_LOGE("Failed to init preview manager %d", ret);
goto cap_sub_deinit;
}
}
2. V4L2
1)Intro
在Linux中,摄像头方面的标准化程度比较高,这个标准就是V4L2驱动程序,这也是业界比较公认的方式。
V4L全称是Video for Linux,是Linux内核中标准的关于视频驱动程序,目前使用比较多的版本是Video for Linux 2,简称V4L2。它为Linux下的视频驱动提供了统一的接口,使得应用程序可以使用统一的API操作不同的视频设备。从内核空间到用户空间,主要的数据流和控制类均由V4L2驱动程序的框架来定义。
V4L2驱动程序一般只提供Video数据的获得,而如何实现视频预览,如何向上层发送数据,如何把纯视频流和取景器、视频录制等实际业务组织起来,都是camera的硬件抽象层需要负责的工作。
V4L2驱动核心实现为如下文件:drivers/media/video/v4l2-dev.c。
V4l2-dev.h中定义的video_device是V4L2驱动程序的核心数据结构,它为具体的摄像头sensor驱动提供了接口调用。
V4l2的采集过程(应用程序):
1)打开设备,获得文件描述符
2)检查和设置设备属性
3)设置帧格式
4)设置一种输入输出方法(缓冲区管理)
5)循环获取数据
6)停止采集,关闭设备
针对上图的流程:
1.  由v4l2驱动框架注册底层字符设备驱动程序/dev/videoX
2.  用户层通过设备接口/dev/videoX打开v4l2设备
3.  通过设备接口/dev/videoX控制camera设备
l  调用v4l2驱动核心
l  V4l2驱动核心调用具体V4l2驱动(DCAM设备驱动)
l  DCAM设备驱动通过硬件操作控制camera硬件接口控制器DCAM
2)数据结构
V4L2的主要数据结构是video_device,定义在v4l2_dev.h中:
struct video_device
{
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
#endif
/* device ops */
const struct v4l2_file_operations *fops;
/* sysfs */
struct device dev;  /* v4l device */
struct cdev *cdev;  /* character device */
/* Set either parent or v4l2_dev if your driver uses v4l2_device */
struct device *parent;  /* device parent */
struct v4l2_device *v4l2_dev; /* v4l2_device parent */
/* Control handler associated with this device node. May be NULL. */
struct v4l2_ctrl_handler *ctrl_handler;
/* Priority state. If NULL, then v4l2_dev->prio will be used. */
struct v4l2_prio_state *prio;
/* device info */
char name[32];
int vfl_type;
/* 'minor' is set to -1 if the registration failed */
int minor;
u16 num;
/* use bitops to set/clear/test flags */
unsigned long flags;
/* attribute to differentiate multiple indices on one physical device */
int index;
/* V4L2 file handles */
spinlock_t  fh_lock; /* Lock for all v4l2_fhs */
struct list_head fh_list; /* List of struct v4l2_fh */
int debug;   /* Activates debug level*/
/* Video standard vars */
v4l2_std_id tvnorms;  /* Supported tv norms */
v4l2_std_id current_norm; /* Current tvnorm */
/* callbacks */
void (*release)(struct video_device *vdev);
/* ioctl callbacks */
const struct v4l2_ioctl_ops *ioctl_ops;
/* serialization lock */
struct mutex *lock;
};
3)主要接口函数
int video_register_device(struct video_device *vdev, int type, int nr);
注册字符设备/dev/videoX
static int v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
v4l2的控制接口,最终调用dcam实现的回调
3. DCAM
1)Intro
DCAM模块是SHARK中的camera硬件控制接口,主要关心以下几个方面:
1.  对从sensor采集的数据进行处理、转换以及输出
2.  支持CCIR和MIPI接口
3.  代码实现上,DCAM和V4L2紧密相关,由DCAM实现V4L2框架中的各个接口,而上层代码利用V4L2提供的接口来控制和处理数据,实际上最终是由DCAM来控制和处理。
2)接口方式:
1.Shark前置摄像头使用的ccir并行接口:
2.Shark后置摄像头使用的MIPI-CSI2接口连接sensor:
3)DCAM驱动的代码关系:
DCAM的驱动实现了v4l2所有的接口,dcam_v4l2.c里面注册了很多的回调函数,都是用于实现v4l2的标准接口的.
DCAM的驱动在内核中的位置:drivers/media/video/sprd_dcam/sc8830它包含下边的文件:
dcam_drv_sc8830.c
dcam的具体实现
dcam_v4l2.c
dcam的v4l2的接口
csi2目录
mipi接口驱动
上层进行preview时,HAL,V4L2,DCAM以及Sensor各层代码,它们之间的调用关系如下:
4) DCAM驱动初始化
1. 在SHARK中,DCAM作为平台设备进行管理,初始设置代码在 kernel\arch\arm\mach-sc\devices-sc8830.c,其中定义了平台设备:
struct platform_device sprd_dcam_device = {
.name  = "sprd_dcam",
.id  = 0,
.num_resources = ARRAY_SIZE(sprd_dcam_resources),
.resource = sprd_dcam_resources,
};
2. 并在kernel\arch\arm\mach-sc\board-sp8830ssd.c中注册平台设备sprd_dcam_device。
3. 最后DCAM module加载时在dcam_v4l2.c中由platform_driver_register()注册dcam驱动,驱动和设备进行绑定到内核。
int __init dcam_v4l2_init(void)
{
int ret = 0, i;
if (platform_driver_register(&dcam_driver) != 0) {
printk("platform device register Failed \n");
return -1;
}
printk(KERN_INFO "Video Technology Magazine Virtual Video "
"Capture Board ver %u.%u.%u successfully loaded.\n",
(DCAM_VERSION >> 16) & 0xFF, (DCAM_VERSION >> 8) & 0xFF,
DCAM_VERSION & 0xFF);
return ret;
}
5) 数据结构
DCAM的主要数据结构dcam_dev:
struct dcam_dev {
struct list_head dcam_devlist;
struct v4l2_device v4l2_dev;
spinlock_t slock;
struct mutex lock;
atomic_t users;
/* various device info */
struct video_device *vfd;
struct dcam_dmaqueue vidq;
/* Several counters */
int h, m, s, ms;
unsigned long jiffies;
char timestr[13];
int mv_count;  /* Controls bars movement */
/* Input Number */
int input;
/* Control 'registers' */
int qctl_regs[ARRAY_SIZE(dcam_qctrl)];
struct v4l2_streamparm streamparm;
};
DCAM控制器在驱动里使用了下面结构来描述:
LOCAL struct video_device sprd_v4l2_template = {
.name                    = "dcam",
.fops                    = &sprd_v4l2_fops,
.ioctl_ops               = &sprd_v4l2_ioctl_ops,
.minor                   = -1,
.release                 = video_device_release,
.tvnorms                 = V4L2_STD_525_60,
.current_norm            = V4L2_STD_NTSC_M,
};
fops结构体是针对v4l2设备的基本操作,定义如下:
LOCAL const struct v4l2_file_operations sprd_v4l2_fops = {
.owner                   = THIS_MODULE,
.open                    = sprd_v4l2_open,
.read                    = sprd_v4l2_read,
.release                 = sprd_v4l2_close,
.write                   = sprd_v4l2_write,
.ioctl                   = video_ioctl2, /* V4L2 ioctl handler */
};
cmr_v4l2_init()中打开v4l2设备:
fd = open(“/dev/video0”, O_RDWR, 0)-> sprd_v4l2_open()
6)接口函数
DCAM的主要回调函数如下,在dcam_v4l2.c中实现v4l2框架中的各个接口函数:
LOCAL const struct v4l2_ioctl_ops sprd_v4l2_ioctl_ops = {
.vidioc_g_parm                = v4l2_g_parm,
.vidioc_s_parm                = v4l2_s_parm,
.vidioc_querycap              = v4l2_querycap,
.vidioc_cropcap               = v4l2_cropcap,
.vidioc_s_crop                = v4l2_s_crop,
.vidioc_enum_fmt_vid_cap      = v4l2_enum_fmt_vid_cap,
.vidioc_enum_fmt_type_private = v4l2_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap         = v4l2_g_fmt_vid_cap,
.vidioc_g_fmt_type_private    = v4l2_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap       = v4l2_try_fmt_vid_cap,
.vidioc_try_fmt_type_private  = v4l2_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap         = v4l2_s_fmt_vid_cap,
.vidioc_qbuf                  = v4l2_qbuf,
.vidioc_dqbuf                 = v4l2_dqbuf,
.vidioc_streamon              = v4l2_streamon,
.vidioc_streamoff             = v4l2_streamoff,
.vidioc_g_crop                = v4l2_g_crop,
.vidioc_g_output              = v4l2_g_output,
.vidioc_s_ctrl                = v4l2_s_ctrl,
.vidioc_g_fmt_vid_out         = v4l2_g_fmt_vid_out,
.vidioc_enum_fmt_vid_out      = v4l2_enum_fmt_vid_cap,
.vidioc_try_fmt_vid_out       = v4l2_try_fmt_vid_cap
};
HAL层cmr_v4l2.c中的控制接口ioctl()根据不同参数通过v4l2-ioctl.c的控制,最终调用上面对应的回调函数,以完成对dcam的控制。
4.  Sensor驱动
1) 驱动三大步
l  摄像头的上电、时钟这些基本条件;
l  I2C保证摄像头的初始化;
l  摄像头工作后传回数据到Camera控制器DCAM。
2) 主要涉及文件
sensor_drv_u.c
用户层的sensor接口,封装sensor_srv_k.c,提供对上接口
sensor_s5k4ecgx_mipi.c
l  具体摄像头驱动-后置
l  用户层驱动,分离于内核层sensor_srv_k.c内核驱动,便于开发和调试
l  Sensor寄存器的读写以实现具体camera功能
sensor_hi702_ccir.c
同上,前置摄像头
sensor_drv_k.c
l  sensor的内核驱动模块,作为platform驱动管理
l  初始化、控制sensor,具体功能包括:
n  上下电
n  设置时钟
n  配置I2C,I2C读写
n  控制闪光灯
l  通过/dev/sprd_sensor提供用户层访问接口
3) 调用关系
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
android从应用到驱动之
V4L2驱动的移植与应用(一)
camera flow notes at 20130523
linux3.3 v4l2视频采集驱动框架(vfe, camera i2c driver,v4l2
android camera(三):camera V4L2 FIMC
FS_S5PC100平台上Linux Camera驱动开发详解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服