日韩性视频-久久久蜜桃-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 | 国产精欧美一区二区三区白种人 | 91尤物视频在线观看 | www狠狠爱| 国产亚洲欧美一区二区三区 | 九九热在线视频观看 | 婷婷视频一区二区三区 | 日日夜夜操操 | 免费av影视 | 精品中文字幕一区二区 | 福利网址在线观看 | 婷婷综合网| 娇小的粉嫩xxx极品 国产精品人人爽人人爽 | 国产网红在线 | 91成人免费在线观看 | 中国在线观看视频高清免费 | 国内精品一区二区三区 | 日韩一区二区三区在线观看视频 | 亚洲国产成人在线观看 | 色999在线观看| 婚后打屁股高h1v1调教 | 欧洲一区二区 | 四虎影视在线播放 | 欧美激情精品久久久久久 | 国产黄色在线网站 | 午夜精品在线播放 | 人人舔人人干 | 天堂а√在线中文在线鲁大师 | 国产精品久久久久久免费免熟 | 国产精品wwww | 理论片琪琪午夜电影 | 九九99视频| 夜夜爽天天爽 | 国产成人精品久久二区二区 | wwwxxx黄色| 91成人福利在线 | 超碰98在线观看 | 国产a久久麻豆入口 | 影音先锋人妻啪啪av资源网站 | 办公室大战高跟丝袜秘书经理ol | 国产毛片儿 | 好吊妞无缓冲视频观看 | 欧美性爱视频久久 | 欧洲午夜精品 | 一级黄色大片免费看 | 丁香视频在线观看 | 日韩av在线资源 | 91久久久精品 | 和漂亮岳做爰3中文字幕 | 久久精品5 | 91一区二区三区四区 | 久久久久久激情 | 亚洲中文字幕一区 | 成人3d动漫一区二区三区91 | 疯狂揉花蒂控制高潮h | 91手机在线 | 亚洲清纯唯美 | 亚洲大色 | 黄色小视频在线观看免费 | 成人免费毛片xxx | 亚洲自拍偷拍精品 | 福利视频午夜 | 伊人影院在线视频 | 日韩激情一区二区三区 | 91麻豆精品国产91久久久久久久久 | 日日夜夜狠狠爱 | 精品探花 | 欧美三级图片 | 性色一区 | 国产一区麻豆 | 尤物精品视频 | 日韩爱爱网 | 爱情岛亚洲首页论坛小巨 | 黄色一级一片免费播放 | 无码国产69精品久久久久网站 | 美女福利视频一区 | 免费毛片大全 | 99精品一区二区 | youjizzxxxxx| 粉嫩av| 中文字幕乱码亚洲精品一区 | 色吊丝中文字幕 | 已满十八岁免费观看全集动漫 | 一起操网站 | 窝窝视频在线 | 久草成人在线视频 | 伊人啪啪 | 久久久久国色av免费观看性色 | 国产日韩在线免费观看 | 国产精品久久久久免费 | 国产二区免费 | 欧美精品免费一区二区 | 性猛交富婆╳xxx乱大交麻豆 | 丰满熟女人妻一区二区三区 |