日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

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

sam_code@hotmail.com

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

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

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

0. 基礎(chǔ)知識

:

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

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

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

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

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

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ū)動結(jié)構(gòu):

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

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

(gt2005)層面。

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

,sunxi_drv_csi.c, sunxi_csi_reg.h 最終會生成sunxi_csi0.ko。

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

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

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

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

platform_driver_register(&csi_driver);

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

Sam的理解是:因為CSI接口一直連接著,所以當(dāng)此Driver剛被注冊時,csi_probe就被調(diào)用。

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

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

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

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

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

video_device?->fops->ioctl()。

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

即:video_ioctl2

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

static long __video_do_ioctl(struct

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

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

同時,csi_ioctl_ops也被鏈接到ioctl_ops。請注意,未來要用到這里。

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

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

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

同樣道理,insmod gt2005.ko時,gt2005.c中的init_sensor()會被啟動。

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

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

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.未來會用。(關(guān)鍵3)

分析下:sensor_ops.

static const struct v4l2_subdev_ops sensor_ops = {

.core = &sensor_core_ops,

.video = &sensor_video_ops,

};

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

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

來做實際動作。而ioctl_ops是誰呢?就是在在sunxi_drv_csi.c中的csi_ioctl_ops

2. ioctl的完整流程:

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

例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). 會通過__vidoe_do_ioctl()

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

為什么沒有進Sensor呢? 是因為能力集在代碼層面維護。不需要去問Sensor。

例2:得到像素格式

ioctl(Handle, VIDIOC_G_FMT, &Format)

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

因為格式也是由程序維護,所以沒有訪問Sensor。

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

ioctl(Handle, VIDIOC_S_FMT, &Format);

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

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

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

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

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

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

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

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

例4:

ioctl(Handle, VIDIOC_G_PARM, &Stream_Parm)

會通過__vidoe_do_ioctl()

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

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

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

例5:

ioctl(Handle, VIDIOC_G_PARM, &Stream_Parm)

會通過__vidoe_do_ioctl()

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

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

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

例6:

ioctl(Handle, VIDIOC_G_CTRL, &ctrl)

會通過__vidoe_do_ioctl()

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

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

注意:這里是core.

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

例7:

ioctl(Handle, VIDIOC_S_CTRL,

&ctrl)

會通過__vidoe_do_ioctl()

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

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

注意:這里是core.

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

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

錯誤如下:

struct v4l2_control {

__u32 ?id;

__s32 ?value;

__u32 user_pt;

};

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

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

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

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

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

*arg)

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

case VIDIOC_G_CTRL:

case VIDIOC_S_CTRL:

如果有全志工程師偶爾看到這篇Blog。 請通知Driver部門。修改這個明顯錯誤。

總結(jié)

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

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