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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

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

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

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

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

具體的模塊分析如下:

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

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

其具體實(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) //注冊(cè)USB設(shè)備驅(qū)動(dòng)

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ū)動(dòng)

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ū)動(dòng)結(jié)構(gòu),即插即用功能的實(shí)現(xiàn)

static struct usb_driver spca5xx_driver = {

"spca5xx",

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

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

{NULL,NULL}

};

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

a --?spca5xx_probe具體實(shí)現(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) //探測(cè)設(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è)備查找,匹配廠商號(hào),設(shè)備號(hào)(在子程序中)

{

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); //初始化幀等待隊(duì)列

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

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

{

spca50x->user = 0;

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

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ū)動(dòng)實(shí)現(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è)備注冊(cè)

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;?//返回?cái)?shù)劇結(jié)構(gòu)

error://錯(cuò)誤處理

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 的具體實(shí)現(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); //減少信號(hào)量

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

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

{

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

spca50x->curframe = -1;

}

for (n = 0; n < SPCA50X_NUMFRAMES; n++) //喚醒所有等待進(jì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); //增加信號(hào)量

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

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");

}

二、上層軟件接口模塊:

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

};

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

總結(jié)

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

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