娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

基于Linux 3.0.8 Samsung FIMC(S5PV210) 的攝像頭驅動框架解讀(一)

發布者:CaptivatingEyes最新更新時間:2024-12-27 來源: cnblogs關鍵字:Linux  S5PV210  攝像頭  驅動框架 手機看文章 掃描二維碼
隨時隨地手機看文章

FIMC這個名字應該是從S5PC1x0開始出現的。在s5pv210里面的定義是攝像頭接口。可是它相同具有圖像數據顏色空間轉換的作用。


而exynos4412對它的定義看起來更清楚些,攝像頭接口被定義為FIMC-LITE 。顏色空間轉換的硬件結構被定義為FIMC-IS。


不多說了,我們先來看看Linux3.0.8 三星的BSP包中與fimc驅動相關的文件。

上面的源代碼文件組成了整個fimc的驅動框架。


通過.c文件的命名也大致能夠推測到FIMC的幾個用途:


1、Capture ,Camera Interface 用于控制Camera,及m2m操作


2、Output,這個用途能夠簡單看成:僅僅使用了FIMC的m2m功能。這里fimc實際上就成了一個帶有顏色空間轉換功能的快速DMA。


3、Overlay,比方Android 的Overlay就依賴了FIMC的這個功能,能夠簡單把它看作是個m2fb,當然實質上還是m2m。


清楚FIMC的大致用途了。再來說說。每一個C文件在FIMC驅動框架中扮演了何種角色:


csis.c文件,用于MIPI 接口的攝像頭設備,這里不多說什么了。


fimc_dev.c 是驅動中對FIMC硬件設備最高層的抽象,這在后面會具體介紹。


fimc_v4l2.c  linux驅動中 。將fimc 設備的功能操作接口(Capture,output,Overlay)。用v4l2框架封裝。在應用層用過攝像頭設備,或在應用層使用FMIC設備完畢過m2m操作的朋友應該都清楚,fimc經層層封裝后終于暴露給用戶空間的是v4l2 標準接口的設備文件 videoX。 這里面也引出了一個我們應該關注的問題:Fimc設備在軟件層上是怎樣同攝像頭設備關聯的。


fimc_capture.c  實現對camera Interface 的控制操作。它實現的基礎依賴硬件相關的攝像頭驅動(eg.ov965X.c  / ov5642.c 等)。


而且提供以下函數接口,由fimc_v4l2.c文件進一步封裝


int fimc_g_parm(struct file *file, void*fh, struct v4l2_streamparm *a)


int fimc_s_parm(struct file *file, void*fh, struct v4l2_streamparm *a)


intfimc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)


intfimc_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qm)


intfimc_enum_input(struct file *file, void *fh, struct v4l2_input *inp)


intfimc_g_input(struct file *file, void *fh, unsigned int *i)


intfimc_release_subdev(struct fimc_control *ctrl)


intfimc_s_input(struct file *file, void *fh, unsigned int i)


intfimc_enum_fmt_vid_capture(struct file *file, void *fh,struct v4l2_fmtdesc *f)


intfimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)


intfimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)


intfimc_try_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)


intfimc_reqbufs_capture(void *fh, struct v4l2_requestbuffers *b)


intfimc_querybuf_capture(void *fh, struct v4l2_buffer *b)


intfimc_g_ctrl_capture(void *fh, struct v4l2_control *c)


intfimc_s_ctrl_capture(void *fh, struct v4l2_control *c)


intfimc_s_ext_ctrls_capture(void *fh, struct v4l2_ext_controls *c)


intfimc_cropcap_capture(void *fh, struct v4l2_cropcap *a)


intfimc_g_crop_capture(void *fh, struct v4l2_crop *a)


intfimc_s_crop_capture(void *fh, struct v4l2_crop *a)


intfimc_start_capture(struct fimc_control *ctrl)


intfimc_stop_capture(struct fimc_control *ctrl)


intfimc_streamon_capture(void *fh)


intfimc_streamoff_capture(void *fh)


intfimc_qbuf_capture(void *fh, struct v4l2_buffer *b)


intfimc_dqbuf_capture(void *fh, struct v4l2_buffer *b)


fimc_output.c  實現fimc m2m操作,須要用FIMC實現硬件顏色空間轉換的時候,這個文件中的函數就派上作用了,另外在fimc 用于Capture 和 overlay 過程本質上也包括m2m操作。因此除了提供功能函數接口,由fimc_v4l2.c文件進一步封裝。另外還提供了一些功能函數供fimc_dev.c調用。比方用于設置一個m2m過程的srcAddr(源地址) 和 dstAddr(目的地址)。


這部分接口太多就不貼出來了。


fimc_overlay.c  實現fimc overlay操作。


相同提供函數接口。由fimc_v4l2.c文件進一步封裝。


fimc_regs.c  Fimc硬件相關操作,基本寄存器配置等。這個文件提供函數接口供fimc_capture.c、fimc_output.c、fimc_overlay.c調用。


通過剛才的分析。能夠總結出以下的源代碼結構圖:

好了,框架有了。再來看源代碼就輕松多了


接下來,先來看看FIMC設備的注冊過程。


以FIMC-0為例。說說/dev/video0 這個設備文件是怎么出來的。


先看幾個關鍵結構:


首先是 s3c_platform_fimcfimc_plat_lsi;也就是抽象fimc模塊的數據結構,fimc_plat_lsi還包括了一個.camera成員。該結構初始化例如以下


static struct s3c_platform_fimc  fimc_plat_lsi = {

.srclk_name = 'mout_mpll',

.clk_name = 'sclk_fimc',

.lclk_name = 'fimc',

.clk_rate = 166750000,

#if defined(CONFIG_VIDEO_S5K4EA)

.default_cam = CAMERA_CSI_C,

#else

#ifdef CAM_ITU_CH_A

.default_cam = CAMERA_PAR_A,

#else

.default_cam = CAMERA_PAR_B,

#endif

#endif

.camera = {

#ifdef CONFIG_VIDEO_S5K4ECGX

&s5k4ecgx,

#endif

#ifdef CONFIG_VIDEO_S5KA3DFX

&s5ka3dfx,

#endif

#ifdef CONFIG_VIDEO_S5K4BA

&s5k4ba,

#endif

#ifdef CONFIG_VIDEO_S5K4EA

&s5k4ea,

#endif

#ifdef CONFIG_VIDEO_TVP5150

&tvp5150,

#endif

#ifdef CONFIG_VIDEO_OV9650

&ov9650,

#endif

},

.hw_ver = 0x43,

};


能夠看到在s3c_platform_fimc中有一個camera成員。


這里重點看一下ov9650.展開ov9650



static struct s3c_platform_camera ov9650 = {

#ifdef CAM_ITU_CH_A

.id = CAMERA_PAR_A,

#else

.id = CAMERA_PAR_B,

#endif

.type = CAM_TYPE_ITU,

.fmt = ITU_601_YCBCR422_8BIT,

.order422 = CAM_ORDER422_8BIT_YCBYCR,

.i2c_busnum = 0,

.info = &ov9650_i2c_info,

.pixelformat = V4L2_PIX_FMT_YUYV,

.srclk_name = 'mout_mpll',

/* .srclk_name = 'xusbxti', */

.clk_name = 'sclk_cam1',

.clk_rate = 40000000,

.line_length = 1920,

.width = 1280,

.height = 1024,

.window = {

.left = 0,

.top = 0,

.width = 1280,

.height = 1024,

},


/* Polarity */

.inv_pclk = 1,

.inv_vsync = 1,

.inv_href = 0,

.inv_hsync = 0,


.initialized = 0,

.cam_power = ov9650_power_en,

};


這個結構體。實現了對ov9650攝像頭硬件結構的抽象。定義了攝像頭的關鍵參數和基本特性。


由于fimc設備在linux3.0.8內核中作為一個平臺設備載入。而上面提到的s3c_platform_fimcfimc_plat_lsi僅是fimc的抽象數據而非設備。

這就須要將抽象fimc的結構體作為fimc  platform_device 的一個私有數據。


所以就有了以下的過程。s3c_platform_fimcfimc_plat_lsi 結構在板級設備初始化XXX_machine_init(void) 過程作為s3c_fimc0_set_platdata 的實參傳入。


之后fimc_plat_lsi就成為了fimc設備的platform_data。






s3c_fimc0_set_platdata(&fimc_plat_lsi);

s3c_fimc1_set_platdata(&fimc_plat_lsi);

s3c_fimc2_set_platdata(&fimc_plat_lsi);


以s3c_fimc0_set_platdata為例展開




void __init s3c_fimc0_set_platdata(struct s3c_platform_fimc *pd)

{

struct s3c_platform_fimc *npd;


if (!pd)

pd = &default_fimc0_data;


npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);

if (!npd)

printk(KERN_ERR '%s: no memory for platform datan', __func__);

else {

if (!npd->cfg_gpio)

npd->cfg_gpio = s3c_fimc0_cfg_gpio;


if (!npd->clk_on)

npd->clk_on = s3c_fimc_clk_on;


if (!npd->clk_off)

npd->clk_off = s3c_fimc_clk_off;


npd->hw_ver = 0x45;


/* starting physical address of memory region */

npd->pmem_start = s5p_get_media_memory_bank(S5P_MDEV_FIMC0, 1);

/* size of memory region */

npd->pmem_size = s5p_get_media_memsize_bank(S5P_MDEV_FIMC0, 1);


s3c_device_fimc0.dev.platform_data = npd;

}

}


最后一句是關鍵 s3c_device_fimc0.dev.platform_data = npd; 


看一下s3c_device_fimc0定義:



struct platform_device s3c_device_fimc0 = {

.name = 's3c-fimc',

.id = 0,

.num_resources = ARRAY_SIZE(s3c_fimc0_resource),

.resource = s3c_fimc0_resource,

};


fimc的抽象數據。則作為它的私有數據被包括進了s3c_device_fimc0這個結構中。到這里才完畢了FIMC平臺設備的終于定義。這個平臺設備的定義s3c_device_fimc0又被加入到了整個硬件平臺的 platform_device 列表中,終于在XXX_machine_init(void) 函數中調用platform_add_devices(mini210_devices, ARRAY_SIZE(mini210_devices));  完畢全部platform_device 的注冊:



static struct platform_device *mini210_devices[] __initdata = {

&s3c_device_adc,

&s3c_device_cfcon,

&s3c_device_nand,

。。。


&s3c_device_fb,

&mini210_lcd_dev,

#ifdef CONFIG_VIDEO_FIMC

&s3c_device_fimc0,

&s3c_device_fimc1,

&s3c_device_fimc2,

}



platform_add_devices(mini210_devices, ARRAY_SIZE(mini210_devices));


platform_device 被載入后,等待與之匹配的platform_driver。

若此時fimc driver 的驅動模塊被載入。


這個時候,fimc_dev.c文件中的static int __devinit fimc_probe(structplatform_device *pdev) 函數上場了。





static int __devinit fimc_probe(struct platform_device *pdev)

{

struct s3c_platform_fimc *pdata;

struct fimc_control *ctrl;

struct clk *srclk;

int ret;

if (!fimc_dev) {

fimc_dev = kzalloc(sizeof(*fimc_dev), GFP_KERNEL);

if (!fimc_dev) {

dev_err(&pdev->dev, '%s: not enough memoryn',

__func__);

return -ENOMEM;

}

}


ctrl = fimc_register_controller(pdev);

if (!ctrl) {

printk(KERN_ERR '%s: cannot register fimcn', __func__);

goto err_alloc;

}


pdata = to_fimc_plat(&pdev->dev);

if (pdata->cfg_gpio)

pdata->cfg_gpio(pdev);


#ifdef REGULATOR_FIMC

/* Get fimc power domain regulator */

ctrl->regulator = regulator_get(&pdev->dev, 'pd');

if (IS_ERR(ctrl->regulator)) {

fimc_err('%s: failed to get resource %sn',

__func__, 's3c-fimc');

return PTR_ERR(ctrl->regulator);

}

#endif //REGULATOR_FIMC

/* fimc source clock */

srclk = clk_get(&pdev->dev, pdata->srclk_name);

if (IS_ERR(srclk)) {

fimc_err('%s: failed to get source clock of fimcn',

__func__);

goto err_v4l2;

}


/* fimc clock */

ctrl->clk = clk_get(&pdev->dev, pdata->clk_name);

if (IS_ERR(ctrl->clk)) {

fimc_err('%s: failed to get fimc clock sourcen',

__func__);

goto err_v4l2;

}


/* set parent for mclk */

clk_set_parent(ctrl->clk, srclk);


/* set rate for mclk */

clk_set_rate(ctrl->clk, pdata->clk_rate);


/* V4L2 device-subdev registration */

ret = v4l2_device_register(&pdev->dev, &ctrl->v4l2_dev);

if (ret) {

fimc_err('%s: v4l2 device register failedn', __func__);

goto err_fimc;

}


/* things to initialize once */

if (!fimc_dev->initialized) {

ret = fimc_init_global(pdev);

if (ret)

goto err_v4l2;

}


/* video device register */

ret = video_register_device(ctrl->vd, VFL_TYPE_GRABBER, ctrl->id);

if (ret) {

fimc_err('%s: cannot register video drivern', __func__);

goto err_v4l2;

}


video_set_drvdata(ctrl->vd, ctrl);


ret = device_create_file(&(pdev->dev), &dev_attr_log_level);

if (ret < 0) {

fimc_err('failed to add sysfs entriesn');

goto err_global;

}

printk(KERN_INFO 'FIMC%d registered successfullyn', ctrl->id);


return 0;


err_global:

video_unregister_device(ctrl->vd);


err_v4l2:

v4l2_device_unregister(&ctrl->v4l2_dev);


err_fimc:

fimc_unregister_controller(pdev);


err_alloc:

kfree(fimc_dev);

return -EINVAL;


}


在fimc_probe函數中有這么一段


if(!fimc_dev->initialized) {

                   ret = fimc_init_global(pdev);

                   if (ret)

                            goto err_v4l2;

         }



這段代碼運行過程:首先推斷fimc是否已經被初始化完畢(此時FIMC是忙狀態的),假設沒有被初始化,則運行fimc_init_global(pdev);函數,它的作用是先推斷平臺數據中是否初始化了攝像頭結構(即前面提到的.camera成員),從平臺數據中獲得攝像頭的時鐘頻率并將平臺數據中內嵌的s3c_platform_camera結構數據保存到該驅動模塊全局的fimc_dev中,感興趣的朋友能夠展開這個函數看一下,這里就不再貼出來了。


緊接著這段代碼還運行了兩個很關鍵的過程:


ret= v4l2_device_register(&pdev->dev, &ctrl->v4l2_dev);

         if (ret) {

                   fimc_err('%s: v4l2device register failedn', __func__);

                   goto err_fimc;

         }



這個函數里的核心完畢了對v4l2_dev->subdev鏈表頭的初始化,并將ctrl->v4l2_dev關聯到pdev->dev結構的私有數據的driver_data成員中(即完畢了pdev->dev->p->driver_data= ctrl->v4l2_dev; )。也就是實現了v4l2_dev向內核結構注冊的過程。

[1] [2]
關鍵字:Linux  S5PV210  攝像頭  驅動框架 引用地址:基于Linux 3.0.8 Samsung FIMC(S5PV210) 的攝像頭驅動框架解讀(一)

上一篇:kernel 2.6.35.7向S5PV210移植
下一篇:s5pv210 uboot-2012-10移植(二) 之能夠啟動進入控制臺

推薦閱讀最新更新時間:2025-04-23 15:30

S5PV210之beep驅動linux2.6.35.7移植到linux3.0.8
beep驅動從linux2.6.35.7內核移植到linux3.0.8,修改的部分為:   '='后面的為修改后的   .ioctl  =  .unlocked_ioctl   static int beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)   = static int beep_ioctl(struct file *file, unsigned int cmd, unsigned long arg)   beep_ioctl函數中struct inode *inode去掉,原因是b
[單片機]
S5PV210 學習 Linux (三) SD卡下載
1、用 USB 下載 比較方便 2、用 SD 卡 更新產品 程序,有時候 會 比較 方便一點 3、我的S5PV210 開發板 有個 撥碼開關,撥到USB 啟動 或者 EMMC 啟動 4、選擇EMMC啟動 會首先從 SD 的通道0(已經接了EMMC 芯片 ) 啟動,如果通道0啟動失敗(校驗和啟動),就會從通道2(可以插大SD卡 )啟動,因此要 破壞 通道0的啟動,才能 從通道2啟動。 5、在Linux和安卓系統下,擦出 SD 的通道0中 uboot 的 一個扇區,這樣才能從SD的通道2啟動。擦除方法是: ①在Linux或者安卓系統下 擦除 uboot 的方法,如下: 指令一:busybox dd if=/dev/zero
[單片機]
用 <font color='red'>S5PV210</font> 學習 <font color='red'>Linux</font> (三) SD卡下載
怎樣在嵌入式Linux系統中使用攝像頭
  簡介   本文主要基于ARM嵌入式模塊系統展示在嵌入式Linux中使用攝像頭示例,所采用的模塊為Toradex VF61,是一款性價比極高但不包含硬件視頻編解碼加速的模塊,核心處理器為NXP/Freescale Vybrid,Cortex-A5和M4異構雙核架構。   1)。 目前越來越多的嵌入式系統采用攝像頭應用,其中主要有下面幾種方式   遠程監控:如閉路電視系統,操作人員通過攝像頭遠程監控某個特定區域,小到一個小區,達到市政公共場所,都可能有這樣的應用。   監控視頻錄制:另外一些監控系統不一定有操作人員一直監控,則會通過錄制監控視頻的方式在需要的時候調出相關視頻進行查閱。   嵌入式視覺系統:嵌入式視覺系統
[單片機]
怎樣在嵌入式<font color='red'>Linux</font>系統中使用<font color='red'>攝像頭</font>
LG G8 ThinQ 渲染圖曝光:前置 TOF 攝像頭并搭載驍龍 855
集微網消息,今年的 MWC 2019 注定是備受關注的一年,除了三星、索尼、諾基亞、華為等廠商已經基本確定將于 MWC 2019 期間發布新品之外,日前知名爆料人士 evleaks 也曝出 LG 也將在展會期間發布 LG G8 ThinQ 。 從曝出的渲染圖中得悉,LG G8 ThinQ 在外觀造型方面與 LG V40 ThinQ 相差不大,兩臺手機均采用了“劉海屏”設計,但 LG G8 ThinQ 采用的是后置雙攝設計。 核心配置方面,LG G8 ThinQ 搭載驍龍 855 移動平臺,配備 6GB + 128GB 存儲組合,后置指紋識別,電池容量為 3500mAh 。 值得一提的的是,LG G8 ThinQ
[手機便攜]
LG G<font color='red'>8</font> ThinQ 渲染圖曝光:前置 TOF <font color='red'>攝像頭</font>并搭載驍龍 855
蛋糕太大一家吃不下?傳3供應商分食iPhone 12攝像頭模組訂單
據外媒報道,有供應鏈消息人士透露,一向“不把雞蛋放在同一個籃子”的蘋果,最終選擇讓三家知名供應商共同為iPhone 12系列供應攝像頭模組... 據外媒macrumors報道稱,臺灣手機供應鏈的消息人士稱,LG Innotek、夏普和歐菲光這三家蘋果供應商將分享iPhone 12系列攝像頭模組訂單。 天風國際證券分析師郭明錤報告先前預估,今年下半年新款iPhone將有3種尺寸和4款機型,包括5.4英寸OLED版(后置雙攝影鏡頭)、6.1英寸OLED版(后置雙攝影鏡頭)、6.1英寸OLED版(后置3攝影鏡頭加上飛時測距ToF功能),以及6.7英寸OLED版(后置3攝影鏡頭加上飛時測距ToF功能)。 預計四款i
[手機便攜]
蛋糕太大一家吃不下?傳<font color='red'>3</font>供應商分食iPhone 12<font color='red'>攝像頭</font>模組訂單
[S5PV210] 網絡掛載文件系統
流程   片內os起來后,從SDCARD加載uboot,然后使用 tftp 從 PC 下載 kernel,然后使用 nfs 掛載 PC 上的文件系統。 搭建 TFTP 和 NFS server TFTP   sudo apt-get install tftp-hpa tftpd-hpa xinetd   sudo vim /etc/xinetd.d/tftp   service tftp   { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbi
[單片機]
嵌入式開發(S5PV210)——ADC和觸摸屏
1、ADC介紹 ADC(analog digital converter)就是AD轉換,把模擬量轉換為數字量。CPU本身是數字的、離散的,而外部世界卻是模擬的、連續的,所以外界的信息是不能直接被計算機進行處理,需要先將模擬量轉換為數字量。現在的CPU都是二進制的,數據用n位二進制來表示,但是現實生活中的時間、電壓、高度等物理量都是連續分布的,在0到1之間就有無數個數,如果用數學來描述當前的物理量大小可能需要無限小數位,顯然計算機是不可能用無限個二進制位來存儲這個物理量,于是就有了量取的精度,用有限位的二進制來表示當前物理量,會損失掉一定的精度,不能百分百真實的表示,但是這點偏差是可以接受的。而ADC就是將當前現實中的物理量,根據精
[單片機]
嵌入式開發(<font color='red'>S5PV210</font>)——ADC和觸摸屏
[S3C6410-01]燒寫Linux3.0.1系統
經過Linus Torvalds及無計其數的linux愛好者的努力,linux kernel3的第一個版本3.0.1終于出師。看了一下官方介紹,截至目前,穩定版的3.3.4也已發布,linux3增加了一些功能,同時也增加了很多驅動。具體的細節可以在網上查到。既然linux3都已經出來了,就趕個時髦,在此上面做些東西。 由于我手頭只有一塊ok6410的板子,在其官方網站上看到飛凌的工程師已經成功移植好ok6410板的linux3.0.1系統,所以閑來無事,我就把我的2.6.28系統升級到3.0.1。 但是飛凌官方的文檔寫的真不靠譜,如果按照里面的步驟燒寫系統,很讓人DT。真希望以后他們能找個文檔工程師專門來寫操作手冊。 第一次按照手
[單片機]
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 绥棱县| 曲阳县| 扎囊县| 宾川县| 永福县| 和硕县| 安多县| 景洪市| 阜新市| 同仁县| 海城市| 汝阳县| 城口县| 武川县| 丹棱县| 莱芜市| 安远县| 宁化县| 库车县| 武穴市| 历史| 武平县| 永修县| 彰化县| 仁化县| 巴林右旗| 南投县| 阿巴嘎旗| 福建省| 洛隆县| 收藏| 南阳市| 于田县| 稷山县| 达州市| 江门市| 涞水县| 泸西县| 厦门市| 丁青县| 秦皇岛市|