<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于USB設(shè)備的Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序開(kāi)發(fā)

          基于USB設(shè)備的Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序開(kāi)發(fā)

          作者: 時(shí)間:2012-05-21 來(lái)源:網(wǎng)絡(luò) 收藏

          圖3

          圖4

          這些資源中,端點(diǎn)對(duì)于設(shè)備有著最重要的意義,實(shí)際的數(shù)據(jù)傳輸就是通過(guò)對(duì)端點(diǎn)的讀寫(xiě)來(lái)實(shí)現(xiàn)的。驅(qū)動(dòng)程序通過(guò)描述符來(lái)獲取這些資源。在初始化時(shí),驅(qū)動(dòng)程序從設(shè)備端點(diǎn)0讀取描述符,經(jīng)過(guò)解析后保存這些資源的屬性,為傳輸數(shù)據(jù)做準(zhǔn)備。

          由于采用了抽象的硬件資源,下的設(shè)備管理也采用了與網(wǎng)絡(luò)子系統(tǒng)類似的棧結(jié)構(gòu),如圖4所示。

          USB Core對(duì)USB驅(qū)動(dòng)程序屏蔽了不同USB主機(jī)控制器之間的差異,使它們對(duì)于USB驅(qū)動(dòng)程序來(lái)說(shuō)具有統(tǒng)一的接口。USB驅(qū)動(dòng)程序通過(guò)發(fā)送URB(USB Request Block)與USB Core交換數(shù)據(jù),USB Core解釋URB,并將URB中包含的數(shù)據(jù)請(qǐng)求通過(guò)USB主機(jī)控制器發(fā)送給對(duì)應(yīng)的USB設(shè)備。另一方面,USB Core負(fù)責(zé)檢測(cè)USB設(shè)備的插入和拔出等事件,當(dāng)這些事件發(fā)生時(shí),USB Core通知內(nèi)核,使內(nèi)核能夠調(diào)用驅(qū)動(dòng)程序的相應(yīng)回調(diào)函數(shù)來(lái)通知驅(qū)動(dòng)程序?qū)@些事件做出響應(yīng)。

          4.2 USB網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

          除了必要的回調(diào)函數(shù)以外,下的每一種驅(qū)動(dòng)程序都必須有初始化函數(shù)和卸載函數(shù)。初始化函數(shù)需要根據(jù)相應(yīng)的硬件設(shè)備,向內(nèi)核注冊(cè)不同的數(shù)據(jù)結(jié)構(gòu),來(lái)聲明自己對(duì)該設(shè)備的支持。對(duì)于USB設(shè)備來(lái)說(shuō),初始化函數(shù)中需要注冊(cè)struct usb_driver,該數(shù)據(jù)結(jié)構(gòu)中的關(guān)鍵域分別為:owner,用于內(nèi)核維護(hù)模塊使用計(jì)數(shù);name,驅(qū)動(dòng)程序名稱;probe,設(shè)備初始化函數(shù)指針;disconnect,設(shè)備刪除函數(shù)指針;id_table,驅(qū)動(dòng)程序支持設(shè)備列表。設(shè)備列表指明該驅(qū)動(dòng)程序所支持的設(shè)備標(biāo)識(shí),對(duì)于USB設(shè)備來(lái)說(shuō),一般是Vendor ID和Product ID。每當(dāng)一個(gè)USB設(shè)備插入系統(tǒng),內(nèi)核將查找現(xiàn)有的所有USB設(shè)備列表,判斷應(yīng)該調(diào)用哪個(gè)驅(qū)動(dòng)程序所注冊(cè)的probe函數(shù)來(lái)完成設(shè)備初始化。當(dāng)USB設(shè)備拔出時(shí),相應(yīng)的disconnect函數(shù)也會(huì)被調(diào)用,來(lái)處理驅(qū)動(dòng)程序的卸載。因此,USB應(yīng)在probe函數(shù)中初始化設(shè)備和注冊(cè)網(wǎng)絡(luò)接口。在disconnect函數(shù)中注銷網(wǎng)絡(luò)接口。

          probe函數(shù)的主要代碼如下:

          ether_setup(netdev); //使用內(nèi)核通用的以太網(wǎng)回調(diào)函數(shù)設(shè)定hard_header等函數(shù)

          SET_MODULE_OWNER(netdev); //設(shè)定模塊擁有者,用于維護(hù)使用計(jì)數(shù)

          netdev->open = thu_plc_open; //設(shè)定open函數(shù)

          netdev->stop = thu_plc_close; //設(shè)定stop函數(shù)

          netdev->tx_timeout = thu_plc_tx_timeout; //設(shè)定超時(shí)函數(shù)

          netdev->hard_start_xmit = thu_plc_start_xmit; //設(shè)定發(fā)送函數(shù)

          netdev->get_stats = thu_plc_netdev_stats; //設(shè)定狀態(tài)統(tǒng)計(jì)函數(shù)

          netdev->watchdog_timeo = THU_PLC_TX_TIMEOUT; //設(shè)定超時(shí)值

          netdev->mtu = THU_PLC_MTU; //配置網(wǎng)絡(luò)接口的MTU

          ……

          if(!thu_plc_config_dev(dev, intf, id)) { //配置USB網(wǎng)絡(luò)設(shè)備

          printk("couldn't configure the devicen");

          break;

          }

          ……

          if(register_netdev(netdev) != 0) { //注冊(cè)ethernet接口

          printk("couldn't register the devicen");

          break;

          }

          ……

          其中thu_plc_config_dev函數(shù)用來(lái)檢測(cè)和配置USB設(shè)備。當(dāng)probe函數(shù)成功返回時(shí),驅(qū)動(dòng)程序已經(jīng)完成了USB設(shè)備的檢測(cè)和網(wǎng)絡(luò)接口的注冊(cè)。而網(wǎng)絡(luò)接口的正式啟用還需要用戶或應(yīng)用程序使能該接口。例如用戶可以使用ifconfig命令來(lái)啟用網(wǎng)絡(luò)接口。當(dāng)接口被正式啟用時(shí),驅(qū)動(dòng)程序的open回調(diào)函數(shù)被調(diào)用,由于USB設(shè)備沒(méi)有類似于硬件中斷的異步通知方式,需要主機(jī)主動(dòng)查詢是否有數(shù)據(jù)需要讀取,而網(wǎng)絡(luò)設(shè)備則需要有能力來(lái)異步通知操作系統(tǒng)數(shù)據(jù)包的到達(dá),因此,在open函數(shù)中需要向USB Core發(fā)送一個(gè)讀請(qǐng)求的URB,使得當(dāng)USB設(shè)備需要將數(shù)據(jù)包輸入主機(jī)時(shí),能夠及時(shí)響應(yīng)。

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();