在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 業(yè)界動(dòng)態(tài) > [ARM筆記](méi)設(shè)備驅(qū)動(dòng)概述

            [ARM筆記](méi)設(shè)備驅(qū)動(dòng)概述

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

              2.2.3 網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)

            本文引用地址:http://www.biyoush.com/article/201611/340660.htm

              網(wǎng)絡(luò)設(shè)備和字符設(shè)備、塊設(shè)備不同,系統(tǒng)對(duì)其有專門的處理函數(shù)和機(jī)制。所有的網(wǎng)絡(luò)驅(qū)動(dòng)程序都遵循通用的接口,設(shè)計(jì)時(shí)采用的是面向?qū)ο蟮姆椒?。把所有網(wǎng)絡(luò)設(shè)備都抽象為一個(gè)接口對(duì)象。由數(shù)據(jù)結(jié)構(gòu)struct device來(lái)表示網(wǎng)絡(luò)設(shè)備在內(nèi)核中的運(yùn)行情況,即網(wǎng)絡(luò)設(shè)備接口,該結(jié)構(gòu)提供了對(duì)所有網(wǎng)絡(luò)設(shè)備的操作集合。它由以dev_base為頭指針的設(shè)備鏈表來(lái)集中管理所有網(wǎng)絡(luò)設(shè)備。該設(shè)備鏈表中的每個(gè)元素代表一個(gè)網(wǎng)絡(luò)設(shè)備接口。數(shù)據(jù)結(jié)構(gòu)device中有很多提供給系統(tǒng)訪問(wèn)和協(xié)議層調(diào)用的設(shè)備方法,包括提供給設(shè)備初始化和向系統(tǒng)注冊(cè)用的init函數(shù)、打開(kāi)和關(guān)閉網(wǎng)絡(luò)設(shè)備的open和stop函數(shù)、處理數(shù)據(jù)包發(fā)送的函數(shù)hard_start_xmit,以及中斷處理函數(shù)等。一般來(lái)講,一個(gè)網(wǎng)絡(luò)設(shè)備最基本的方法有初始化(initialize)、發(fā)送和接收。初始化,當(dāng)把驅(qū)動(dòng)程序載入系統(tǒng)的時(shí)候會(huì)調(diào)用此程序,主要完成檢測(cè)設(shè)備、配置和初始化硬件、初始化device結(jié)構(gòu)中的變量等。設(shè)備驅(qū)動(dòng)各函數(shù)是網(wǎng)絡(luò)設(shè)備接口層net_device數(shù)據(jù)結(jié)構(gòu)的具體成員,它通過(guò)hard_start_xmit()函數(shù)啟動(dòng)發(fā)送操作,并通過(guò)網(wǎng)絡(luò)設(shè)備上的中斷觸發(fā)接收操作。

              下編寫(xiě)網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)的主體工作是完成net_device結(jié)構(gòu)體的填充以及成員函數(shù)的實(shí)現(xiàn),底層最核心的工作是:發(fā)送數(shù)據(jù)包和接收數(shù)據(jù)包,接收數(shù)據(jù)包是由中斷觸發(fā)的。發(fā)送數(shù)據(jù)包函數(shù)的典型結(jié)構(gòu)如下——網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)發(fā)送數(shù)據(jù)包的典型結(jié)構(gòu)。

              int xxx_tx(struct sk_buff *skb, struct net_device *dev)

              {

              int len;

              char *data, shortpkt[ETH_ZLEN];

              /* 獲得有效數(shù)據(jù)指針和長(zhǎng)度 */

              data = skb->data;

              len = skb->len;

              if (len < ETH_ZLEN)

              {

              /* 如果幀長(zhǎng)小于以太幀最小長(zhǎng)度,補(bǔ)0 */

              memset(shortpkt, 0, ETH_ZLEN);

              memcpy(shortpkt, skb->data, skb->len);

              len = ETH_ZLEN;

              data = shortpkt;

              }

              dev->trans_start = jiffies; /* 記錄發(fā)送時(shí)間戳 */

              /* 設(shè)置硬件寄存器讓硬件把數(shù)據(jù)包發(fā)送出去 */

              xxx_hw_tx(data, len, dev);

              //...

              }

              接收數(shù)據(jù)包的典型結(jié)構(gòu)如下——網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)接受數(shù)據(jù)包的典型結(jié)構(gòu)。

              static void xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)

              {

              //...

              switch (status &ISQ_EVENT_MASK)

              {

              case ISQ_RECEIVER_EVENT:

              /* 獲取數(shù)據(jù)包 */

              xxx_rx(dev);

              break;

              /* 其他類型的中斷 */

              }

              }

              static void xxx_rx(struct xxx_device *dev)

              {

              //...

              length = get_rev_len (...);

              /* 分配新的套接字緩沖區(qū) */

              skb = dev_alloc_skb(length + 2);

              skb_reserve(skb, 2); /* 對(duì)齊 */

              skb->dev = dev;

              /* 讀取硬件上接收到的數(shù)據(jù) */

              insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1);

              if (length &1)

              skb->data[length - 1] = inw(ioaddr + RX_FRAME_PORT);

              /* 獲取上層協(xié)議類型 */

              skb->protocol = eth_type_trans(skb, dev);

              /*把數(shù)據(jù)包交給上層 */

              netif_rx(skb);

              /* 記錄接收時(shí)間戳 */

              dev->last_rx = jiffies;

              //...

              }

              2.3 Linux設(shè)備文件的創(chuàng)建

              Linux是一種類Unix系統(tǒng),Unix的一個(gè)基本特點(diǎn)是“一切皆為文件”,它抽象了設(shè)備的處理,將所有的硬件設(shè)備都像普通文件一樣看待,也就是說(shuō)硬件可以跟普通文件一樣打開(kāi)、關(guān)閉和讀寫(xiě)。系統(tǒng)中的設(shè)備都用一個(gè)特殊文件代表,叫做設(shè)備文件。在 Linux2.4以后的內(nèi)核版本中引入了設(shè)備文件系統(tǒng)(devfs),所有的設(shè)備文件作為一個(gè)可以掛裝的文件系統(tǒng),這樣就可以被文件系統(tǒng)進(jìn)行統(tǒng)一管理,從而設(shè)備文件就可以掛裝到任何需要的地方。

              在前面也講過(guò),字符設(shè)備和塊設(shè)備都可以通過(guò)文件節(jié)點(diǎn)來(lái)存取,而與字符設(shè)備和塊設(shè)備不同,網(wǎng)絡(luò)設(shè)備的訪問(wèn)是通過(guò)Socket而不是設(shè)備節(jié)點(diǎn),在系統(tǒng)里根本就不存在網(wǎng)絡(luò)設(shè)備節(jié)點(diǎn),所以在此我們僅討論塊設(shè)備和字符設(shè)備。

              那么如何在內(nèi)核中創(chuàng)建設(shè)備文件的掛載節(jié)點(diǎn)呢?簡(jiǎn)單的說(shuō),設(shè)備文件是由系統(tǒng)調(diào)用創(chuàng)建的,在命令行中,mknod命令會(huì)調(diào)用同名的程序來(lái)創(chuàng)建文件節(jié)點(diǎn)。rename和unlink系統(tǒng)調(diào)用可以用于移動(dòng)和刪除節(jié)點(diǎn),相應(yīng)的命令是mv和rm。在使用cp命令時(shí)加上-R或-a參數(shù),可以創(chuàng)建一個(gè)與原設(shè)備節(jié)點(diǎn)具有同樣屬性的節(jié)點(diǎn)。mknod命令,該命令形式如下:

              #mknod [OPTION] NAME TYPE [MAJOR MINOR]

              說(shuō)明:option選項(xiàng)設(shè)置,最常用的就是-m,基本上可以不用;name自定義設(shè)備名稱;type設(shè)備類型,有b和c還有p;MAJOR主設(shè)備號(hào);MINOR次設(shè)備號(hào)。

              mknod命令建立一個(gè)目錄項(xiàng)和一個(gè)特殊文件的對(duì)應(yīng)索引節(jié)點(diǎn)。第一個(gè)參數(shù)Name項(xiàng)是設(shè)備的名稱,選擇一個(gè)描述性的設(shè)備名稱。



            關(guān)鍵詞: ARM Linux

            評(píng)論


            相關(guān)推薦

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

            關(guān)閉