• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      設(shè)計(jì)以太網(wǎng)驅(qū)動(dòng)

      2006-07-27 10:49:50潘曉嵐王?;?/span>
      關(guān)鍵詞:鍵入驅(qū)動(dòng)程序網(wǎng)卡

      潘曉嵐 楊 斌 王?;?/p>

      文章以S3C4510B的以太網(wǎng)驅(qū)動(dòng)程序?yàn)槔?,給出了驅(qū)動(dòng)程序的一般設(shè)計(jì)方法,具體描述了驅(qū)動(dòng)程序的初始化,數(shù)據(jù)接收和數(shù)據(jù)發(fā)送過程。

      本文設(shè)計(jì)了基于S3C4510B的以太網(wǎng)驅(qū)動(dòng)程序,并通過串口輸出。文章給出了對(duì)一般性網(wǎng)卡驅(qū)動(dòng)程序的編寫,但在調(diào)試中,有兩點(diǎn)需要注意:一是ARM板是處于大端方式還是小端方式;二是注意字符串的定義,如設(shè)備名等。本文適用于所有與NE2000兼容的以太網(wǎng)控制器在uclinux操作系統(tǒng)上驅(qū)動(dòng)程序的開發(fā),并可以供嵌入式系統(tǒng)中驅(qū)動(dòng)程序的開發(fā)者參考。

      S3c4510b內(nèi)嵌一個(gè)以太網(wǎng)控制器,支持媒體獨(dú)立接口(Media Independent Interface MII)和帶緩沖DMA接口(Buffer DMA Interface,BDI)。可在半雙工或全雙工模式下提供10M/100Mbps的以太網(wǎng)接入。在半雙工模式下,控制器支持CSMA/CD協(xié)議,在全雙工模式下支持IEEE802.3MAC控制層協(xié)議。

      因此,S3C4510B內(nèi)部實(shí)際上已經(jīng)包含了以太網(wǎng)MAC控制,但并未提供物理層接口,因此,需外接一片物理芯片以提供以太網(wǎng)的接入通道。在該系統(tǒng)中,使用RTL8201作為以太網(wǎng)的物理層接口。

      以太幀格式

      以太網(wǎng)采用廣播機(jī)制,所有與網(wǎng)絡(luò)連接的工作站都可以看到網(wǎng)絡(luò)上傳遞的數(shù)據(jù)。它們通過查看包含在幀中的目標(biāo)地址,確定是否進(jìn)行接受或放棄。如果確定數(shù)據(jù)是發(fā)給自己的,工作站就會(huì)接受數(shù)據(jù)并傳遞給高層協(xié)議進(jìn)行處理。

      標(biāo)準(zhǔn)IEEE802.3幀結(jié)構(gòu)由以下幾部分組成:幀頭(Preamble)、幀的起始定界標(biāo)志(SFD-Start of Frame Delimiter)、目的地址(Destination)、源地址(source)、數(shù)據(jù)長(zhǎng)度(Length)、數(shù)據(jù)(Data)和幀校驗(yàn)序列(FCS)

      在幀結(jié)構(gòu)中,除了數(shù)據(jù)域的長(zhǎng)度不固定外,其他域的長(zhǎng)度都是固定不變的。在數(shù)據(jù)發(fā)送時(shí),幀頭、幀起始定界符與校驗(yàn)和都是由NIC自動(dòng)填加的。在接收數(shù)據(jù)過程中,幀頭和幀起始定界符將由NIC跳過,即NIC一旦檢測(cè)到有效幀頭和幀起始定界符,就認(rèn)為有效數(shù)據(jù)開始,并將有效數(shù)據(jù)存入接收緩沖環(huán)。存入接收緩沖環(huán)的數(shù)據(jù)包括:目的地址、源地址、數(shù)據(jù)域長(zhǎng)度、數(shù)據(jù)域及校驗(yàn)和。

      幀頭是62位的1、0交替的位序列,即1010101010……10共62位。使用這一序列的目的是為了取得接收的串行數(shù)據(jù)的位同步信號(hào)。提取位同步信號(hào)的功能由SNI完成。

      當(dāng)發(fā)送禎時(shí),每一禎都包含了62位的幀頭,在接收禎時(shí),幀頭的62位1、0序列則跳過。即使在網(wǎng)絡(luò)數(shù)據(jù)傳輸時(shí)丟掉一些1、0序列,也不會(huì)影響有效數(shù)據(jù)的正確接收。

      禎起始定界符負(fù)責(zé)檢測(cè)有效幀的字節(jié)起始位置,由連續(xù)2位1組成。一旦NIC的定界邏輯檢測(cè)到兩個(gè)連續(xù)的1,就認(rèn)為有效幀已到,把接收到的串行數(shù)據(jù)以字節(jié)方式計(jì)數(shù),并將數(shù)據(jù)送入FIFO(First In First Out)先入先出寄存器。

      在網(wǎng)絡(luò)上傳輸數(shù)據(jù)時(shí),由于某種原因,使幀頭中的某一位由0變?yōu)?,NIC就會(huì)接收到錯(cuò)誤的幀(由CRC校驗(yàn)邏輯完成),從而拒絕接收該幀數(shù)據(jù)。

      下面定義了兩個(gè)結(jié)構(gòu)體來(lái)描述以太幀頭和以太網(wǎng)幀。

      /*以太網(wǎng)幀頭*/

      typedef struct {

      BYTE dest[MACLEN];

      BYTE srce[MACLEN];

      WORD ptype;

      }ETHERHDR;

      /*以太網(wǎng)接收幀的最大長(zhǎng)度,包括校驗(yàn)和CRC在內(nèi)*/

      #define MAXFRAMEC 1518 /*最大幀長(zhǎng)度(包括CRC)*/

      #define MINFRAMEC 64 /*最小幀長(zhǎng)度(包括CRC)*/

      /*高層驅(qū)動(dòng)采用以太網(wǎng)的幀長(zhǎng)度減去幀頭和校驗(yàn)和的長(zhǎng)度*/

      #define ETHERMTU (MAXFRAME-sizeof(ETHERHDR)) //數(shù)據(jù)長(zhǎng)度

      type struct {

      ETHERHDR h; /*幀頭*/

      BYTE data[ETHERMTU]; /*數(shù)據(jù)*/

      LWORD crc; /*CRC*/

      }ETHERFRAME;

      以太網(wǎng)卡初始化

      驅(qū)動(dòng)程序必須有一個(gè)初始化方法。在把驅(qū)動(dòng)程序載入系統(tǒng)的時(shí)候會(huì)調(diào)用這個(gè)初始化程序。它做以下幾方面的工作:檢測(cè)設(shè)備,在初始化程序里可以根據(jù)硬件的特征檢查硬件是否存在,然后決定是否啟動(dòng)這個(gè)驅(qū)動(dòng)程序。配置和初始化硬件,在初始化程序可以完成對(duì)硬件資源的配置配置或協(xié)商好硬件占用的資源以后,就可以向系統(tǒng)申請(qǐng)這些資源。有些資源是可以和別的設(shè)備共享的,如中斷。有些是不能共享的,如IO、DMA。接下來(lái)要初始化device結(jié)構(gòu)中的變量。最后,可以讓硬件正式開始工作。

      為了使網(wǎng)卡處于在線工作狀態(tài),能夠接收或發(fā)送數(shù)據(jù),首先必須對(duì)相關(guān)的寄存器進(jìn)行初始化。這些寄存器包括BDMATXCON、BDMARXCON、BDMATXPTR、BDMARXPTR、BDMARXLST、BDMASTAT、CAM、BDMATXBUF、BDMARXBUF等。

      首先對(duì)以太網(wǎng)卡的寄存器進(jìn)行初始化,并設(shè)置以太物理地址,參考程序如下:

      int s3c4510_eth_init(unsigned char *mac_addr)

      {

      int i;

      // reset BDMA and MAC

      outl(BRxRS, BDMARXCON);

      outl(BTxRS, BDMATXCON);

      outl(MaxRxFrameSize, BDMARXLSZ);

      outl(Reset, MACON);

      outl(gMACCON, MACON);

      s3c4510_eth_fd_init();

      for(i = 0; i < 4; i++)

      CAM_Reg(0) = (CAM_Reg(0) < < 8) | mac_addr[i];

      for(i = 4; i < 6; i++)

      CAM_Reg(1) = (CAM_Reg(1) < < 8) | mac_addr[i];

      CAM_Reg(1) = (CAM_Reg(1) < < 16);

      outl(0x0001, CAMEN);

      outl(gCAMCON, CAMCON);

      outl(gBDMATXCON, BDMATXCON);

      outl(gMACTXCON, MACTXCON);

      outl(gBDMARXCON, BDMARXCON);

      outl(gMACRXCON, MACRXCON);

      return 0;

      }

      數(shù)據(jù)發(fā)送

      在網(wǎng)絡(luò)中,數(shù)據(jù)傳輸?shù)倪^程是,發(fā)送方將待發(fā)送的數(shù)據(jù)按幀格式要求封裝成幀,然后通過網(wǎng)卡將幀發(fā)送到網(wǎng)絡(luò)的傳輸線上,接收方根據(jù)接收到的幀的目的地址來(lái)確定時(shí)候?qū)⒃搸峤唤o上層應(yīng)用程序。本地DMA通道使用緩沖環(huán)結(jié)構(gòu)(Buffer Ring Structure)來(lái)提供對(duì)接收的幀進(jìn)行緩存。該緩沖環(huán)由一系列固定長(zhǎng)度的緩沖區(qū)組成,每一個(gè)緩沖區(qū)的長(zhǎng)度位256字節(jié),并將它稱為一頁(yè)。因此,也可以說緩沖環(huán)是由一系列的頁(yè)組成,每頁(yè)的容量為256字節(jié)。緩沖環(huán)用來(lái)存放接收到的幀。接收緩沖環(huán)的地址可以由起始頁(yè)(PAGE STAR)和終止頁(yè)(PAGE STOP)寄存器來(lái)指定。為了將待發(fā)送的幀送入網(wǎng)卡的發(fā)送緩沖區(qū),必須使用NIC的遠(yuǎn)程DMA寫操作來(lái)完成。

      幀的發(fā)送是指將待發(fā)送的數(shù)據(jù)以幀的形式發(fā)送到網(wǎng)絡(luò)傳輸線上的過程,因此,數(shù)據(jù)的發(fā)送過程應(yīng)包括以下幾個(gè)大步驟:得到Tx幀描述符;裝入以太幀;發(fā)送以太幀;改變BDMA所有權(quán),能夠接收下一個(gè)幀。其流程如圖所示。參考程序如下:

      int s3c4510_eth_send(unsigned char *data, int len)

      {

      struct frame_desc_struct *fd_ptr;

      volatile unsigned long *fb_ptr;

      unsigned char *fb_data;

      int i;

      // 1. Get Tx frame descriptor & data pointer

      fd_ptr = (struct frame_desc_struct *)gtx_ptr;

      fb_ptr = (unsigned long *)&fd;_ptr-> frame_data_ptr;

      fb_data = (unsigned char *)fd_ptr->frame_data_ptr;

      // 2. Check BDMA ownership

      if(*fb_ptr & BDMA_owner)

      return -1;

      // 3. Prepare Tx Frame data to Frame buffer

      memcpy(fb_data, data, len);

      if (len < 60) {

      for (i = len; i < 60; i++)

      fb_data[i] = 0x00;

      len = 60;

      }

      // 4. Set Tx Frame flag & Length Field

      fd_ptr->reserved = (Padding | CRCMode | FrameDataPtrInc | LittleEndian | WA00 | MACTxIntEn);

      fd_ptr->status_and_frame_lenght = (len & 0xFFFF);

      // 5. Change ownership to BDMA

      fd_ptr->frame_data_ptr |= BDMA_owner;

      // 6. Enable MAC and BDMA Tx control register

      outl(gBDMATXCON, BDMATXCON);

      outl(gMACTXCON, MACTXCON);

      // 7. Change the Tx frame descriptor for next use

      gtx_ptr = (unsigned long)(fd_ptr-> next_frame_desc);

      return 0;

      }

      數(shù)據(jù)接收

      數(shù)據(jù)接收是指將網(wǎng)絡(luò)上的數(shù)據(jù)幀接收并緩存于網(wǎng)卡的接收緩沖環(huán)中,然后由主機(jī)程序?qū)⒕彺姝h(huán)的幀讀走并存入內(nèi)存中以備程序使用。從中可以看出,幀的接收過程分成兩步:第一步通過本地DMA將幀存入接收緩沖環(huán);第二步是通過遠(yuǎn)程DMA并在主機(jī)的配合下將接收緩沖環(huán)中的幀讀入內(nèi)存。

      一般設(shè)備收到數(shù)據(jù)后都會(huì)產(chǎn)生一個(gè)中斷,在中斷處理程序中驅(qū)動(dòng)程序申請(qǐng)一塊sk_buff(skb),從硬件讀出數(shù)據(jù)放置到申請(qǐng)好的緩沖區(qū)里。接下來(lái)填充sk_buff中的一些信息。skb->dev = dev,判斷收到幀的協(xié)議類型,填入skb->protocol(多協(xié) 議的支持)。把指針skb->mac.raw指向硬件數(shù)據(jù)然后丟棄硬件幀頭(skb_pull)。還要設(shè)置skb->pkt_type,標(biāo)明第二層(鏈路層)數(shù)據(jù)類型??梢允且韵骂愋停篜ACKET_BROADCAST,鏈路層廣播;PACKET_MULTICAST,鏈路層組播;PACKET_SELF,發(fā)給自己的幀;PACKET_OTHERHOST,發(fā)給別人的幀(監(jiān)聽模式時(shí)會(huì)有這種幀);最后調(diào)用netif_rx()把數(shù)據(jù)傳送給協(xié)議層。netif_rx()里數(shù)據(jù)放入處理隊(duì)列然后返回,真正的處理是在中斷返回以后,這樣可以減少中斷時(shí)間 (下面的參考程序只是中斷之后的部分程序)。部分參考程序如下:

      int s3c4510_eth_rcv(unsigned char *data, int *len)

      {

      struct frame_desc_struct *fd_ptr;

      unsigned long rx_status;

      unsigned long bdma_status;

      unsigned char *tmp;

      // 1. Get Rx Frame Descriptor

      fd_ptr = (struct frame_desc_struct *)grx_ptr;

      if (fd_ptr->frame_data_ptr & BDMA_owner)

      return -1;

      rx_status = (fd_ptr->status_and_frame_lenght >> 16) & 0xffff;

      // 2. Get current frame descriptor and status

      bdma_status = inl(BDMASTAT);

      // 3. Clear BDMA status register bit by write 1

      outl(bdma_status | S_BRxRDF, BDMASTAT);

      // 4. If Rx frame is good, then process received frame

      *len = 0;

      if (rx_status & Good) {

      *len = (fd_ptr->status_and_frame_lenght & 0xffff) - 4;

      tmp = (unsigned char *)fd_ptr->frame_data_ptr + 2;

      // 6. Get received frame to memory buffer

      memcpy(data, tmp, *len);

      }

      // 5. Change ownership to BDMA for next use

      fd_ptr->frame_data_ptr |= BDMA_owner;

      // Save Current Status and Frame Length field, and clear

      fd_ptr->status_and_frame_lenght = 0x0;

      // 6. Get Next Frame Descriptor pointer to process

      grx_ptr = (unsigned long)(fd_ptr->next_frame_desc);

      // 7. Check Notowner status

      if (inl(BDMASTAT) & S_BRxNO) {

      outl(S_BRxNO, BDMASTAT);

      }

      if ((inl(MACRXSTAT) & 0x400) == 0x400) {

      outl(gBDMARXCON, BDMARXCON);

      outl(gMACRXCON, MACRXCON);

      }

      return 0;

      }

      到此程序設(shè)計(jì)部分已經(jīng)基本完成。

      燒寫入內(nèi)核

      最后,我把程序燒寫入內(nèi)核來(lái)驗(yàn)證本次設(shè)計(jì)。首先將上述文件拷貝到drivers/net,然后編譯uClinux內(nèi)核: 鍵入命令:make menuconfig,內(nèi)核配置; 鍵入命令:make dep,來(lái)尋找依存關(guān)系;鍵入命令:make clean, 清除以前構(gòu)造內(nèi)核時(shí)生成的所有目標(biāo)文件,模塊文件和一些臨時(shí)文件; 鍵入命令:make lib_only,編輯庫(kù)文件;鍵入命令:make user_only,編輯用戶應(yīng)用程序;鍵入命令:make romfs,生成rom文件;鍵入命令:make image ,做到這一步的時(shí)候可能會(huì)出現(xiàn)錯(cuò)誤的信息提示,這是因?yàn)榈谝淮尉幾g時(shí)還沒有romfs.o,所以出錯(cuò),等romfs.o編譯好了以后,如果再進(jìn)行內(nèi)核的編譯,就不會(huì)出現(xiàn)這個(gè)錯(cuò)誤信息了,它完全不影響內(nèi)核的編譯,可以完全不必理會(huì)這個(gè)錯(cuò)誤信息,繼續(xù)進(jìn)行編譯工作; 鍵入命令:make,通過各個(gè)目錄的Makefile文件進(jìn)行,會(huì)在各目錄下生成一大堆目標(biāo)文件。

      上述步驟完成后,就完成了對(duì)uClinux源碼的編譯工作。

      猜你喜歡
      鍵入驅(qū)動(dòng)程序網(wǎng)卡
      在DDS 中間件上實(shí)現(xiàn)雙冗余網(wǎng)卡切換的方法
      MATLAB 在導(dǎo)數(shù)和積分中的應(yīng)用
      Server 2016網(wǎng)卡組合模式
      挑戰(zhàn)Killer網(wǎng)卡Realtek網(wǎng)游專用Dragon網(wǎng)卡
      Netstat命令使用實(shí)例解析
      河南科技(2013年6期)2013-11-07 07:45:06
      Word文檔快速簽名三法
      使Windows XP快上幾倍的三招
      驅(qū)動(dòng)程序更新與推薦
      驅(qū)動(dòng)程序更新與推薦
      驅(qū)動(dòng)程序更新與推薦
      印江| 榆中县| 甘谷县| 万荣县| 襄汾县| 信丰县| 霍邱县| 韶山市| 蓬莱市| 江永县| 洞口县| 政和县| 阜新市| 望江县| 柘荣县| 宁海县| 嘉祥县| 湖口县| 潢川县| 临沭县| 穆棱市| 阿拉善盟| 沁水县| 绿春县| 炎陵县| 夏邑县| 青海省| 扎囊县| 公主岭市| 买车| 怀化市| 兴仁县| 嵊泗县| 边坝县| 鹤壁市| 杂多县| 咸丰县| 农安县| 贵阳市| 行唐县| 陆良县|