關(guān)鍵詞:
android ?camera CMM 模組 camera參數(shù) ?CAMIF ? V4L2 ?
平臺(tái)信息: 內(nèi)核:
linux
系統(tǒng):
android
平臺(tái): S5PV310(samsung exynos 4210)?
作者:xubin341719(歡迎轉(zhuǎn)載,請(qǐng)注明作者)
android camera(一):camera模組CMM介紹
android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF)
android camera(三):camera V4L2 FIMC
android camera(四):camera 驅(qū)動(dòng) GT2005
下載:常用攝像頭規(guī)格書(個(gè)別有android驅(qū)動(dòng)程序)? :bf3703 30W、gc0308 30W、ov7670、gt2005 200W、gt2015 200W、NT99250 200W、s5k5ba 200W、s5k4ba
????????? 前面兩篇說的有點(diǎn)多了,不過多了解點(diǎn)東西也挺好的,遇到問題時(shí)可以有更多的思路,真正驅(qū)動(dòng)是從這一塊開始。一般BSP的camera都是完好的,我們只用關(guān)心驅(qū)動(dòng)這些就可以了。
1. V4L2
1)簡(jiǎn)介
??????? 在Linux中,攝像頭方面的標(biāo)準(zhǔn)化程度比較高,這個(gè)標(biāo)準(zhǔn)就是V4L2驅(qū)動(dòng)程序,這也是業(yè)界比較公認(rèn)的方式。
??????? V4L全稱是Video for Linux,是Linux內(nèi)核中標(biāo)準(zhǔn)的關(guān)于視頻驅(qū)動(dòng)程序,目前使用比較多的版本是Video for Linux 2,簡(jiǎn)稱V4L2。它為L(zhǎng)inux下的視頻驅(qū)動(dòng)提供了統(tǒng)一的接口,使得應(yīng)用程序可以使用統(tǒng)一的API操作不同的視頻設(shè)備。從內(nèi)核空間到用戶空間,主要的數(shù)據(jù)流和控制類均由V4L2驅(qū)動(dòng)程序的框架來定義。
V4L2驅(qū)動(dòng)程序一般只提供Video數(shù)據(jù)的獲得,而如何實(shí)現(xiàn)視頻預(yù)覽,如何向上層發(fā)送數(shù)據(jù),如何把純視頻流和取景器、視頻錄制等實(shí)際業(yè)務(wù)組織起來,都是camera的硬件抽象層需要負(fù)責(zé)的工作。
V4L2驅(qū)動(dòng)核心實(shí)現(xiàn)為如下文件:drivers/media/video/v4l2-dev.c。
V4l2-dev.h中定義的video_device是V4L2驅(qū)動(dòng)程序的核心數(shù)據(jù)結(jié)構(gòu),它為具體的攝像頭sensor驅(qū)動(dòng)提供了接口調(diào)用。
V4l2的采集過程(應(yīng)用程序):
1)???? 打開設(shè)備,獲得文件描述符;
2)???? 設(shè)置圖片格式;
3)???? 分配緩沖區(qū);
4)???? 啟動(dòng)采集過程,讀取數(shù)據(jù);
5)???? 停止采集,關(guān)閉設(shè)備。
?
2)數(shù)據(jù)結(jié)構(gòu)
V4L2的主要數(shù)據(jù)結(jié)構(gòu)是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;????? };??
主要接口函數(shù)有:
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)簡(jiǎn)介
FIMC這個(gè)模塊不僅僅是一個(gè)攝像頭的控制接口,它還承擔(dān)著V4L2的output功能和overlay的功能。
FIMC的驅(qū)動(dòng)在內(nèi)核中的位置:drivers/media/video/samsung/fimc
它包含下邊的文件:
??????fimc_regs.c ????????fimc_capture.c ????????fimc_dev.c ????????fimc_output.c ????????fimc_overlay.c ????????fimc_v4l2.c
它們的組織關(guān)系如下:
可以看到,FIMC的驅(qū)動(dòng)實(shí)現(xiàn)了v4l2所有的接口,可以分為v4l2-input設(shè)備接口,v4l2-output設(shè)備接口以及v4l2-overlay設(shè)備接口。這里我們主要關(guān)注v4l2-input設(shè)備接口,因?yàn)閿z像頭屬于視頻輸入設(shè)備。
fimc_v4l2.c里面注冊(cè)了很多的回調(diào)函數(shù),都是用于實(shí)現(xiàn)v4l2的標(biāo)準(zhǔn)接口的,但是這些回調(diào)函數(shù)基本上都不是在fimc_v4l2.c里面實(shí)現(xiàn)的,而是有相應(yīng)的.c分別去實(shí)現(xiàn)。比如:
v4l2-input設(shè)備的操作實(shí)現(xiàn):fimc_capture.c ????????v4l2-output設(shè)備的操作實(shí)現(xiàn): fimc_output.c ????????v4l2-overlay設(shè)備的操作實(shí)現(xiàn): fimc_overlay.c
這些代碼其實(shí)都是和具體硬件操作無關(guān)的,這個(gè)驅(qū)動(dòng)把所有操作硬件寄存器的代碼都寫到一個(gè)文件里面了,就是fimc40_regs.c。這樣把硬件相關(guān)的代碼和硬件無關(guān)的代碼分開來實(shí)現(xiàn)是非常好的方式,可以最大限度的實(shí)現(xiàn)代碼復(fù)用。
?2) 數(shù)據(jù)結(jié)構(gòu)?
?
FIMC的主要數(shù)據(jù)結(jié)構(gòu)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];?? };??
因?yàn)镕IMC
一共有三套一樣的控制器(fimc0, fimc1, fimc2),所以驅(qū)動(dòng)里使用了一個(gè)數(shù)組來描述:
[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結(jié)構(gòu)體是針對(duì)v4l2設(shè)備的基本操作,定義如下:
[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初始設(shè)置
在S5PV210中,FIMC初始設(shè)置代碼在 /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,?? };??
?對(duì)于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)接口函數(shù)
FIMC的主要回調(diào)函數(shù)如下,實(shí)現(xiàn)在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,?? };??
對(duì)于寄存器的操作,實(shí)現(xiàn)都在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;?? }??
總結(jié)
以上是生活随笔 為你收集整理的android camera(三):camera V4L2 FIMC 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。