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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux usb摄像头 源码,Linux USB摄像头驱动实现源码分析

發(fā)布時間:2025/4/16 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux usb摄像头 源码,Linux USB摄像头驱动实现源码分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Spac5xx的實現(xiàn)是按照標準的USB VIDEO設(shè)備的驅(qū)動框架編寫(其具體的驅(qū)動框架可參照/usr/src/linux/drivers/usb/usbvideo.c文件),整個源程序由四個主體部分組成:

設(shè)備模塊的初始化模塊和卸載模塊,上層軟件接口模塊,數(shù)據(jù)傳輸模塊。

具體的模塊分析如下:

一、初始化設(shè)備模塊

該驅(qū)動采用了顯式的模塊初始化和消除函數(shù),即調(diào)用module_init來初始化一個模塊,并在卸載時調(diào)用moduel-exit函數(shù)

其具體實現(xiàn)如下:

1、模塊初始化:

module_init (usb_spca5xx_init);

static int __init usb_spca5xx_init (void)

{

#ifdef CONFIG_PROC_FS

proc_spca50x_create ();//建立PROC設(shè)備文件

#endif /* CONFIG_PROC_FS */

if (usb_register (&spca5xx_driver) < 0) //注冊USB設(shè)備驅(qū)動

return -1;

info ("spca5xx driver %s registered", version);

return 0;

}

2、模塊卸載:

module_exit (usb_spca5xx_exit);

static void __exit usb_spca5xx_exit (void)

{

usb_deregister (&spca5xx_driver); //注銷USB設(shè)備驅(qū)動

info ("driver spca5xx deregistered");

#ifdef CONFIG_PROC_FS

proc_spca50x_destroy ();//撤消PROC設(shè)備文件

#endif /* CONFIG_PROC_FS */

}

關(guān)鍵數(shù)據(jù)結(jié)構(gòu)USB驅(qū)動結(jié)構(gòu),即插即用功能的實現(xiàn)

static struct usb_driver spca5xx_driver = {

"spca5xx",

spca5xx_probe, //注冊設(shè)備自我偵測功能

spca5xx_disconnect,//注冊設(shè)備自我斷開功能

{NULL,NULL}

};

用兩個函數(shù)調(diào)用spca5xx_probe 和spca5xx_disconnect來支持USB設(shè)備的即插即用功能:

a --?spca5xx_probe具體實現(xiàn)如下:

static void * spca5xx_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)

{

struct usb_interface_descriptor *interface; //USB設(shè)備接口描述符

struct usb_spca50x *spca50x; //物理設(shè)備數(shù)據(jù)結(jié)構(gòu)

int err_probe;

int i;

if (dev->descriptor.bNumConfigurations != 1) //探測設(shè)備是不是可配置

goto nodevice;

if (ifnum > 0)

goto nodevice;

interface = &dev->actconfig->interface[ifnum].altsetting[0];

MOD_INC_USE_COUNT;

interface = &intf->altsetting[0].desc;

if (interface->bInterfaceNumber > 0)

goto nodevice;

if ((spca50x = kmalloc (sizeof (struct usb_spca50x), GFP_KERNEL)) == NULL) //分配物理地址空間

{

err ("couldn't kmalloc spca50x struct");

goto error;

}

memset (spca50x, 0, sizeof (struct usb_spca50x));

spca50x->dev = dev;

spca50x->iface = interface->bInterfaceNumber;

if ((err_probe = spcaDetectCamera (spca50x)) < 0) //具體物理設(shè)備查找,匹配廠商號,設(shè)備號(在子程序中)

{

err (" Devices not found !! ");

goto error;

}

PDEBUG (0, "Camera type %s ", Plist[spca50x->cameratype].name)

for (i = 0; i < SPCA50X_NUMFRAMES; i++)

init_waitqueue_head (&spca50x->frame[i].wq); //初始化幀等待隊列

init_waitqueue_head (&spca50x->wq); //初始化驅(qū)動等待隊列

if (!spca50x_configure (spca50x)) //物理設(shè)備配置(主要完成傳感器偵測和圖形參數(shù)配置),主要思想是給控制寄存器寫值,讀回其返回值,以此判斷具體的傳感器型號

{

spca50x->user = 0;

init_MUTEX (&spca50x->lock); //信號量初始化

init_MUTEX (&spca50x->buf_lock);

spca50x->v4l_lock = SPIN_LOCK_UNLOCKED;

spca50x->buf_state = BUF_NOT_ALLOCATED;

}

else

{

err?("Failed?to?configure?camera");

goto?error;

}

/*?Init?video?stuff?*/

spca50x->vdev?=?video_device_alloc?();???????????//設(shè)備控制塊內(nèi)存分配

if?(!spca50x->vdev)

goto?error;

memcpy?(spca50x->vdev,?&spca50x_template,?sizeof?(spca50x_template));

//系統(tǒng)調(diào)用的掛接,在此將驅(qū)動實現(xiàn)的系統(tǒng)調(diào)用,掛到內(nèi)核中

video_set_drvdata?(spca50x->vdev,?spca50x);

if?(video_register_device?(spca50x->vdev,?VFL_TYPE_GRABBER,?video_nr)?

{

//video設(shè)備注冊

err?("video_register_device?failed");

goto?error;

}

spca50x->present?=?1;

if?(spca50x->force_rgb)

info?("data?format?set?to?RGB");

spca50x->task.sync?=?0;

spca50x->task.routine?=?auto_bh;

spca50x->task.data?=?spca50x;

spca50x->bh_requested?=?0;

MOD_DEC_USE_COUNT;?//增加模塊使用數(shù)

return?spca50x;?//返回數(shù)劇結(jié)構(gòu)

error://錯誤處理

if?(spca50x->vdev)

{

if?(spca50x->vdev->minor?==?-1)

video_device_release?(spca50x->vdev);

else

video_unregister_device?(spca50x->vdev);

spca50x->vdev?=?NULL;

}

if?(spca50x)

{

kfree?(spca50x);

spca50x?=?NULL;

}

MOD_DEC_USE_COUNT;

return?NULL;

nodevice:

return?NULL;

}

b -- Spca5xx_disconnect 的具體實現(xiàn)如下:

static void spca5xx_disconnect (struct usb_device *dev, void *ptr)

{

struct usb_spca50x *spca50x = (struct usb_spca50x *) ptr;

int n;

MOD_INC_USE_COUNT; //增加模塊使用數(shù)

if (!spca50x)

return;

down (&spca50x->lock); //減少信號量

spca50x->present = 0; //驅(qū)動卸載置0

for (n = 0; n < SPCA50X_NUMFRAMES; n++) //標示所有幀ABORTING狀態(tài)

{

spca50x->frame[n].grabstate = FRAME_ABORTING;

spca50x->curframe = -1;

}

for (n = 0; n < SPCA50X_NUMFRAMES; n++) //喚醒所有等待進程

{

if (waitqueue_active (&spca50x->frame[n].wq))

wake_up_interruptible (&spca50x->frame[n].wq);

if (waitqueue_active (&spca50x->wq))

wake_up_interruptible (&spca50x->wq);

}

spca5xx_kill_isoc(spca50x); //子函數(shù)終止URB包的傳輸

PDEBUG (3,"Disconnect Kill isoc done");

up (&spca50x->lock); //增加信號量

while(spca50x->user) /如果還有進程在使用,進程切換

schedule();

down (&spca50x->lock);

if (spca50x->vdev)

{

video_unregister_device (spca50x->vdev); //注銷video設(shè)備

usb_driver_release_interface (&spca5xx_driver,&spca50x->dev->actconfig->interface[spca50x->iface]); //端口釋放

spca50x->dev = NULL;

}

up (&spca50x->lock);

#ifdef CONFIG_PROC_FS

destroy_proc_spca50x_cam (spca50x); //注銷PROC文件

#endif /* CONFIG_PROC_FS */

if (spca50x && !spca50x->user) //釋放內(nèi)存空間

{

spca5xx_dealloc (spca50x);

kfree (spca50x);

spca50x = NULL;

}

MOD_DEC_USE_COUNT; //減少模塊記數(shù)

PDEBUG (3, "Disconnect complete");

}

二、上層軟件接口模塊:

該模塊通過file_operations數(shù)據(jù)結(jié)構(gòu),依據(jù)V4L協(xié)議規(guī)范,實現(xiàn)設(shè)備的關(guān)鍵系統(tǒng)調(diào)用,實現(xiàn)設(shè)備文件化的UNIX系統(tǒng)設(shè)計特點。作為攝相頭驅(qū)動,其功能在于數(shù)據(jù)采集,而沒有向攝相頭輸出的功能,因此在源碼中沒有實現(xiàn)write系統(tǒng)調(diào)用。

其關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)如下:

static?struct?video_device?spca50x_template?=?{

.owner?=?THIS_MODULE,

.name?=?"SPCA5XX?USB?Camera",

.type?=?VID_TYPE_CAPTURE,

.hardware?=?VID_HARDWARE_SPCA5XX,

.fops?=?&spca5xx_fops,

};

static?struct?file_operations?spca5xx_fops?=?{

.owner?=?THIS_MODULE,

.open?=?spca5xx_open,?//open功能

.release?=?spca5xx_close,//close功能

.read?=?spca5xx_read,?//read功能

.mmap?=?spca5xx_mmap,?//內(nèi)存映射功能

.ioctl?=?spca5xx_ioctl,?//文件信息獲取

.llseek?=?no_llseek,//文件定位功能未實現(xiàn)

};

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的linux usb摄像头 源码,Linux USB摄像头驱动实现源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产永久免费观看 | 日本一区二区不卡在线 | 免费人成自慰网站 | 日日精 | 色狠狠av | 久久精品三级视频 | 姐姐的朋友2在线 | 国产在线国偷精品免费看 | 免费观看全黄做爰的视频 | 中文字幕精品亚洲 | 成人看片在线观看 | 亚洲v日韩v综合v精品v | 国产乱码精品一区二区三区精东 | 在线视频资源 | www.日本在线视频 | 69视频在线| 亚洲女优在线播放 | 国产乱淫av片| 欧美成人视 | 亚洲视频在线观看网址 | 久久久久久久久久一区二区 | 91嫩草香蕉 | 日韩黄色片在线观看 | 一区二区三区四区av | 青娱乐在线播放 | 欧美黄一级 | 欧美激情一区在线 | 亚洲国产精品区 | 黄色网战大全 | 国产精品三区在线观看 | 伊人一区二区三区四区 | 久久影视一区 | 久草免费看| 中文亚洲av片不卡在线观看 | 亚洲人成电影网 | 十大污视频 | 天天天天天天天干 | 欧美精品久久久久久久 | 色播五月激情五月 | 波多野结衣视频在线观看 | 顶级毛茸茸aaahd极品 | 欧美aaaaaaaaa| 久久天堂av | 右手影院亚洲欧美 | 国产最新在线视频 | 老太婆av | 99久久精品国产毛片 | 欧美bbbbbbbbbbbb18av | 日韩专区第一页 | 亚洲欧美日韩国产一区二区三区 | 久操视频网站 | 中文字幕在线观看网 | 99色这里只有精品 | 播播激情网 | 国产毛片av | 91欧美视频 | 亚洲性自拍 | 国产午夜一区二区 | 日韩欧美中文字幕一区二区三区 | 欧美18一20男同69gay | 逼逼爱插插网站 | 19韩国主播青草vip | 国产91在线 | 亚洲 | 久久人人爽人人爽人人av | 日日干夜夜艹 | 欧美视频成人 | 韩国19主播内部福利vip | 视频一区二区三区在线观看 | 中文字幕av一区二区三区人妻少妇 | 在线99热 | 精品日韩视频 | 免费av影视| 日韩在线观看网址 | 手机免费av片 | 国产剧情av在线播放 | 少妇人妻无码专区视频 | 亚州色图欧美色图| 国产激情久久久久久熟女老人av | 艹少妇视频| 清纯粉嫩极品夜夜嗨av | 波多野结衣伦理 | 91麻豆影院 | 欧美成人午夜视频 | 黄色av免费在线播放 | 亚洲天堂视频在线 | 黄色片免费看 | 久久综合色网 | 精品91在线| 亚洲一区二区自拍偷拍 | 国产欧美综合视频 | 日韩欧美精品一区二区 | 国产系列在线 | 好色婷婷 | 欧美日韩久久精品 | 日韩在线视频在线观看 | av一级网站 | 国产成人综合一区二区三区 | 午夜一区二区三区在线观看 | 最新黄色网址在线观看 |