** 「本文寫的是usb攝像機linux驅動層簡單介紹,linux的usb驅動非常複雜,坑很大,搞懂全部的七八成就是大神級別的人物了。我剛開始上手uvc驅動非常暈,超多結構體,還是指標形式,封裝層數龐大,各種bind,以前linux驅動基本沒碰過,只看過開發板手冊裡的led驅動,現在直接做usb驅動,只能一步步來,不心急。」**
我們現在要做的是驅動乙個usb介面攝像機,所以寫的是usb裝置的**,而不是usb主機host。
這個驅動名稱可以稱作linux usb gadget類軟體。
linux usb gadget軟體分為三層。這三層其中兩層是與硬體無關的,分別是gadget功能驅動層、usb裝置層。udc層與硬體有關。
**很複雜,我們簡化一下,三個層主要用到的結構體如下,各項引數設定都與他們有關係
gadget功能驅動層:usb_composite_driver
usb裝置層: usb_composite_dev與usb_gadget_driver
udc層: usb_gadget
linux驅動程式框架
==這是給新手看的,高手略過
module_init(webcam_init);//初始化
module_exit(webcam_cleanup);//解除安裝
webcam_cleanup(void)
裡面呼叫的是usb_gadget_unregister_driver方法,這是linux usb gadget系統的方法,我們完全不用看,了解他的作用就行。
接下來看
webcam_init(void)
static struct usb_composite_driver webcam_driver = ;
在usb_composite_probe裡面填充composite_driver結構體。composite_driver是usb_gadget_driver結構體,所以開始連線usb裝置層,之後執行此函式
usb_gadget_probe_driver(&composite_driver, composite_bind);
這裡面定義了usb_gadget結構體,出現了最底層的udc層。之後把它傳到。
composite_bind(struct usb_gadget *gadget)
這裡面定義了乙個usb_composite_dev結構體cdev,這是usb裝置層的,所以關係挺複雜的,我們暫時不去理解。
之後填充cdev結構體,毫無疑問,它儲存了上層的很多資訊。
這個函式有點複雜,主要用到了這幾個介面
composite_gadget_bind(cdev);//這個函式裡面內容有點多,之後我會再發一篇文作基礎介紹
override_id(cdev, &cdev->desc.imanufacturer);
device_create_file(&gadget->dev, &dev_attr_suspended);
composite_bind結束之後回到了usb_gadget_probe_driver,然後執行
usb_gadget_start(udc->gadget, driver, bind);
1.結構体作形參
fun(*struct x)
2.指標函式
int foo(int x,int y);
int fun(char a,int (*pfun)(int x,inty))
呼叫:fun('c',foo);
ubuntu下使用UVC攝像頭
導師讓學習opencv程式設計,想用qt但是發現windows上qt使用directshow非常麻煩,就想到linux上程式設計,於是買一普通攝像頭,回來一看,插在ubuntu電腦上沒有反應,知道視驅動的問題,開始探尋如何在ubuntu上使用。具體操作如下 首先使用lsusb命令 bus 005 d...
ubuntu下使用UVC攝像頭
導師讓學習opencv程式設計,想用qt但是發現windows上qt使用directshow非常麻煩,就想到linux上程式設計,於是買一普通攝像頭,回來一看,插在ubuntu電腦上沒有反應,知道視驅動的問題,開始探尋如何在ubuntu上使用。具體操作如下 首先使用lsusb命令 bus 005 d...
OpenWRT下使用UVC攝像頭
準備在openwrt系統使用uvc免驅攝像頭採集影象,編譯的系統使用預設的配置。使用程式對攝像頭進行資料採集的時候發現程式只能進行支援的格式讀取,不能進行格式設定 緩衝區分配和影象採集,一開始懷疑是攝像頭不支援linux系統,後來使用orangepi進行測試的時候發現orangepi是可以正常讀取影...