5 struct v4l2_subdev

v4l2_device下面一个层次是v4l2_subdev,它需要和它的子设备进行通信,如果说camera

host是一个v4l2_device设备,那么就可以将camera模组称为一个v4l2_subdev设备,它们之间的通信可以采取多种方式常见的有I2C和SPI.

通常这些子设备都属于I2C设备,当然也有其他接口的比如SPI

Interface,为了给驱动程序提供一个一致性的接口,Linux内核为这些设备抽象出了一个struct

v4l2_subdev结构来描述一个v4l2

sub device,所以每个v4l2

sub-device都需要一个struct

v4l2_subdev结构实例,该结构的定义如下:

include/media/v4l2-subdev.h

点击(此处)折叠或打开

/* Each instance of a subdev driver should create this struct, either

stand-alone or embedded in a larger struct.

*/

struct v4l2_subdev {

#if defined(CONFIG_MEDIA_CONTROLLER)/*这系列文章暂不针对media多媒体设备*/

struct media_entity entity;

#endif

struct list_head list;      /*用于管理每个子设备*/

struct module *owner;       /*指向i2c_lient driver module*/

/*该子设备属于那种设备(如I2C),see V4L2_SUBDEV_FL_IS_XX and */

u32 flags;        /*是否包含设备节点 V4L2_SUBDEV_FL_HAS_DEVNODE 有设备节点*/

struct v4l2_device *v4l2_dev;

const struct v4l2_subdev_ops *ops;

/* Never call these internal ops from within a */

const struct v4l2_subdev_internal_ops *internal_ops;

/* The control handler of this subdev. May be NULL. */

struct v4l2_ctrl_handler *ctrl_handler;

/* name must be unique */

char name[V4L2_SUBDEV_NAME_SIZE];/*该模组的名字*/

/* can be used to group similar subdevs, value is driver-specific */

u32 grp_id;

/* pointer to private data */

void *dev_priv;              /*eg. point i2c_client data struct*/

void *host_priv;             /*eg. point camera host data struct*/

/* subdev device node */

struct video_device devnode;/*指向video device设备实例,后面会详细介绍*/

/* number of events to be allocated on open */

unsigned int nevents;

};

u32

flags:flags字段用于标志该sub_devs属于那一种设备(如I2C,SPI),另外还标致着该子设备是否产生设备节点,它一共有四种取值;V4L2_SUBDEV_FL_IS_I2C,V4L2_SUBDEV_FL_IS_SPI,

V4L2_SUBDEV_FL_HAS_DEVNODE,V4L2_SUBDEV_FL_HAS_EVENTS

v4l2_dev:指向struct

v4l2_device结构,在v4l2_subdev的注册过程会将该指针指向前面注册过的v4l2_device设备结构;

ops:指向struct

v4l2_subdev_ops *ops函数结构指针,这个结构指针是需要我们在sub

device模组驱动中去实现的;

dev_priv:如果该设备为I2C设备,则该字段用于保存i2c_client结构

host_priv:用于保存camera

host数据结构.

devnode:指向video设备结构实例

每一个subdev驱动程序都应该创建一个struct

v4l2_subdev结构实例,你可以在你的驱动程序中单独的为该结构申请内存,同样可以将这个结构嵌入到其他的驱动数据结构中去.一般性的我们将该结构嵌入到camera

sensor模组驱动的数据结构中去,同样为了该sub

device和i2c

client之间的相互引用,我们还常把i2c_client结构嵌入到模组驱动数据结构中去系统为我们提供了2个API,用于struct

v4l2_subdev结构和该子设备所属的设备类型(如I2C,SPI)等数据结构之间的相互引用,定义如下:

点击(此处)折叠或打开

static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)

{

sd->dev_priv = p;

}

你可以简单的调用v4l2_set_subdevdata(sd,

client)就可以将i2c_client结构保存到struct

v4l2_subdev结构中的dev_priv字段中去,这样你下次使用的时候只需要调用下面这个API就可以返回你保存过的i2c_client结构

同样的对于struct

v4l2_subdev结构的camera

host端,内核也为我们提供了两个API用于它和hos驱动结构之间的相互引用

点击(此处)折叠或打开

static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p)

{

sd->host_priv = p;

}

这样你只要简单的调用v4l2_set_subdev_hostdata()就可以将camera

host那端的数据结构保存到struct

v4l2_subdev结构的host_priv字段,在另一地方要引用camera

host对应的数据结构的时候之需要调用v4l2_get_subdev_hostdata就可以返回了

5.1

v4l2_subdev initialized

一个子设备驱动使用如下函数初始化v4l2_subdev结构:

点击(此处)折叠或打开

v4l2_subdev_init(sd, &ops);

点击(此处)折叠或打开

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

{

INIT_LIST_HEAD(&sd->list);

BUG_ON(!ops);

sd->ops = ops;

sd->v4l2_dev = NULL;

sd->flags = 0;

sd->name[0] = '\0';

sd->grp_id = 0;

sd->dev_priv = NULL;

sd->host_priv = NULL;

#if defined(CONFIG_MEDIA_CONTROLLER)

sd->entity.name = sd->name;

sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;

#endif

}

其中的subdev->name字段是需要我们去初始化的,并且还需要设置这个module

owner,对于I2C设备系统为我们提供了相应的v4l2_i2c_subdev_init接口来初始化一个subdev子模块,这个接口实现如下:drivers/media/video/v4l2-common.c

点击(此处)折叠或打开

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

const struct v4l2_subdev_ops *ops)

{

v4l2_subdev_init(sd, ops);/*初始化struct v4l2_subdev结构,绑定操作函数指针*/

sd->flags |= V4L2_SUBDEV_FL_IS_I2C;/*设置该标志,指定该模组设备属于I2C设备*/

/* the owner is the same as the i2c_client's driver owner */

sd->owner = client->driver->driver.owner;/*init the sd->owner*/

/* i2c_client and v4l2_subdev point to one another */

v4l2_set_subdevdata(sd, client);

i2c_set_clientdata(client, sd);

/* 初始化subdev结构的name字段*/

snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",

client->driver->driver.name, i2c_adapter_id(client->adapter),

client->addr);

}5.2

v4l2_subdev register:

一个设备v4l2_subdev驱动需要将v4l2_subdev结构注册到v4l2_device当中去(也就是将struct

v4l2_subdev和struct

v4l2_device结构关联起来)使用如下API:

点击(此处)折叠或打开

int err = v4l2_device_register_subdev(v4l2_dev, sd);

删除一部分信息,留下一部分我比较关注的信息这个API的实现如下:

点击(此处)折叠或打开

int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,

struct v4l2_subdev *sd)

{

int err;

/* Check for valid input */

if (v4l2_dev == NULL || sd == NULL || !sd->name[0])

return -EINVAL;

/* 检测是否重复注册 */

WARN_ON(sd->v4l2_dev != NULL);

/*通过try_module_get去获取sub_dev所属的内核模块是否已经成功被加载

*如果该sub_dev所属的内核模块还未被成功注册进内核则返回ENODEV

*try_module_get通过回调module_is_live来判断sd->owner的状态

*/

if (!try_module_get(sd->owner))

return -ENODEV;

/*关联v4l2_dev*/

sd->v4l2_dev = v4l2_dev;

/*将v4l2_subdev结构中的list链表挂到v4l2_device结构中的subdevs链表中去*/

spin_lock(&v4l2_dev->lock);

list_add_tail(&sd->list, &v4l2_dev->subdevs);

spin_unlock(&v4l2_dev->lock);

return 0;

}

现在你再返回去看这两个结构体,很明显子设备的注册就是将struct

v4l2_subdev结构中的list链表字段追加到struct

v4l2_device结构中的subdevs链表尾中.如果子设备模块在它成功注册之前消失了,那这个注册函数肯定会失败的。这个函数成功执行之后,这样subdev->dev就会指向v4l2_device。于是就关联起来了。

5.3

v4l2_subdev unregister:

通过\如下函数注销掉之前注册的子设备:

点击(此处)折叠或打开

v4l2_device_unregister_subdev(sd);

在这个函数执行之后,子设备模块将被卸载并且sd->dev==NULL;

点击(此处)折叠或打开

void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)

{

struct v4l2_device *v4l2_dev;

/* return if it isn't registered */

if (sd == NULL || sd->v4l2_dev == NULL)

return;

v4l2_dev = sd->v4l2_dev;

/*将v4l2_subdev结构中的list链表从v4l2_device结构的subdevs链表中删除*/

spin_lock(&v4l2_dev->lock);

list_del(&sd->list);

spin_unlock(&v4l2_dev->lock);

/*最后注销设备节点*/

video_unregister_device(&sd->devnode);

module_put(sd->owner);

}5.4

v4l2_subdev_xxx_ops:

每个v4l2_subdev结构包含了若干函数指针,子设备驱动可以实现这些函数(或者让它为NULL,如果不用到它的话)。这些函数指针已经按照分类排序,并且每个分类具有它自己的ops结构体。顶层的(top-level)的ops结构体包含了到分类ops结构体的指针,它们可以是NULL,如果子设备驱动(subdev

driver)不支持这个分类的功能。

点击(此处)折叠或打开

struct v4l2_subdev_ops {

const struct v4l2_subdev_core_ops *core;        /*共用*/

const struct v4l2_subdev_tuner_ops *tuner;

const struct v4l2_subdev_audio_ops *audio;

const struct v4l2_subdev_video_ops *video;   /*video设备*/

};

下面我们主要来分析v4l2_subdev_ops结构指针中的core和video结构指针,核心ops(core_ops)是所有子设备(subdevs)公用的,其他分类的ops是否使用取决于子设备。例如,一个视频设备不太可能去支持一个audio

ops和vice

versa;

点击(此处)折叠或打开

struct v4l2_subdev_core_ops {

int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);

int (*init)(struct v4l2_subdev *sd, u32 val);

int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);

int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);

int (*g_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);

int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);

long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);

...

};

上面这个结构是我们在摄像头sensor模组驱动中要实现的精华部分,操作摄像头sensor就是通过这些接口来完成的,当然上面这些只是v4l2_subdev_core_ops一部分成员,下面结合v4l2子系统中的一些结构来简单的学习一下这些函数指针的使用

5.5.1

chip identifier

点击(此处)折叠或打开

struct v4l2_dbg_chip_ident {

struct v4l2_dbg_match match;

__u32 ident; /* chip identifier as specified in */

__u32 revision; /* chip revision, chip specific 0 */

} __attribute__ ((packed));

match:用于匹配,如果sensor是i2c设备那么里面保存着该设备的地址和名字,通过i2c地址以及设备名字来匹配

ident:我们每移植一款sensor设备,都需要在media/v4l2-chip-ident.h文件中声明一个唯一的标识符,用来说明你这套代码支持该sensor

revision:0

通过VIDIOC_DBG_G_CHIP_IDENT命令来枚举该结构int

(*g_chip_ident)函数指针的通用实现如下:

点击(此处)折叠或打开

static int sensor_g_chip_ident(struct v4l2_subdev *sd,

struct v4l2_dbg_chip_ident *id)

{

struct i2c_client *client = v4l2_get_subdevdata(sd);

/*Match against I2C 7-bit address*/

if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)

return -EINVAL;

/*sensor设备从地址*/

if (id->match.addr != client->addr)

return -ENODEV;

id->ident = SENSOR_V4L2_IDENT;/*这个就是我们自己添加的*/

id->revision = 0;

return 0;

}

在驱动的初始化阶段,可以通过v4l2_subdev_call(sd,

core, g_chip_ident, id)来回调该函数指针来匹配驱动是否支持该sensor

5.5.2

sensor initialized

每个v4l2_subdev设备都需要初始化,调过摄像头的朋友都知道,没个sensor都有N多的初始化代码,这些初始化信息就是由camera

host通过v4l2_subdev_call(sd,core,

init,

0)来回调init函数指针将初始化代码段写进sensor芯片内,这些初始化信息包括sensor所支持的功能,如亮度调节,白平衡,聚焦,照片的像素等等的一系列信息。当然这部分信息一般由FAE提供。

5.5.3

v4l2 control

对于相机有很多的功能,我们需要对它们进行操作,比如说调焦,白平衡,效果调节等等.用户空间程序中通过VIDIOC_QUERYCTRL命令来枚举下面结构,获取可用的控制操作相应的由驱动程序中的vidioc_queryctrl()方法来实现用户空间的ioctl操作。该函数指针的原型如下:include/media/v4l2-ioctl.h

点击(此处)折叠或打开

int (*vidioc_queryctrl) (struct file *file, void *fh,

struct v4l2_queryctrl *a);

v4l2_queryctrl结构的定义如下:include/linux/video2.h

点击(此处)折叠或打开

/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */

struct v4l2_queryctrl {

__u32         id;

enum v4l2_ctrl_type type;

__u8         name[32];    /* Whatever */

__s32         minimum;    /* Note signedness */

__s32         maximum;

__s32         step;

__s32         default_value;

__u32 flags;

__u32         reserved[2];

};

这个结构包含了许多字段,下面一个一个分析

id:每一个功能都有一个唯一的ID,它们都形如V4L2_CID_XXX,定义在include/linux/video2.h中,比较常见的有如下几种

V4L2_CID_DO_WHITE_BALANCE/*白平衡*/

V4L2_CID_EFFECT/*效果*/

V4L2_CID_FLASH/*闪光灯*/

V4L2_CID_BRIGHTNESS/*亮度*/

V4L2_CID_EXPOSURE/*曝光*/

V4L2_CID_SATURATION/*色彩饱和度*/

V4L2_CID_CONTRAST/*对比度*/

V4L2_CID_HFLIP/*水平镜像*/

V4L2_CID_VFLIP/*垂直镜像*/

V4L2_CID_SCENE/*场景,白天黑夜*/

V4L2_CID_FOCUS_AUTO/*自动聚焦*/

V4L2_CID_FOCUS_RELATIVE/*相对聚焦*/

V4L2_CID_FOCUS_ABSOLUTE/*绝对聚焦*/

V4L2_CID_FOCUS_CONTINUOUS/*持续聚焦*/

V4L2_CID_ZOOM_RELATIVE/*数字变焦*/

V4L2_CID_ZOOM_ABSOLUTE

name:控制名字如Focus

Control只是一个标识,可以随意填\

minimum:支持调节的最小值

maximum:支持调节的最大值

step:每次调节的步进

default_value:默认值在minimum和maximum之间(对整型、布尔型和菜单控制适用)

type:该字段表明了一组固定的选项,针对没一组固定的选项定义了如下枚举结构

点击(此处)折叠或打开

enum v4l2_ctrl_type {

V4L2_CTRL_TYPE_INTEGER     = 1,

V4L2_CTRL_TYPE_BOOLEAN     = 2,

V4L2_CTRL_TYPE_MENU          = 3,    /*菜单型的*/

V4L2_CTRL_TYPE_BUTTON     = 4,

V4L2_CTRL_TYPE_INTEGER64 = 5,

V4L2_CTRL_TYPE_CTRL_CLASS = 6,

V4L2_CTRL_TYPE_STRING = 7,

};

flags:表示控制的标志,有如下定义

V4L2_CTRL_FLAG_DISABLED/*控制操作不可用,应用应忽略它*/

V4L2_CTRL_FLAG_GRABBED/*控制暂时不可变,可能是因为另一个应用正在使用*/

V4L2_CTRL_FLAG_READ_ONLY

/*可以查看,但不可以操作*/

V4L2_CTRL_FLAG_UPDATE

/*调整这个参数可以会对其他控指造成影响*/

V4L2_CTRL_FLAG_INACTIVE

/*与当前设备配置无关的操作*/

V4L2_CTRL_FLAG_SLIDER

/*暗示应用在使用这个操作的时候可以使用类似滚动条的接口*/

V4L2_CTRL_FLAG_WRITE_ONLY

当然该结构可以代表那么多的功能是用id字段来区分的,对于菜单型的诸多控制操作来说(type=V4L2_CTRL_TYPE_MENU)用户空间程序可以使用VIDIOC_QUERYMENU命令通过驱动程序当中的vidioc_querymenu函数来完成相应的ioctl操作

点击(此处)折叠或打开

int (*vidioc_querymenu)(struct file *file, void *fh,

struct v4l2_querymenu *a);

struct

v4l2_querymenu结构的定义如下:

点击(此处)折叠或打开

/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */

struct v4l2_querymenu {

__u32        id;

__u32        index;

__u8        name[32];    /* Whatever */

__u32        reserved;/*永远都等于0*/

};

id:相关控制菜单的ID值和上面v4l2_queryctrl结构中的ID是保持一致的这更进一步表明了可用控制的遍历过程

index:菜单ID值的索引(每打开一个菜单是不是有很长的一列?就是这个),从0开始一直到上面那个结构定义的maximum字段为止

name:由驱动程序填充(并出现在菜单中,比如android系统中的闪光灯中的auto,on,off..)

到这里应用程序已经遍历到驱动中支持的可用操作了,现在我们可以对它进行查询已经操作了,对于这些操作v4l2定义了如下结构:

点击(此处)折叠或打开

/*

*    include/linux/video2.h

*/

struct v4l2_control {

__u32         id;

__s32         value;

};

现在假设我们要查询某一个可用操作,当然这是由用户空间通过VIDIOC_G_CTRL命令发出的,在我们的驱动程序中由vidioc_g_ctrl函数指针来响应这个命令,最后回调v4l2_subdev中的函数指针g_ctrl来实现这个命令(再回首5.1中的那个pos),这两个函数指针的原型分别是:

点击(此处)折叠或打开

int (*vidioc_g_ctrl)(struct file *file, void *fh, struct v4l2_control *a);

int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);

从它们的原型我们可以知道,用户空间通过对设备文件节点的操作,最后转化到实际硬件的操作,懂linux的朋友一定很清晰,如果查询的操作不存在将返回-EINVAL,如果查询成功则返回当前控制设定的值.

如果我们试图在上层通过按钮试图改变当前的控制,比如说把曝光调大或小一点,则在用户空间通过发送VIDIOC_S_CTRL命令请求来实现,在驱动中对应的vidioc_s_ctrl函数指针首先相应该请求,最后通过会调用v4l2_subdev中对应的s_ctrl函数指针来操作相应的sensor硬件,它们的原型分别是:

点击(此处)折叠或打开

int (*vidioc_s_ctrl)(struct file *file, void *private_data,

struct v4l2_control *ctrl);

int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);

对于具体的操作我们可以查看V4L2应用API官方文档:这些ioctl属于user

contrl,除此之外还有其他一些扩展控制,扩展控制可以同时原子的对多个ID进行控制,在用户空间程序中使用ioctl配套的三个命令如下:VIDIOC_G_EXT_CTRLS,

VIDIOC_S_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS如果操作成功则返回0否则返回EINVAL,驱动中对应的v4l2_device函数指针如下:

点击(此处)折叠或打开

int (*vidioc_g_ext_ctrls) (struct file *file, void *fh,

struct v4l2_ext_controls *a);

int (*vidioc_s_ext_ctrls) (struct file *file, void *fh,

struct v4l2_ext_controls *a);

int (*vidioc_try_ext_ctrls) (struct file *file, void *fh,

struct v4l2_ext_controls *a);

驱动中对应的v4l2_subdev中的ops函数指针如下:

点击(此处)折叠或打开

int (*g_ext_ctrls)(struct v4l2_subdev *sd,

struct v4l2_ext_controls *ctrls);

int (*s_ext_ctrls)(struct v4l2_subdev *sd,

struct v4l2_ext_controls *ctrls);

int (*try_ext_ctrls)(struct v4l2_subdev *sd,

struct v4l2_ext_controls *ctrls);

struct

v4l2_ext_controls结构的应以如下:include/linux/video2.h

点击(此处)折叠或打开

struct v4l2_ext_controls {

__u32 ctrl_class;

__u32 count;

__u32 error_idx;

__u32 reserved[2];//0

struct v4l2_ext_control *controls;

};

ctrl_class:控制类,每一种类代表一种特性,如CLASS_USER,CLASS_MPEG等等

count:controls数组的个数

controls:指向struct

v4l2_ext_control结构

对于__u32

ctrl_class字段有如下定义

点击(此处)折叠或打开

/* Values for ctrl_class field */

V4L2_CTRL_CLASS_USER     /*'user' controls VIDIOC_G_CTRL和VIDIOC_S_CTRL属于该范畴*/

V4L2_CTRL_CLASS_MPEG         /*MPEG-compression controls */

V4L2_CTRL_CLASS_CAMERA     /* Camera class controls */

V4L2_CTRL_CLASS_FM_TX     /* FM Modulator control class */

V4L2_CTRL_CLASS_JPEG          /*JPEG compression controls*/

V4L2_CTRL_CLASS_IMAGE_SOURCE     /*Image source controls*/

V4L2_CTRL_CLASS_IMAGE_PROC    /*Image processing controls*/

具体的意思可以通过V4L2提供的官方文档查看:

struct

v4l2_ext_control结构的定义如下:

点击(此处)折叠或打开

struct v4l2_ext_control {

__u32 id;

__u32 size;

__u32 reserved2[1];/*0*/

union {

__s32 value;

__s64 value64;

char *string;

};

} __attribute__ ((packed));

id:Identifies

the control,和上面结构中的ID一样

value:就是要控制值应该和v4l2_querymenu结构中的index字段保持一致

上面这些控制都是一些功能特效的控制,属于基本控制.对于subdev还有许多的内容需要修改,比如流控等,一些数据的格式,这需要和camera

host配合控制这将在后面再进行说明

linux media v4l2,Overview of the V4L2 driver framework (v4l2_subdev)相关推荐

  1. 嵌入式linux环境视频采集知识(V4L2)

    Video for Linux two(Video4Linux2)简称V4L2,是V4L的改进版.V4L2是linux操作系统下用于采集图片.视频和音频数据的API接口,配合适当的视频采集设备和相应的 ...

  2. 嵌入式Linux驱动笔记(十八)------浅析V4L2框架之ioctl【转】

    转自:https://blog.csdn.net/Guet_Kite/article/details/78574781 权声明:本文为 风筝 博主原创文章,未经博主允许不得转载!!!!!!谢谢合作 h ...

  3. 浅谈Linux media framework

    基本概念 通过调试camera过程中对接触的v4l2,意外发现了Linux一个不是很起眼的子系统--Linux media framework,那它存在的意义是什么? 节选一段来自Linux源码中的文 ...

  4. Linux ALSA 之八:ALSA ASOC Platform Driver

    ALSA ASOC Platform Driver 一.Platform 驱动作用 二.ASOC Platform Driver 代码分析 2.1 Linux Platform Driver & ...

  5. linux设备驱动目录,Linux设备模型(5)_device和device driver

    Linux设备模型(5)_device和device driver 作者:wowo 发布于:2014-4-2 19:28 分类:统一设备模型 1. 前言 device和device driver是Li ...

  6. linux media v4l2,Linux kernel drivers/media/v4l2-core/videobuf2-v4l2.c拒绝服务漏洞(CVE-2016-4568)...

    Linux kernel drivers/media/v4l2-core/videobuf2-v4l2.c拒绝服务漏洞(CVE-2016-4568) 发布日期:2016-05-19 更新日期:2016 ...

  7. Linux下的视频采集(V4L2)

    写在前面的话:以下代码均是从自己的项目中摘出来的,类似调试打印,结构体都是自己定义的,需要修改后才能使用,需要源码的可直接到总结博客写一个自己的小型视频监控系统 最近两周加班有点多,趁着周末一些零碎时 ...

  8. v4l2视频采集驱动框架(vfe, camera i2c driver,v4l2_subdev等之间的联系)

    2014年的博文就从这篇文章开始吧,又一次回到linux,过去的一年从dm3730再到dm6437,这次来到了全志的A31 4核处理器,每一次都是全新的事物,但是偶然间还是可以感受到对新事物的消化能力 ...

  9. <Linux> Linux Power Management Overview

    Overview Generic PM 传统意义上的Power Management,如Power On/Off, Restart, Suspend to RAM/Disk等. Clock Frame ...

  10. linux安装系统前安装驱动(driver)方法

    在Cent OS 下装HBA/Raid card driver方法: 1.从安装盘启动: 2.进入系统菜单选择界面(一般有3个选项),迅速按下"E"键: 3.用键盘的方向键定位到& ...

最新文章

  1. SPQuery简单使用示例
  2. 常考数据结构和算法:合并有序链表
  3. spider RPC入门指南
  4. 为何出现Error Loading Midas.dll消息?
  5. 冒泡排序算法[C++]
  6. java 静态对象赋值_基于Java class对象说明、Java 静态变量声明和赋值说明(详解)...
  7. OpenJudge/Poj 1915 Knight Moves
  8. 审稿意见说我引言和结论写的毫无差别!
  9. java io流读取txt文件_Java使用IO流读取TXT文件
  10. (转) 淘淘商城系列——搜索服务搭建
  11. set容器内元素的访问
  12. 冲刺One之站立会议6 /2015-5-19
  13. 一文搞懂什么是禁忌搜索算法Tabu Search【附应用举例】
  14. 极速pdf android,极速PDF阅读器 V3.0.0.2003 官方版[安卓软件]
  15. raid之创建磁盘列阵raid-0
  16. Helio P10 (MT6755)
  17. Java中的程序计数器
  18. 高等数学(三) 极限
  19. [2016 T-EDGE]王坚对话无人机教父:创新就要享受走在悬崖边的刺激
  20. springboot整合全文搜索引擎Elasticsearch | Spring Boot 28

热门文章

  1. python--spilt和strip用法
  2. java 组件是什么意思_java中组件是什么意思?
  3. 谢烟客---------Linux之命令引入篇
  4. 如何使用GOOGLE高级搜索技巧
  5. HTML文本框内容发生变化时引发事件执行
  6. TPSHOP商城软件测试环境搭建过程
  7. 终端模拟器怎么用android命令大全,终端模拟器命令大全apk下载-终端模拟器刷入recovery手机版下载V1.0.70安卓最新版-西西软件下载...
  8. 反函数法生成服从特定概率密度函数的随机数
  9. vrp java_HCIA-VRP基础及操作
  10. 用python做餐厅点餐系统