一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

看看Linux為相機(jī)提供的驅(qū)動(dòng)框架

冬至配餃子 ? 來源:嵌入式軟件開發(fā)交流 ? 作者:年輕的 ? 2022-08-07 16:03 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

前面我們了解了一些相機(jī)的基礎(chǔ)知識(shí)《相機(jī)基礎(chǔ)知識(shí)》。下面來看看Linux為相機(jī)提供的驅(qū)動(dòng)框架。

V4L2簡(jiǎn)介

V4L2 (Video Linux Two),是為支持Linux內(nèi)核設(shè)計(jì)的驅(qū)動(dòng)框架驅(qū)動(dòng)框架。為應(yīng)用設(shè)置的操作接口層(ioctl),是在提供更廣泛的時(shí)候它的設(shè)備,它們只有在原件上,才是真正的視頻設(shè)備,所以它們才是真正的攝像頭設(shè)計(jì)。

V4L2框架

poYBAGLvcXOAU-5_AACaFZ8UYXM697.png

在應(yīng)用層,可以在 /dev 顯示設(shè)備節(jié)點(diǎn),程序打開設(shè)備設(shè)備進(jìn)行我們的設(shè)備目錄發(fā)現(xiàn)應(yīng)用程序0、視頻畫面。video1、video2...這些設(shè)備節(jié)點(diǎn)是在核心層注冊(cè)。

v4l2-dev.c) 起承上啟下的作用,它會(huì)為每一個(gè)核心層注冊(cè)中的設(shè)備設(shè)置一個(gè)統(tǒng)一的 v4l2_fops ,這些統(tǒng)一驅(qū)動(dòng)的接口最終將調(diào)用到驅(qū)動(dòng)的 video_device 的 fops 。

重要結(jié)構(gòu)體

視頻設(shè)備

視頻設(shè)備

//表示一個(gè)視頻設(shè)備

struct video_device {

#if defined(CONFIG_MEDIA_CONTROLLER);

struct media_entity entity;

struct media_intf_devnode *intf_devnode;

struct media_pipeline pipe;

#endif;

const struct v4l2_file_operations *fops; //文件操作接口(dev/videoX)

u32 device_caps; //設(shè)備功能,用于v4l2_capabilities(應(yīng)用層定義的結(jié)構(gòu)體)

struct device dev;

struct cdev *cdev; //字符設(shè)備

struct v4l2_device *v4l2_dev; //V4L2設(shè)備

struct device *dev_parent;

struct v4l2_ctrl_handler *ctrl_handler; //設(shè)備節(jié)點(diǎn)對(duì)應(yīng)的控制句柄

struct vb2_queue *queue;

struct v4l2_prio_state *prio;

char name[32]; //Video設(shè)備名稱

enum vfl_devnode_type vfl_type; //V4L設(shè)備類型

enum vfl_devnode_direction vfl_dir; //V4L 接收者/發(fā)送者/m2m

int minor; //子設(shè)備號(hào),主設(shè)備為81

u16 num;

unsigned long flags;

int index;

spinlock_t fh_lock;

struct list_head fh_list;

int dev_debug;

v4l2_std_id tvnorms;

void (*release)(struct video_device *vdev); //video_device release()回調(diào)

const struct v4l2_ioctl_ops *ioctl_ops; //IOCTL回調(diào)

unsigned long valid_ioctls[BITS_TO_LONGS(BASE_VIDIOC_PRIVATE)];

struct mutex *lock;

};

v4l2_device

struct v4l2_device {

struct device *dev;

struct media_device *mdev;

struct list_head subdevs; //用于追蹤已注冊(cè)的subdev

spinlock_t lock;

char name[V4L2_DEVICE_NAME_SIZE]; //設(shè)備名

void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg);

struct v4l2_ctrl_handler *ctrl_handler; //控制句柄

struct v4l2_prio_state prio; //設(shè)備的優(yōu)先狀態(tài)

struct kref ref; //引用

void (*release)(struct v4l2_device *v4l2_dev);//引用計(jì)數(shù)為0后調(diào)用

};

嵌入到video_device中,表示一個(gè)v4l2設(shè)備實(shí)例。

v4l2_subdev

struct v4l2_subdev {

#if defined(CONFIG_MEDIA_CONTROLLER);

struct media_entity entity;

#endif;

struct list_head list; //subdev列表

struct module *owner;

bool owner_v4l2_dev;

u32 flags;

struct v4l2_device *v4l2_dev; //依附的v4l2_device

const struct v4l2_subdev_ops *ops; //subdev操作函數(shù)

const struct v4l2_subdev_internal_ops *internal_ops;

struct v4l2_ctrl_handler *ctrl_handler; //控制句柄

char name[V4L2_SUBDEV_NAME_SIZE]; //subdev名稱

u32 grp_id;

void *dev_priv;

void *host_priv;

struct video_device *devnode;

struct device *dev;

struct fwnode_handle *fwnode;

struct list_head async_list;

struct v4l2_async_subdev *asd;

struct v4l2_async_notifier *notifier;

struct v4l2_async_notifier *subdev_notifier;

struct v4l2_subdev_platform_data *pdata;//subdev平臺(tái)數(shù)據(jù)

};

依附在一個(gè)v4l2_device下面,并表示一個(gè)v4l2設(shè)備的子設(shè)備,v4l2_device下可以有多個(gè)sub_device。

v4l2_fh

struct v4l2_fh {

struct list_head list; //文件句柄列表

struct video_device *vdev; //依附的video_device

struct v4l2_ctrl_handler *ctrl_handler;

enum v4l2_priority prio; //文件句柄的優(yōu)先級(jí)

wait_queue_head_t wait;

struct mutex subscribe_lock;

struct list_head subscribed; //訂閱的事件列表

struct list_head available; //可用的事件

unsigned int navailable; //可用的事件數(shù)

u32 sequence;

struct v4l2_m2m_ctx *m2m_ctx;

};

追蹤的文件句柄用于

v4l2_device和v4l2_subdev的關(guān)系:

subdev 的設(shè)計(jì)目的是為了多路復(fù)用,就是控制使用一個(gè)v4l2_device可以掛接多個(gè)v4l2_subdev。這樣的多路復(fù)用就是一個(gè)攝像頭來多個(gè)攝像頭。手機(jī)和后置攝像頭。

在V4L2驅(qū)動(dòng)中,使用v4l2_device來表示攝像頭攝像頭(ISP)。使用v4l2_subdev來表示具體的某個(gè)攝像頭(Sensor)。

v4l2_file_operations

//V4L2設(shè)備操作函數(shù)

struct v4l2_file_operations {

struct module *owner;

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

__poll_t (*poll) (struct file *, struct poll_table_struct *);

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

#ifdef CONFIG_COMPAT;

long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);

#endif;

unsigned long (*get_unmapped_area) (struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

int (*mmap) (struct file *, struct vm_area_struct *);

int (*open) (struct file *);

int (*release) (struct file *);

};

v4l2_ioctl_ops

//IOCTL操作函數(shù)

struct v4l2_ioctl_ops {

......

int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i);

int (*vidioc_g_fbuf)(struct file *file, void *fh, struct v4l2_framebuffer *a);

int (*vidioc_s_fbuf)(struct file *file, void *fh, const struct v4l2_framebuffer *a);

int (*vidioc_streamon)(struct file *file, void *fh, enum v4l2_buf_type i);

int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i);

......

int (*vidioc_enum_framesizes)(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize);

int (*vidioc_enum_frameintervals)(struct file *file, void *fh, struct v4l2_frmivalenum *fival);

int (*vidioc_s_dv_timings)(struct file *file, void *fh, struct v4l2_dv_timings *timings);

int (*vidioc_g_dv_timings)(struct file *file, void *fh, struct v4l2_dv_timings *timings);

int (*vidioc_query_dv_timings)(struct file *file, void *fh, struct v4l2_dv_timings *timings);

int (*vidioc_enum_dv_timings)(struct file *file, void *fh, struct v4l2_enum_dv_timings *timings);

int (*vidioc_dv_timings_cap)(struct file *file, void *fh, struct v4l2_dv_timings_cap *cap);

int (*vidioc_g_edid)(struct file *file, void *fh, struct v4l2_edid *edid);

int (*vidioc_s_edid)(struct file *file, void *fh, struct v4l2_edid *edid);

int (*vidioc_subscribe_event)(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub);

int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub);

long (*vidioc_default)(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg);

};

v4l2_subdev_ops

//subdev操作函數(shù)

struct v4l2_subdev_ops {

const struct v4l2_subdev_core_ops *core; //subdev核心操作回調(diào)

const struct v4l2_subdev_tuner_ops *tuner; //radio模式打開v4l設(shè)備時(shí)的操作回調(diào)

const struct v4l2_subdev_audio_ops *audio; //音頻相關(guān)設(shè)置回調(diào)

const struct v4l2_subdev_video_ops *video; //video模式打開v4l設(shè)備時(shí)的操作回調(diào)

const struct v4l2_subdev_vbi_ops *vbi; //通過vbi設(shè)備節(jié)點(diǎn)以video模式打開v4l設(shè)備時(shí)的操作回調(diào)

const struct v4l2_subdev_ir_ops *ir; //IR(紅外)設(shè)備操作函數(shù)

const struct v4l2_subdev_sensor_ops *sensor; //sensor操作函數(shù)

const struct v4l2_subdev_pad_ops *pad; //pad操作函數(shù)

};

v4l22,所以多部分可以輕松地根據(jù)實(shí)際設(shè)備的需要實(shí)現(xiàn)的設(shè)備。

上面的_ioctl_ops中實(shí)現(xiàn)的部分ioctl最終到v4l2_dev_ops中的調(diào)用子函數(shù)。

API函數(shù)

//注冊(cè)/注銷video_device

int video_register_device(struct video_device *vdev, enum vfl_devnode_type type, int nr)

void video_unregister_device(struct video_device *vdev)

//分配/釋放video_device

struct video_device * __must_check video_device_alloc(void);

void video_device_release(struct video_device *vdev)

//注冊(cè)/注銷v4l2_device

int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)

void v4l2_device_unregister(struct v4l2_device *v4l2_dev)

//注冊(cè)/注銷v4l2_subdev(關(guān)聯(lián)v4l2_device和v4l2_subdev)

int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, struct v4l2_subdev *sd)

void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)

//初始化v4l2_subdev

void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops);

/********************************I2C subdev*************************************/

//初始化v4l2_subdev, 該subdev是I2C設(shè)備

void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,

const struct v4l2_subdev_ops *ops)

/*******************************SPI subdev************************************************/

//初始化v4l2_subdev, 該subdev是SPI設(shè)備

void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,

const struct v4l2_subdev_ops *ops)



審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11511

    瀏覽量

    213830
  • 攝像頭
    +關(guān)注

    關(guān)注

    61

    文章

    4982

    瀏覽量

    98393
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    317

    瀏覽量

    22406
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Linux之PWM驅(qū)動(dòng)

    本文主要講述了Linux的PWM驅(qū)動(dòng)框架、實(shí)現(xiàn)方法、驅(qū)動(dòng)添加方法和調(diào)試方法。
    發(fā)表于 05-25 09:19 ?898次閱讀
    <b class='flag-5'>Linux</b>之PWM<b class='flag-5'>驅(qū)動(dòng)</b>

    linux驅(qū)動(dòng)框架

    驅(qū)動(dòng)程序的框架有了大致的了解,感覺花了這么長(zhǎng)的時(shí)間值得,以后的框架就能了解了。明天獨(dú)立寫再次編寫led驅(qū)動(dòng)程序。Led驅(qū)動(dòng)程序代碼(firs
    發(fā)表于 03-20 12:44

    linux驅(qū)動(dòng)框架是什么

    編寫linux驅(qū)動(dòng)先看一下驅(qū)動(dòng)框架是什么樣子的。驅(qū)動(dòng)編寫和應(yīng)用層編寫有什么區(qū)別呢?
    發(fā)表于 07-26 08:14

    Linux下的UART驅(qū)動(dòng)框架詳解

    Linux下的UART驅(qū)動(dòng)框架
    發(fā)表于 12-22 07:18

    Linux 驅(qū)動(dòng) = 軟件框架 + 硬件操作

    ??Linux 驅(qū)動(dòng) = 軟件框架 + 硬件操作??驅(qū)動(dòng)程序依賴于 Linux 內(nèi)核,你開發(fā)板
    發(fā)表于 12-17 07:11

    OpenHarmony相機(jī)用戶態(tài)驅(qū)動(dòng)框架

    Linux采用的開源協(xié)議具有傳染性[1],導(dǎo)致Android HAL[2]成為了手機(jī)廠商們競(jìng)爭(zhēng)的重要戰(zhàn)場(chǎng)。隨著OpenHarmony 3.1[3]的發(fā)布,相機(jī)模塊也逐漸完善起來,目前提供了基礎(chǔ)預(yù)覽和拍照的能力
    發(fā)表于 04-20 17:09

    想要駕馭Linux驅(qū)動(dòng)開發(fā),必須深刻理解Linux總線設(shè)備驅(qū)動(dòng)框架

    想要駕馭Linux驅(qū)動(dòng)開發(fā),必須深刻理解Linux總線設(shè)備驅(qū)動(dòng)框架。之所以會(huì)形成這樣的框架,主要
    的頭像 發(fā)表于 03-22 11:08 ?1.1w次閱讀
    想要駕馭<b class='flag-5'>Linux</b><b class='flag-5'>驅(qū)動(dòng)</b>開發(fā),必須深刻理解<b class='flag-5'>Linux</b>總線設(shè)備<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>框架</b>

    Linux DMA Engine框架的介紹

    此會(huì)話描述如何從設(shè)備驅(qū)動(dòng)程序在Linux中使用DMA。 這包括內(nèi)存分配,緩存控制和DMA設(shè)備控制。 詳細(xì)介紹了Linux DMA Engine框架
    的頭像 發(fā)表于 11-23 06:29 ?6725次閱讀

    你對(duì)Linux總線設(shè)備驅(qū)動(dòng)框架是否了解

    Linux的設(shè)備驅(qū)動(dòng)模型,或者說,Linux的設(shè)備驅(qū)動(dòng)框架,都是同一個(gè)意思。應(yīng)該這樣理解,(Linux
    發(fā)表于 05-05 15:13 ?883次閱讀

    如何使用Linux內(nèi)核實(shí)現(xiàn)USB驅(qū)動(dòng)程序框架

    Linux內(nèi)核提供了完整的USB驅(qū)動(dòng)程序框架。USB總線采用樹形結(jié)構(gòu),在一條總線上只能有唯一的主機(jī)設(shè)備。 Linux內(nèi)核從主機(jī)和設(shè)備兩個(gè)角度
    發(fā)表于 11-06 17:59 ?20次下載
    如何使用<b class='flag-5'>Linux</b>內(nèi)核實(shí)現(xiàn)USB<b class='flag-5'>驅(qū)動(dòng)</b>程序<b class='flag-5'>框架</b>

    嵌入式Linux驅(qū)動(dòng)開發(fā)從基礎(chǔ)到框架

    想講好嵌入式Linux驅(qū)動(dòng)開發(fā)并不容易,各位業(yè)界大神最基礎(chǔ)的字符驅(qū)動(dòng)到中斷并發(fā)再到驅(qū)動(dòng)框架、應(yīng)用層調(diào)用。但是總覺得業(yè)界寫的書都是點(diǎn)到為止,
    發(fā)表于 11-01 16:58 ?15次下載
    嵌入式<b class='flag-5'>Linux</b><b class='flag-5'>驅(qū)動(dòng)</b>開發(fā)從基礎(chǔ)到<b class='flag-5'>框架</b>

    Linux內(nèi)核中視頻設(shè)備驅(qū)動(dòng)框架V4L2X詳解

    V4L2(Video for Linux 2):Linux內(nèi)核中關(guān)于視頻設(shè)備驅(qū)動(dòng)框架,對(duì)上向應(yīng)用層提供統(tǒng)一的接口,對(duì)下支持各類復(fù)雜硬件的靈
    的頭像 發(fā)表于 05-30 16:18 ?6990次閱讀

    Linux的PWM驅(qū)動(dòng)框架及實(shí)現(xiàn)方法

    本文主要講述了Linux的PWM驅(qū)動(dòng)框架、實(shí)現(xiàn)方法、驅(qū)動(dòng)添加方法和調(diào)試方法。
    的頭像 發(fā)表于 05-14 15:24 ?1875次閱讀
    <b class='flag-5'>Linux</b>的PWM<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>框架</b>及實(shí)現(xiàn)方法

    Linux驅(qū)動(dòng)分析之RTC框架

    當(dāng)Linux內(nèi)核啟動(dòng)時(shí),它會(huì)從RTC中讀取時(shí)間與日期,作為基準(zhǔn)值。然后通過軟件來維護(hù)系統(tǒng)時(shí)間和日期。Linux系統(tǒng)中提供了RTC核心層,對(duì)于驅(qū)動(dòng)開發(fā)者而言,操作起來就變得很簡(jiǎn)單了。我們
    的頭像 發(fā)表于 05-26 15:12 ?1242次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>驅(qū)動(dòng)</b>分析之RTC<b class='flag-5'>框架</b>

    Linux Regmap 驅(qū)動(dòng)框架

    ,regmap 向驅(qū)動(dòng)編寫人員提供的 API 接口,驅(qū)動(dòng)編寫人員使用這些API 接口來操作具體的芯片設(shè)備,也是驅(qū)動(dòng)編寫人員重點(diǎn)要掌握的。 2、regmap 結(jié)構(gòu)體
    的頭像 發(fā)表于 07-06 17:29 ?1433次閱讀
    <b class='flag-5'>Linux</b> Regmap <b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>框架</b>