基于USB設備的Linux網絡驅動程序開發(fā)
open回調函數(shù)的主要代碼如下:
……
usb_fill_bulk_urb(dev->rx_urb, //構造讀請求的URB
dev->udev,
usb_rcvbulkpipe(dev->udev, 6), //指定讀端點
dev->rx_skb->data,
512,
read_bulk_callback, //使用read_bulk_callback做為URB的
dev //回調函數(shù)。
);
if((result = usb_submit_urb(dev->rx_urb, GFP_KERNEL))){ //將URB發(fā)送給
…… //USB Core
}
netif_start_queue(netdev); //使能網絡傳輸隊列
……
當讀請求URB完成時,意味著主機收到了一個數(shù)據(jù)包或該URB超時,此時read_bulk_callback將會被內核調用。無論是哪種情況,為了將來可能到來的數(shù)據(jù)包能夠及時得被主機讀取,驅動程序都應該再發(fā)送一個讀請求URB給USB Core。而在主機收到數(shù)據(jù)包的情況下,read_bulk_callback函數(shù)構造一個skb_buff數(shù)據(jù)結構來描述數(shù)據(jù)包,并調用 netif_rx函數(shù),把該數(shù)據(jù)包交給上層協(xié)議,從而完成一次接受過程。
與接受過程相比,發(fā)送數(shù)據(jù)包的過程簡單了很多。當網絡子系統(tǒng)準備發(fā)送一個數(shù)據(jù)包時,上層協(xié)議將會構造一個skb_buff數(shù)據(jù)結構來描述數(shù)據(jù)包,并且調用網絡驅動程序注冊的hard_start_xmit回調函數(shù)來發(fā)送該數(shù)據(jù)包。由于該函數(shù)被調用時內核持有xmit_lock自旋鎖,因而驅動程序可以不必考慮對設備寫操作的同步問題。hard_start_xmit函數(shù)根據(jù)數(shù)據(jù)包的長度將其拆分為USB設備可以傳輸?shù)拈L度,然后構造相應的寫請求 URB,發(fā)送至USB Core即可。
hard_start_xmit回調函數(shù)的主要代碼如下:
……
usb_fill_bulk_urb(dev->tx_urb, //構造寫請求的URB
dev->udev,
usb_sndbulkpipe(dev->udev, 2), //指定寫端點
skb->data,
512,//count,
write_bulk_callback, //使用write_bulk_callback做為URB的回調函數(shù)。
dev
);
if((result = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))){ //將URB發(fā)送給
…… //USB Core
}
寫請求URB完成時,write_bulk_callback回調函數(shù)被內核調用。該函數(shù)判斷寫請求URB是否成功完成。根據(jù)URB的完成情況,驅動程序需要更新網絡接口的相應統(tǒng)計數(shù)據(jù),例如成功/失敗發(fā)送包的數(shù)目等。
5. 小結
本文從工程應用出發(fā),介紹了Linux的體系結構及其網絡子系統(tǒng),并結合USB設備在Linux下的訪問機制,研究了USB驅動程序實現(xiàn)異步通知的方法,并給出了USB網絡驅動程序的設計框架和實例。在實際測試中,本文分析的驅動程序運行穩(wěn)定,并且達到了預期的網絡傳輸速度。
參考文獻:
[1] J. Corbet, A. Rubini, and G. Kroah-Hartman. Linux Device Drivers, Third Edition. 2005, O'Reilly Media, Inc.
[2]毛德操 胡希明. Linux內核源代碼情景分析. 2001. 浙江大學出版社.
[3]Daniel P. Bovet, M. Cesati. Understanding the Linux Kernel, Second Edition. 2002, O'Reilly Media, Inc.
[4]李少甫 何小慶 江文瑞.The Development of Embedded Wireless LAN Application System Based on MontaVista Linux.微計算機信息. 2002年11期49-51
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評論