Linux V4L2 原始碼分析

2021-10-24 13:13:22 字數 3400 閱讀 7275

video for linux 2真的是乙個很複雜的框架,抽象倒不是它複雜的原因,是因為耦合了其他框架的內容,導致要掌握v4l2必須得需要乙個非常廣的核心層知識面,以及linux抽象思想。這篇文章將會以ov2640.c為例子進行原始碼分析,我會盡量從上往下,也就是使用者層呼叫到核心層進行分析。

注:在linux核心層學習,你得學會適應龐大**給你帶來的不安感。

首先,像ov2640這樣類似的攝像頭感測器,是由多部分組成的,需要i2c作為控制,mipi-csi作為資料傳輸。

那麼在v4l2的框架裡,v4l2_device就是ov2640裝置,而v4l2_device負責管理v4l2_subdev,v4l2_subdev分別對於i2c和mipi-csi硬體裝置。

video_device是負責和使用者層對接的資料結構,/dev/videox和/dev/subdevx都是使用video_device及相關函式向使用者空間開放使用者介面(字元裝置)。

struct video_device

;

v4l2_device 是用於管理全體子裝置subdevs的資料結構。

struct v4l2_device 

;

v4l2_subdev是代表子裝置的資料結構,i2c和mipi,isp都應該有乙個subdev

struct v4l2_subdev 

;

代表資料流,不是實體裝置。

struct media_device 

;

直接看probe函式:

static

intov2640_probe

(struct i2c_client *client,

const

struct i2c_device_id *did)

priv =

devm_kzalloc

(&client->dev,

sizeof

(*priv)

, gfp_kernel);if

(!priv)

return

-enomem;

if(client->dev.of_node)

ret =

ov2640_probe_dt

(client, priv)

; 從裝置樹中查詢指定gpio,找不到報錯

if(ret)

goto err_clk;

priv->win =

ov2640_select_win

(svga_width, svga_height)

; priv->cfmt_code = media_bus_fmt_uyvy8_2x8;

前面大概做了些用於ov2640的資料填充工作。

v4l2_i2c_subdev_init

(&priv->subdev, client,

&ov2640_subdev_ops)

;//初始化subdev,繫結subdev i2c,操作函式

priv->subdev.flags |

= v4l2_subdev_fl_has_devnode | 子節點需要裝置節點

v4l2_subdev_fl_has_events; 子節點有事件傳送

v4l2_i2c_subdev_init初始化subdev裡面的資料,將ops賦值給subdev。

v4l2_ctrl_handler_init

(&priv->hdl,3)

; 分配空間

priv->hdl.lock =

&priv->lock;

v4l2_ctrl_new_std

(&priv->hdl,

&ov2640_ctrl_ops,

v4l2_cid_vflip,0,

1,1,

0); 新增非選單控制項,使用者在使用ioctl時候會呼叫的函式 v4l2_cid_vflip為屬性

v4l2_ctrl_new_std

(&priv->hdl,

&ov2640_ctrl_ops,

v4l2_cid_hflip,0,

1,1,

0);v4l2_ctrl_new_std_menu_items

(&priv->hdl,

&ov2640_ctrl_ops,

v4l2_cid_test_pattern,

array_size

(ov2640_test_pattern_menu)-1

,0,0

, ov2640_test_pattern_menu)

; priv->subdev.ctrl_handler =

&priv->hdl; 給subdev裡新增控制項(使用者空間使用)

if(priv->hdl.error)

這裡是一些ctrl的設定

ret =

ov2640_video_probe

(client);if

(ret <0)

goto err_videoprobe;

ret =

v4l2_async_register_subdev

(&priv->subdev)

;//註冊subdev

if(ret <0)

goto err_videoprobe;

dev_info

(&adapter->dev,

"ov2640 probed\n");

return

0;

設定好subdev的相關資訊後,通知sun4i_csi模組非同步註冊video_device.

linux V4L2程式設計

前言 目前正在忙於arm平台的linux應用程式的開發 其實是剛剛起步學習啦 底層的東西不用考慮了,開發板子提供了nand bootloader,和linux 2.6的原始碼,而且都編譯好了。自己編譯的bootloader可以用,但是linux編譯後,檔案很大,暫且就用人家編譯的系統,先專心寫應用程...

iptables原始碼分析(2)

1.1 表的查詢 再回到iptc init 函式上來,它根據表名,從核心獲取對應的表的相關資訊,handle是乙個iptc handle t型別的指標,在libiptc.c中,有如下定義 transparent handle type.typedef struct iptc handle iptc ...

Leveldb原始碼分析 2

輕鬆一刻,前面約定中講過leveldb使用了很多varint型編碼,典型的如後面將涉及到的各種key。其中的編碼 解碼函式分為varint和fixedint兩種。int32和int64操作都是類似的。首先是fixedint編碼,直接上 很簡單明瞭。void encodefixed32 char bu...