關鍵詞:
android ?camera CMM 模組 camera參數 ?CAMIF ? V4L2 ?
平臺信息: 內核:
linux
系統:
android
平臺: S5PV310(samsung exynos 4210)?
作者:xubin341719(歡迎轉載,請注明作者)
android camera(一):camera模組CMM介紹
android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF)
android camera(三):camera V4L2 FIMC
android camera(四):camera 驅動 GT2005
下載:常用攝像頭規格書(個別有android驅動程序)? :bf3703 30W、gc0308 30W、ov7670、gt2005 200W、gt2015 200W、NT99250 200W、s5k5ba 200W、s5k4ba
????????? 前面兩篇說的有點多了,不過多了解點東西也挺好的,遇到問題時可以有更多的思路,真正驅動是從這一塊開始。一般BSP的camera都是完好的,我們只用關心驅動這些就可以了。
1. V4L2
1)簡介
??????? 在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)???? 停止采集,關閉設備。
?
2)數據結構
V4L2的主要數據結構是video_device,定義在v4l2_dev.h中:
[cpp] ?view plaincopy
struct ?video_device?? {?? ?????? ????const ? struct ?v4l2_file_operations?*fops;?? ?? ?? ?????? ????struct ?device?dev;?????? ?? ????struct ?cdev?*cdev;?????? ?? ?? ?????? ????struct ?device?*parent;?????? ?? ????struct ?v4l2_device?*v4l2_dev;??? ?? ?? ?????? ????char ?name[32];?? ?? ????int ?vfl_type;?? ?????? ????int ?minor;???? ?? ????u16?num;?? ?????? ????unsigned?long ?flags;?? ?????? ????int ?index;?? ?? ?????? ????spinlock_t??????fh_lock;??? ????struct ?list_head????fh_list;? ?? ?? ????int ?debug;?????????? ?? ?? ?????? ????v4l2_std_id?tvnorms;?????????? ????v4l2_std_id?current_norm;????? ?? ?????? ????void ?(*release)( struct ?video_device?*vdev);?? ?? ?????? ????const ? struct ?v4l2_ioctl_ops?*ioctl_ops;????? };??
主要接口函數有:
intvideo_register_device(struct video_device *vdev, int type, int nr);
static intv4l2_ioctl(struct inode *inode, struct file *filp,?????? unsigned int cmd, unsigned long arg);
2. ?FIMC?????????????????????
1)簡介
FIMC這個模塊不僅僅是一個攝像頭的控制接口,它還承擔著V4L2的output功能和overlay的功能。
FIMC的驅動在內核中的位置:drivers/media/video/samsung/fimc
它包含下邊的文件:
??????fimc_regs.c ????????fimc_capture.c ????????fimc_dev.c ????????fimc_output.c ????????fimc_overlay.c ????????fimc_v4l2.c
它們的組織關系如下:
可以看到,FIMC的驅動實現了v4l2所有的接口,可以分為v4l2-input設備接口,v4l2-output設備接口以及v4l2-overlay設備接口。這里我們主要關注v4l2-input設備接口,因為攝像頭屬于視頻輸入設備。
fimc_v4l2.c里面注冊了很多的回調函數,都是用于實現v4l2的標準接口的,但是這些回調函數基本上都不是在fimc_v4l2.c里面實現的,而是有相應的.c分別去實現。比如:
v4l2-input設備的操作實現:fimc_capture.c ????????v4l2-output設備的操作實現: fimc_output.c ????????v4l2-overlay設備的操作實現: fimc_overlay.c
這些代碼其實都是和具體硬件操作無關的,這個驅動把所有操作硬件寄存器的代碼都寫到一個文件里面了,就是fimc40_regs.c。這樣把硬件相關的代碼和硬件無關的代碼分開來實現是非常好的方式,可以最大限度的實現代碼復用。
?2) 數據結構?
?
FIMC的主要數據結構fimc_control,定義在fimc.h中:
[cpp] ?view plaincopy
struct ?fimc_control?{?? ????int ?????????????id;????? ?? ????char ????????????????name[16];?? ????atomic_t????????????in_use;?? ????void ?__iomem????????????*regs;?????? ?? ????struct ?clk??????????*clk;??????? ?? ????struct ?regulator????*regulator;????? ?? ????struct ?fimc_meminfo?????mem;???????? ?? ?? ?????? ????struct ?mutex????????????lock;??????? ?? ????struct ?mutex????????????alloc_lock;?? ????struct ?mutex????????????v4l2_lock;?? ????wait_queue_head_t???????wq;?? ????struct ?device???????????*dev;?? ????int ?????????????irq;?? ?? ?????? ????struct ?video_device?????*vd;?? ????struct ?v4l2_device??????v4l2_dev;?? ?? ?????? ????struct ?fimc_limit???????*limit;????? ?? ????struct ?s3c_platform_camera??*cam;??????? ?? ????struct ?fimc_capinfo?????*cap;??????? ?? ????struct ?fimc_outinfo?????*out;??????? ?? ????struct ?fimc_fbinfo??????fb;????? ?? ????struct ?fimc_scaler??????sc;????? ?? ????struct ?fimc_effect??????fe;????? ?? ?? ????enum ?fimc_status????????status;?? ????enum ?fimc_log???????????log;?? ?? ????u32?????????????ctx_busy[FIMC_MAX_CTXS];?? };??
因為FIMC
一共有三套一樣的控制器(fimc0, fimc1, fimc2),所以驅動里使用了一個數組來描述:
[cpp] ?view plaincopy
struct ?video_device?fimc_video_device[FIMC_DEVICES]?=?{?? ????[0]?=?{?? ????????.fops?=?&fimc_fops,?? ????????.ioctl_ops?=?&fimc_v4l2_ops,?? ????????.release?=?fimc_vdev_release,?? ????},?? ????[1]?=?{?? ????????.fops?=?&fimc_fops,?? ????????.ioctl_ops?=?&fimc_v4l2_ops,?? ????????.release?=?fimc_vdev_release,?? ????},?? ????[2]?=?{?? ????????.fops?=?&fimc_fops,?? ????????.ioctl_ops?=?&fimc_v4l2_ops,?? ????????.release?=?fimc_vdev_release,?? ????},?? };??
fb_ops結構體是針對v4l2設備的基本操作,定義如下:
[cpp] ?view plaincopy
static ? const ? struct ?v4l2_file_operations?fimc_fops?=?{?? ????.owner??????=?THIS_MODULE,?? ????.open???????=?fimc_open,?? ????.release????=?fimc_release,?? ????.ioctl??????=?video_ioctl2,?? ????.read???????=?fimc_read,?? ????.write??????=?fimc_write,?? ????.mmap???????=?fimc_mmap,?? ????.poll???????=?fimc_poll,?? };??
3)FIMC初始設置
在S5PV210中,FIMC初始設置代碼在 /drivers/ arch/arm/mach-s5pv210/mach-smdkv310.c中:
[cpp] ?view plaincopy
static ? struct ?s3c_platform_fimc?fimc_plat?=?{?? ????.srclk_name?=?"mout_mpll" ,?? ????.clk_name???=?"sclk_fimc" ,?? ????.lclk_name??=?"sclk_fimc_lclk" ,?? ????.clk_rate???=?166750000,?? ????.default_cam????=?CAMERA_CSI_C,?? ?????????.camera????????=?{?? ????????&mt9p111,?? ????????&s5k6aafx,?? ????},?? ????.hw_ver?????=?0x43,?? };??
?對于GPIO的配置代碼在 /drivers/ arch/arm/mach-s5pv210/setup-fimc0.c中:
[cpp] ?view plaincopy
oid?s3c_fimc0_cfg_gpio( struct ?platform_device?*pdev)?? {?? ????int ?i?=?0;?? ?? ?????? ????for ?(i?=?0;?i?<?8;?i++)?{?? ????????s3c_gpio_cfgpin(S5PV210_GPE0(i),?S3C_GPIO_SFN(2));?? ????????s3c_gpio_setpull(S5PV210_GPE0(i),?S3C_GPIO_PULL_NONE);?? ????}?? ?????? ????for ?(i?=?0;?i?<?5;?i++)?{?? ????????s3c_gpio_cfgpin(S5PV210_GPE1(i),?S3C_GPIO_SFN(2));?? ????????s3c_gpio_setpull(S5PV210_GPE1(i),?S3C_GPIO_PULL_NONE);?? ????}?? ?????? ????for ?(i?=?0;?i?<?8;?i++)?{?? ????????s3c_gpio_cfgpin(S5PV210_GPJ0(i),?S3C_GPIO_SFN(3));?? ????????s3c_gpio_setpull(S5PV210_GPJ0(i),?S3C_GPIO_PULL_NONE);?? ????}?? ?????? ????for ?(i?=?0;?i?<?5;?i++)?{?? ????????s3c_gpio_cfgpin(S5PV210_GPJ1(i),?S3C_GPIO_SFN(3));?? ????????s3c_gpio_setpull(S5PV210_GPJ1(i),?S3C_GPIO_PULL_NONE);?? ????}?? }??
4)接口函數
FIMC的主要回調函數如下,實現在fimc_v4l2.c中:
[cpp] ?view plaincopy
onst? struct ?v4l2_ioctl_ops?fimc_v4l2_ops?=?{?? ????.vidioc_querycap????????=?fimc_querycap,?? ????.vidioc_reqbufs?????????=?fimc_reqbufs,?? ????.vidioc_querybuf????????=?fimc_querybuf,?? ????.vidioc_g_ctrl??????????=?fimc_g_ctrl,?? ????.vidioc_s_ctrl??????????=?fimc_s_ctrl,?? ????.vidioc_s_ext_ctrls?????=?fimc_s_ext_ctrls,?? ????.vidioc_cropcap?????????=?fimc_cropcap,?? ????.vidioc_g_crop??????????=?fimc_g_crop,?? ????.vidioc_s_crop??????????=?fimc_s_crop,?? ????.vidioc_streamon????????=?fimc_streamon,?? ????.vidioc_streamoff???????=?fimc_streamoff,?? ????.vidioc_qbuf????????????=?fimc_qbuf,?? ????.vidioc_dqbuf???????????=?fimc_dqbuf,?? ????.vidioc_enum_fmt_vid_cap????=?fimc_enum_fmt_vid_capture,?? ????.vidioc_g_fmt_vid_cap???????=?fimc_g_fmt_vid_capture,?? ????.vidioc_s_fmt_vid_cap???????=?fimc_s_fmt_vid_capture,?? ????.vidioc_try_fmt_vid_cap?????=?fimc_try_fmt_vid_capture,?? ????.vidioc_enum_input??????=?fimc_enum_input,?? ????.vidioc_g_input?????????=?fimc_g_input,?? ????.vidioc_s_input?????????=?fimc_s_input,?? ????.vidioc_g_parm??????????=?fimc_g_parm,?? ????.vidioc_s_parm??????????=?fimc_s_parm,?? ????.vidioc_queryctrl???????=?fimc_queryctrl,?? ????.vidioc_querymenu???????=?fimc_querymenu,?? ????.vidioc_g_fmt_vid_out???????=?fimc_g_fmt_vid_out,?? ????.vidioc_s_fmt_vid_out???????=?fimc_s_fmt_vid_out,?? ????.vidioc_try_fmt_vid_out?????=?fimc_try_fmt_vid_out,?? ????.vidioc_g_fbuf??????????=?fimc_g_fbuf,?? ????.vidioc_s_fbuf??????????=?fimc_s_fbuf,?? ????.vidioc_try_fmt_vid_overlay?=?fimc_try_fmt_overlay,?? ????.vidioc_g_fmt_vid_overlay???=?fimc_g_fmt_vid_overlay,?? ????.vidioc_s_fmt_vid_overlay???=?fimc_s_fmt_vid_overlay,?? };??
對于寄存器的操作,實現都在fimc_regs.c文件中,如
[cpp] ?view plaincopy
int ?fimc_hwset_camera_source( struct ?fimc_control?*ctrl)?? {?? ????struct ?s3c_platform_camera?*cam?=?ctrl->cam;?? ????u32?cfg?=?0;?? ?? ????cfg?|=?S3C_CISRCFMT_ITU601_8BIT;?? ????cfg?|=?cam->order422;?? ?? ????if ?(cam->type?==?CAM_TYPE_ITU)?? ????????cfg?|=?cam->fmt;?? ?? ????cfg?|=?S3C_CISRCFMT_SOURCEHSIZE(cam->width);?? ????cfg?|=?S3C_CISRCFMT_SOURCEVSIZE(cam->height);?? ?? ????writel(cfg,?ctrl->regs?+?S3C_CISRCFMT);?? ?? ????return ?0;?? }?? ?? int ?fimc_hwset_enable_irq( struct ?fimc_control?*ctrl,? int ?overflow,? int ?level)?? {?? ????u32?cfg?=?readl(ctrl->regs?+?S3C_CIGCTRL);?? ?? ????cfg?&=?~(S3C_CIGCTRL_IRQ_OVFEN?|?S3C_CIGCTRL_IRQ_LEVEL);?? ????cfg?|=?S3C_CIGCTRL_IRQ_ENABLE;?? ?? ????if ?(overflow)?? ????????cfg?|=?S3C_CIGCTRL_IRQ_OVFEN;?? ?? ????if ?(level)?? ????????cfg?|=?S3C_CIGCTRL_IRQ_LEVEL;?? ?? ????writel(cfg,?ctrl->regs?+?S3C_CIGCTRL);?? ?? ????return ?0;?? }??
總結
以上是生活随笔 為你收集整理的android camera(三):camera V4L2 FIMC 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。