V4L接口

v4l(VideoforLinux標準)

v4l是linux中提供的一個音視頻接口規範,所有的音視頻設備的驅動編寫要用的這些接口
Video4Linux
其中用到的數據結構有:
 2 -28,I was sitting just by them.
nothing romantic.what on hell happened? 
◆ video_capability 包含攝像頭基本信息
                       設備名稱                               n a m e [ 3 2 ]   
                      最大最小分辨率信                    m a x w i d t h
                      號源信息                                channels  /type
◆ video_picture 包含設備採集圖象的各種屬性
                        brightness(亮度)、
                        hue     (色調)、
                        contrast(對比度)、
                        whiteness(色度)、
                        depth(深度)
◆ video_mmap 用於內存映射
◆ video_mbuf 利用mmap 進行映射的幀信息
 

v4l-----資料之與usb相關

Linux核心中,視頻部分的標準是VideoforLinux(簡稱V4L)
標準定義了一套接口
內核、驅動、應用程序以這個接口爲標準進行交流
USB攝像頭的驅動應當與內核提供的視頻驅動掛鉤
 
  驅動核心之間的通信過程:           聲明-----------------指定-----------------調用---------------傳遞
 
聲明video_device結構&&指定  文件操作   函數指針數組
(應用程序 發出  文件操作  的命令時)
核心  根據  指針  調用  相應函數
將該結構作爲參數傳遞給應用程序
 
擴大URB的緩衝/建立兩個URB(usb request block,簡稱urb)
                                         (usb總線就像一條高速公路,數據可以看成是系統與設備交互的貨物,而urb就可以看成是交通工具)
                                          (endpoint4種不同類型,於是能在這條高速公路上流動的數據也就有四種,但對車是沒有要求的。)
                                          (struct urb的具體內容:要運什麼,目的地是什麼)
 
{
USB的基本特性:
每一個設備(device)會有一個或者多個的邏輯連接點在裏面,每個連接點叫endpoint.每個endpoint有四種數據傳送方式:控制(Control)方式傳送;同步(isochronous)方式傳送;中斷(interrupt)方式傳送;大量(bulk)傳送.但是所有的endpoint都被用來傳送配置和控制信息。在host和endpoint設備的之間的連接叫作管道“pipe”。
}
 
 
系統中/驅動中
 核態、戶態
在需要處理大批量數據的圖像處理過程中,要用內存映射而不是拷貝的方式,實現系統調用。
 
首先使用vmalloc()申請足夠大的核態內存,將其作爲圖像數據緩衝空間,兩個URB帶回的圖像數據在這裏暫存;
然後使用remap_page_range()函數將其逐頁映射到用戶空間中。
戶態的圖像處理程序使用mmap()函數,直接讀寫核態圖像緩衝內存,大大減少額外開銷。
 

這就是linux中usb相關的那個結構體

keep away from wine.
Linux的內核是用c來編寫的。用結構化的思想分析問題。
 usb_skeleton是USB的骨架。結構體名稱是USB_SKEL.
 
struct usb_skel {
     struct usb_device *    udev;              /* the usb device for this device */
     struct usb_interface * interface;         /* the interface for this device */
     struct semaphore   limit_sem;         /* limiting the number of writes in progress */
     unsigned char *        bulk_in_buffer;        /* the buffer to receive data */
     size_t             bulk_in_size;      /* the size of the receive buffer */
     __u8          bulk_in_endpointAddr;  /* the address of the bulk in endpoint */
     __u8          bulk_out_endpointAddr; /* the address of the bulk out endpoint */
     struct kref        kref;
};
據說,USB的驅動分爲兩塊,bus驅動 和 設備驅動
設備----配置(configuration)----接口(interface)----端點(endpoint)
通過端點進行數據交換,主機與端點之間建立起單向管道交換數據。
 

對於那篇文章的筆記

Linux內核用C語言編寫,所以基本從面向對象和結構化的角度來實現。
定義的結構體 包含了驅動程序所有資源,即屬性和成員。
我們所關心的 usb驅動或者規範是linux內核中的一部分,包括兩個部分:一部分由Linux內核來實現,指的是當USB設備連接後,usb_core監測到設備的信息並確定調用什麼驅動處理該設備。另一部分由我們實現,usb設備驅動,指的是當usb_core調用到我們寫的驅動時,驅動開始工作。
這篇文章分成三個部分來敘述,1)usb的協議規範細節2)驅動框架3)源代碼分析
 
2)驅動框架:
usb的設備驅動會被編譯成模塊,需要時被掛載到內核。
一個linux模塊的例子:
#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("GPL")                                                    //向linux內核告知該模塊的版權信息
static int hello_init(void)                                        //初始化函數本身
{
printk(KERN_ALERT "hello world./n");
return 0;
static int hello_exit(void)                                        //退出函數本身
{//never feel it this way.maybe ever have,but that's long ago.
printk(KERN_ALERT "GOODBYE/n");
module_init(hello_init);                                    //向內核註冊模塊的初始化函數
module_exit(hello_exit);                                  //向內核註冊模塊的退出函數
這個簡單的例子說明了模塊的寫法。
要編譯一個模塊,需要用到內核源碼樹中的makefile
Makefile是用來進行項目配置和管理的。我們要把Linux編譯、鏈接最後生成可執行的內核映像,Makefile文件是必不可少的。
一般的內核開發者只需要知道如何使用配置系統(除非是配置系統的維護者)無須瞭解配置系統的原理,只需要知道如何編寫 Makefile 和配置文件。
 
1)USB的協議規範細節
從面向對象(OO)的角度,我們注意封裝、繼承等概念,同時要注重c語言中的結構化思想。
usb_skeleton
struct  usb_skel{
          struct  usb_device* udev;       
          struct  usb_interface* interface;
          struct semaphore limit_sem;
          unsigned char*  bulk_in_buffer;
          size_t    bulk_in_size;
          _u8      bulk_in_endpointAddr;
          _u8      bulk_out_endpointAddr;
          struct kref     kref;    
}
這個結構體描述的是該驅動所擁有的資源及狀態。
結構體udev用來描述usb設備,semaphore limit_sem用於訪問控制,kref是一個內核使用的引用計數器。
據前面所述,usb設備有若干配置(configuration),每個配置又有多個接口(interface),接口本身可以沒有端點或者有不止一個端點(endpoint)。
linux用結構體 usb_host_endpoint來描述USB端點(endpoint)
 
3)源碼分析
static int_init usb_skel_init(void)                                //初始化函數
{
   int result;
   result=usb_register(&skel_driver)
   if(result)
   err("usb_register failed.Error number %d",result);
   return result;
}
static void_exit usb_skel_exit(void)                            //退出函數
{
   usb_deregister(&skel_driver);
}
module_init(usb_skel_init);                         //模塊向內核註冊初始化函數
module_exit(usb_skel_exit);                       //模塊向內核註冊退出函數
MODULE_LICENSE("GPL");                          //版權信息
在這段程序中,有兩三處關鍵字:usb_register(struct *usb_driver),usb_deregister(struct *usb_driver),skel_driver;
其中,skel_driver是結構體usb_driver的一個實現。
前面提到的兩個函數是用來註冊和註銷驅動程序
而結構體的作用是向系統提供函數入口、驅動的名字。
這個結構體是:
static struct usb_driver skel_driver={
.name="skeleton",
.probe=skel_probe,
.disconnect=skel_disconnect,
.id_table=skel_table,
};
------id_table 用來告訴內核 該模塊支持的設備
#define USB_SKEL_VENDOR_ID oxfff0
#define USB_SKEL_PRODUCT_ID oxfff0
static struct usb_device_id skel_table[]={
{USB_DEVICE(USB_SKEL_VENDOR_ID,USB_SKEL_PRODUCT_ID)},
{}                                                                                               //設備表的最後一個元素
};
MODULE_DEVICE_TABLE{usb,skel_table};
 
其中,最後一個函數的兩個參數分別是:設備類型和設備表,而且設備表的最後一個元素是空的,用於表示結束。
------probe 是usb子系統自動調用的一個函數,當有usb設備接到硬件集線器時。
有待補充。
得到usb_device之後,
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章