日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

linux csi驱动添加,CSI接口Camera驱动学习

發(fā)布時(shí)間:2025/3/15 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux csi驱动添加,CSI接口Camera驱动学习 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

sam_code@hotmail.com

在Android4.0升級(jí)后,突然發(fā)現(xiàn)大量平臺(tái)對(duì)Camera的支持均非常不好。要么Camera使用不穩(wěn)定,要么各類ioctl設(shè)置不能使用,更有甚者,連Camera

Device都不能創(chuàng)建。

而我們的產(chǎn)品,基于Camera的正常工作,必須解決此類問題。選擇了其中一款使用CSI接口Camera的平臺(tái):全志A20來做研究和解決。

0. 基礎(chǔ)知識(shí)

:

0.0. 目錄結(jié)構(gòu):

除了常見的,在linux-3.3/drivers/media/video/

目錄下有v4l2一些文件外,全志還在另一個(gè)目錄下放置了csi以及做支持模組芯片的代碼:linux-3.3/drivers/media/video/sunxi_csi/

其中,csi部分在csi0或者csi1中。 模組對(duì)應(yīng)代碼在device中。

這些代碼,基本組成了全志CSI 接口 Camera的全部驅(qū)動(dòng)代碼。

0.1. CSI:

COMS Sensor Interface:

CSI接口通常從COMS Sensor,Video Encoder和其它視頻輸出設(shè)備收集數(shù)據(jù)。

0.2. 模組芯片:

手頭這塊板子上自帶GT2005模組。所以需要看linux-3.3/drivers/media/video/sunxi_csi/device/gt2005.c

1. 驅(qū)動(dòng)結(jié)構(gòu):

CSI 模組Driver的基本思路其實(shí)挺簡(jiǎn)單,就是需要?jiǎng)?chuàng)建主設(shè)備號(hào)為81的device.

/dev/videoX。并將其open,close,ioctl 與Driver聯(lián)系起來,最終反應(yīng)到Sensor

(gt2005)層面。

我們首先從linux-3.3/drivers/media/video/sunxi_csi/csi0部分開始著手,這個(gè)文件夾內(nèi)的三個(gè)文件:sunxi_csi_reg.c

,sunxi_drv_csi.c, sunxi_csi_reg.h 最終會(huì)生成sunxi_csi0.ko。

會(huì)被以modules形式insmod 進(jìn)系統(tǒng)。

1.1:CSI0 modules學(xué)習(xí):

當(dāng)sunxi_csi0.ko被insmod時(shí),sunxi_drv_csi.c中的csi_init()被調(diào)用。

csi_init() 中注冊(cè)了一個(gè)driver--csi_driver.

platform_driver_register(&csi_driver);

csi_driver中有偵測(cè)函數(shù):.probe = csi_probe,

Sam的理解是:因?yàn)镃SI接口一直連接著,所以當(dāng)此Driver剛被注冊(cè)時(shí),csi_probe就被調(diào)用。

請(qǐng)注意:csi_probe中作了相當(dāng)多事情,是sunxi_csi0.ko的重點(diǎn)。

它做了很多準(zhǔn)備工作.并通過video_register_device()創(chuàng)建了Device. /dev/videoX.

并將此device的操作與v4l2_fops聯(lián)系起來。

所以,對(duì)此Device的open,close, ioctl等, 都使用v4l2_fops中提供的函數(shù)指證。

而我們看v4l2_fops中的ioctl. 它最終是

video_device?->fops->ioctl()。

其實(shí)就是:csi_template 中的:.fops ?= &csi_fops, 的ioctl.

即:video_ioctl2

video_ioctl2,在v4l2-ioctl.c中定義:其實(shí)就是:

static long __video_do_ioctl(struct

file *file,unsigned int cmd, void *arg)

所以,經(jīng)過CSI程序的鏈接。最終,對(duì)Device /dev/videoX的操作,最終都被歸結(jié)到__video_do_ioctl

同時(shí),csi_ioctl_ops也被鏈接到ioctl_ops。請(qǐng)注意,未來要用到這里。

看到這里,大家都會(huì)疑惑。 這怎么和Sensor操作練習(xí)起來了。這部分只將CSI和V4L2 連起來了。

這就是下一部要說的gt2005.ko了。

1.2: GT2005模塊學(xué)習(xí):

同樣道理,insmod gt2005.ko時(shí),gt2005.c中的init_sensor()會(huì)被啟動(dòng)。

在init_sensor()中,只執(zhí)行了:i2c_add_driver(&sensor_driver);

其中,sensor_driver 同樣會(huì)在驅(qū)動(dòng)安裝后立刻啟動(dòng)。

static int sensor_probe(struct

i2c_client *client,const struct i2c_device_id *id)

v4l2_i2c_subdev_init(sd, client, &sensor_ops);

這一句代碼是關(guān)鍵。

它將sensor_ops加入v4l2_subdev->ops中去了。而v4l2_subdev類型的sd被加入list.未來會(huì)用。(關(guān)鍵3)

分析下:sensor_ops.

static const struct v4l2_subdev_ops sensor_ops = {

.core = &sensor_core_ops,

.video = &sensor_video_ops,

};

也就是有:core和video 兩個(gè)。一定要注意了,這里和未來很有關(guān)系。(關(guān)鍵4)

__video_do_ioctl()最終會(huì)通過vfd->ioctl_ops

來做實(shí)際動(dòng)作。而ioctl_ops是誰呢?就是在在sunxi_drv_csi.c中的csi_ioctl_ops

2. ioctl的完整流程:

當(dāng)用戶open /dev/videoX后,使用ioctl()時(shí),

例1:得到能力集:

rel = ioctl(Handle, VIDIOC_QUERYCAP, &cap);

通過上面的分析, 它通過?__video_do_ioctl?最終調(diào)用到:vfd->ioctl_ops->vidioc_querycap.

也就是?csi_ioctl_ops

的?.vidioc_querycap ?= vidioc_querycap,

也就是說: 調(diào)用ioctl(VIDIOC_QUERYCAP). 會(huì)通過__vidoe_do_ioctl()

最終調(diào)用到sunxi_drv_sic.c中的vidioc_querycap()

為什么沒有進(jìn)Sensor呢? 是因?yàn)槟芰诖a層面維護(hù)。不需要去問Sensor。

例2:得到像素格式

ioctl(Handle, VIDIOC_G_FMT, &Format)

它最終被調(diào)用sunxi_drv_csi.c中的vidioc_g_fmt_vid_cap()

因?yàn)楦袷揭彩怯沙绦蚓S護(hù),所以沒有訪問Sensor。

例3:設(shè)置像素格式

ioctl(Handle, VIDIOC_S_FMT, &Format);

最終被調(diào)用sunxi_drv_csi.c中的vidioc_s_fmt_vid_cap()

注意: 設(shè)置像素格式,需要通知Sensor。

所以會(huì)被調(diào)用:

v4l2_subdev_call(dev->sd,video,s_mbus_fmt,&ccm_fmt);

這里的video. 就是表明調(diào)用的是關(guān)鍵4 那個(gè)的sensor_video_ops。

這里的sd,其實(shí)就是關(guān)鍵3 那里的v4l2_subdev類型sd.

所以,又被調(diào)用到gt2005.c中的sensor_s_fmt()

此時(shí)會(huì)向Sensor中寫入數(shù)據(jù)。sensor_write

例4:

ioctl(Handle, VIDIOC_G_PARM, &Stream_Parm)

會(huì)通過__vidoe_do_ioctl()

調(diào)用到sunxi_drv_csi.c中vidioc_g_parm()

這里會(huì):v4l2_subdev_call(dev->sd,video,g_parm,parms);

在gt2005.c中寫死的。 如果格式大于 800x600. 則15幀。 小于800x600. 則30幀。

例5:

ioctl(Handle, VIDIOC_G_PARM, &Stream_Parm)

會(huì)通過__vidoe_do_ioctl()

調(diào)用到sunxi_drv_csi.c中vidioc_s_parm()

這里會(huì):v4l2_subdev_call(dev->sd,video,s_parm,parms);

在gt2005.c 中。這里打空。所以其實(shí)不能調(diào)。

例6:

ioctl(Handle, VIDIOC_G_CTRL, &ctrl)

會(huì)通過__vidoe_do_ioctl()

調(diào)用到sunxi_drv_csi.c中vidioc_g_ctrl()

這里會(huì):v4l2_subdev_call(dev->sd,core,g_ctrl,ctrl);

注意:這里是core.

所以調(diào)用gt2005.c中的sensor_g_ctrl()

例7:

ioctl(Handle, VIDIOC_S_CTRL,

&ctrl)

會(huì)通過__vidoe_do_ioctl()

調(diào)用到sunxi_drv_csi.c中vidioc_s_ctrl()

這里會(huì):v4l2_subdev_call(dev->sd,core,s_ctrl,ctrl);

注意:這里是core.

所以調(diào)用gt2005.c中的sensor_s_ctrl()

但有一點(diǎn)需要注意:在A20平臺(tái)編程中,大家會(huì)發(fā)現(xiàn)所有VIDIOC_G_CTRL,VIDIOC_S_CTRL全不可用。Sam查了一下代碼。發(fā)現(xiàn)是全志修改Kernel時(shí)弄錯(cuò)了。

錯(cuò)誤如下:

struct v4l2_control {

__u32 ?id;

__s32 ?value;

__u32 user_pt;

};

看起來,是全志一位叫Raymon的工程師非常隨意的修改了v4l2_control結(jié)構(gòu)體。添加了4個(gè)字節(jié)的user_pt;

但這會(huì)造成嚴(yán)重后果,首先,大量使用v4l2_control的接口會(huì)出現(xiàn)未知問題。

更嚴(yán)重的是:ioctl的cmd這一項(xiàng)是計(jì)算出來的。v4l2_control的大小會(huì)影響到cmd的值。

所以,在A20平臺(tái)上,應(yīng)用程序使用VIDIOC_G_CTRL,VIDIOC_S_CTRL時(shí),

__video_do_ioctl(struct file *file,unsigned int cmd, void

*arg)

參數(shù)2:cmd這一項(xiàng)和Kernel中算出的cmd值對(duì)不上。所以無法進(jìn)入:

case VIDIOC_G_CTRL:

case VIDIOC_S_CTRL:

如果有全志工程師偶爾看到這篇Blog。 請(qǐng)通知Driver部門。修改這個(gè)明顯錯(cuò)誤。

總結(jié)

以上是生活随笔為你收集整理的linux csi驱动添加,CSI接口Camera驱动学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。