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就可以看成是交通工具)
(endpoint有4種不同類型,於是能在這條高速公路上流動的資料也就有四種,但對車是沒有要求的。)
(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之後,