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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51單片機SNMP網(wǎng)管板卡驅(qū)動程序

          51單片機SNMP網(wǎng)管板卡驅(qū)動程序

          作者: 時間:2011-09-07 來源:網(wǎng)絡(luò) 收藏

            SNMP網(wǎng)管板使用了RTL8019AS 10M ISA網(wǎng)卡芯片接入以太網(wǎng)。選它的好處是:NE2000兼容,軟件移植性好;接口簡單不用轉(zhuǎn)換芯片如PCI-ISA橋;價格便宜2.1$/片(我的購入價為22元RMB/片);帶寬充裕(針對51);較長一段時間內(nèi)不會停產(chǎn)。8019有3種配置模式:跳線方式、即插即用PP方式、串行Flash配置方式。為了節(jié)省成本,我去掉了9346而使用X5045作為閃盤存儲MAC地址和其他可配置信息。PP模式用在PC機中,這里用不上。只剩下跳線配置模式可用,它的電路設(shè)計參考REALTEK提供的DEMO板圖紙。一天時間就可以完成,相對來說硬件設(shè)計比較簡單。

            與這部分硬件相對應(yīng)的軟件是網(wǎng)卡驅(qū)動。所謂驅(qū)動程序是指一組子程序,它們屏蔽了底層硬件處理細節(jié),同時向上層軟件提供硬件無關(guān)接口。驅(qū)動程序可以寫成子程序嵌入到應(yīng)用程序里(如DOS下的I/O端口操作和ISR),也可以放在動態(tài)鏈接庫里,用到的時候再動態(tài)調(diào)入以便節(jié)省內(nèi)存。在WIN98中,為了使V86、WIN16、WIN32三種模式的應(yīng)用程序共存,提出了虛擬機的概念,在CPU的配合下,系統(tǒng)工作在保護模式,OS接管了I/O、中斷、內(nèi)存訪問,應(yīng)用程序不能直接訪問硬件。這樣提高了系統(tǒng)可靠性和兼容性,也帶來了軟件編程復(fù)雜的問題。任何網(wǎng)卡驅(qū)動都要按VXD或WDM模式編寫,對于硬件一側(cè)要處理虛擬機操作、總線協(xié)議(如ISA、PCI)、即插即用、電源管理;上層軟件一側(cè)要實現(xiàn)NDIS規(guī)范。因此在WIN98下實現(xiàn)網(wǎng)卡驅(qū)動是一件相當(dāng)復(fù)雜的事情。

            我這里說的驅(qū)動程序特指實模式下的一組硬件芯片驅(qū)動子程序。從程序員的角度看,8019工作流程非常簡單,驅(qū)動程序?qū)⒁l(fā)送的數(shù)據(jù)包按指定格式寫入芯片并啟動發(fā)送命令,8019會自動把數(shù)據(jù)包轉(zhuǎn)換成物理幀格式在物理信道上傳輸。反之,8019收到物理信號后將其還原成數(shù)據(jù),按指定格式存放在芯片RAM中以便主機程序取用。簡言之就是8019完成數(shù)據(jù)包和電信號之間的相互轉(zhuǎn)換:數(shù)據(jù)包===>電信號。以太網(wǎng)協(xié)議由芯片硬件自動完成,對程序員透明。驅(qū)動程序有3種功能:芯片初始化、收包、發(fā)包。

            以太網(wǎng)協(xié)議不止一種,我用的是802.3。它的幀結(jié)構(gòu)如圖1所示。物理信道上的收發(fā)操作均使用這個幀格式。其中,前導(dǎo)序列、幀起始位、CRC校驗由硬件自動添加/刪除,與上層軟件無關(guān)。值得注意的是,收到的數(shù)據(jù)包格式并不是802.3幀的真子集,而是如圖2所示。明顯地,8019自動添加了“接收狀態(tài)、下一頁指針、以太網(wǎng)幀長度(以字節(jié)為單位)”三個數(shù)據(jù)成員(共4字節(jié))。這些數(shù)據(jù)成員的引入方便了驅(qū)動程序的設(shè)計,體現(xiàn)了軟硬件互相配合協(xié)同工作的設(shè)計思路。當(dāng)然,發(fā)送數(shù)據(jù)包的格式是802.3幀的真子集,如圖3所示。

            


            有了收發(fā)包的格式,如何發(fā)送和接收數(shù)據(jù)包呢?如圖4所示,先將待發(fā)送的數(shù)據(jù)包存入芯片RAM,給出發(fā)送緩沖區(qū)首地址和數(shù)據(jù)包長度(寫入TPSR、TBCR0,1),啟動發(fā)送命令(CR=0x3E)即可實現(xiàn)8019發(fā)送功能。8019會自動按以太網(wǎng)協(xié)議完成發(fā)送并將結(jié)果寫入狀態(tài)寄存器。如圖5所示,接收緩沖區(qū)構(gòu)成一個循環(huán)FIFO隊列,PSTART、PSTOP兩個寄存器限定了循環(huán)隊列的開始和結(jié)束頁,CURR為寫入指針,受芯片控制,BNRY為讀出指針,由主機程序控制。根據(jù)CURR==BNRY+1?可以判斷是否收到新的數(shù)據(jù)包,新收到的數(shù)據(jù)包按圖2格式存于以CURR指出的地址為首址的RAM中。當(dāng)CURR==BNRY時芯片停止接收數(shù)據(jù)包。如果做過FPGA設(shè)計,用過VHDL,可以想象到硬件芯片的工作原理。此處,設(shè)計2個8bit寄存器和一個2輸入比較器,當(dāng)收到數(shù)據(jù)包時,接收狀態(tài)機根據(jù)當(dāng)前狀態(tài)和比較器結(jié)果決定下一個狀態(tài),如果CURR=BNRY,進入停收狀態(tài);反之,CURR按模增1。8019數(shù)據(jù)手冊沒有給出硬件狀態(tài)機實現(xiàn)方法,說明也很簡略,往往要通過作實驗的方法推理出工作過程。比如,ISR寄存器不只和中斷有關(guān),當(dāng)接收緩沖溢出時,如果不清ISR(寫入FFH),芯片將一直停止接收。在流量較大時溢出經(jīng)常發(fā)生,此時不清ISR,就會導(dǎo)致網(wǎng)卡芯片死機。

            

            明白了發(fā)送和接收數(shù)據(jù)包的原理,那么數(shù)據(jù)包又是怎樣被主機寫入芯片RAM和從芯片RAM讀出的呢?如圖6所示,主機設(shè)置好遠端DMA開始地址(RSAR0,1)和遠端DMA數(shù)據(jù)字節(jié)數(shù)(RBCR0,1),并在CR中設(shè)置讀/寫,就可以從遠端DMA口寄存器里讀出芯片RAM里的數(shù)據(jù)/把數(shù)據(jù)寫入芯片RAM。

            何謂本地/遠端DMA呢?如圖7所示,“遠端”指CPU接口側(cè);“本地”指8019的硬件收發(fā)電路側(cè)。沒有更深的意思,與遠近無關(guān),僅僅為了區(qū)分主機和芯片硬件兩個接口端。這里的DMA與平時所說的DMA有點不同。RTL8019AS的local DMA操作是由控制器本身完成的,而其remote DMA并不是在無主處理器的參與下,數(shù)據(jù)能自動移到主處理器的內(nèi)存中。remote DMA指主機CPU給出起址和長度就可以讀寫芯片RAM,每操作一次RAM地址自動加1。而普通RAM操作每次要先發(fā)地址再處理數(shù)據(jù),速度較慢。

            在一些高檔通信控制器上自帶有MAC控制器,工作原理與8019的差不多,比如:Motorola 68360/MPC860T內(nèi)部的CPM帶有以太網(wǎng)處理器,通過設(shè)置BD表,使軟件和硬件協(xié)同工作,它的緩沖區(qū)更大且可靈活配置。這些通信控制器的設(shè)計,體現(xiàn)了軟硬件互相融合協(xié)同工作的趨勢:軟件硬化(VHDL),硬件軟化(DSP),希望大家關(guān)注!

            

            如圖7所示,8019以太網(wǎng)控制器以存儲器(16K雙口RAM)為核心,本地和遠端控制器并發(fā)操作。這種體系結(jié)構(gòu)滿足了數(shù)據(jù)帶寬的需要。8019擁有控制、狀態(tài)、數(shù)據(jù)寄存器,通過它們,可以與8019通信。由于51資源緊張,在實現(xiàn)TCPIP協(xié)議棧時不要進行內(nèi)存塊拷貝,建議(1)使用全局結(jié)構(gòu)體變量,在內(nèi)存中只保存一個數(shù)據(jù)包拷貝,其他沒有來得及處理的包保存在8019的16K RAM里;(2)使用查詢方式而不用中斷;(3)客戶服務(wù)器模型中服務(wù)器工作于串行方式,并發(fā)模式不適合

            芯片內(nèi)部地址空間的分配如圖8所示,其中0x00-0x0B(工作于8位DMA模式)用于存放本節(jié)點MAC地址,奇偶地址內(nèi)容是重復(fù)放置的。如:MAC地址0000 1234 5678存放在0x00-0x0B中為000000001212343456567878,單地址和雙地址的內(nèi)容是重復(fù)的.一般使用偶數(shù)地址的內(nèi)容,這主要是為了同時適應(yīng)8位和16位的dma。Prom內(nèi)容是網(wǎng)卡在上電復(fù)位的時候從93C46里讀出來的。如果你沒有使用93C46,就不要使用Prom,那么使用了93C46后如何獲得網(wǎng)卡的地址呢?有兩種方法,一是直接讀93C46,二是讀Prom。網(wǎng)卡MAC地址既不由93C46也不由Prom決定,而是由PAR0-PAR5寄存器決定。Prom只保存上電時從9346中讀出的MAC地址(如果有93C46的話),僅此而矣。

            

          51單片機SNMP網(wǎng)管板卡驅(qū)動程序

            

          51單片機SNMP網(wǎng)管板卡驅(qū)動程序

            網(wǎng)卡MAC地址不是隨便定義的,它的組成結(jié)構(gòu)如圖9所示。以太網(wǎng)的地址為48位,由ieee統(tǒng)一分配給網(wǎng)卡制造商,每個網(wǎng)卡的地址都必須是全球唯一的。共6個字節(jié)的長度。FF:FF:FF:FF:FF:FF為廣播地址,只能用在目的地址段,不能作為源地址段。目的地址為廣播地址的數(shù)據(jù)包,可以被一個局域網(wǎng)內(nèi)的所有網(wǎng)卡接收到。合法的以太網(wǎng)地址第32位組播標(biāo)志必須為0。例如:

            X0:XX:XX:XX:XX:XX

            X2:XX:XX:XX:XX:XX

            X4:XX:XX:XX:XX:XX

            X6:XX:XX:XX:XX:XX

            X8:XX:XX:XX:XX:XX

            XA:XX:XX:XX:XX:XX

            XC:XX:XX:XX:XX:XX

            XE:XX:XX:XX:XX:XX

            為合法以太網(wǎng)地址。上面的X代表0-F中的任一個。

            地址

            X1:XX:XX:XX:XX:XX

            X3:XX:XX:XX:XX:XX

            X5:XX:XX:XX:XX:XX

            X7:XX:XX:XX:XX:XX

            X9:XX:XX:XX:XX:XX

            XB:XX:XX:XX:XX:XX

            XD:XX:XX:XX:XX:XX

            XF:XX:XX:XX:XX:XX

            為組播地址,只能作為目的地址,不能作為源地址。組播地址可以被支持該組播地址的一組網(wǎng)卡接收到。組播地址主要用在視頻廣播,遠程喚醒(通過發(fā)一個特殊的數(shù)據(jù)包使網(wǎng)卡產(chǎn)生一個中斷信號,啟動電腦),游戲(多個人在局域網(wǎng)里聯(lián)機打游戲)里等。

            以下是一些具體的組播地址:

            地址范圍

            01:00:5E:00:00:00---01:00:5E:7F:FF:FF 用于ip地址的組播,其他組播地址跟tcp/ip無關(guān),不做介紹。

            網(wǎng)卡可以接收以下3種地址的數(shù)據(jù)包:

            第一種 目的地址跟自己的網(wǎng)卡地址是一樣的數(shù)據(jù)包;

            第二種 目的地址為FF:FF:FF:FF:FF:FF廣播地址的數(shù)據(jù)包;

            第三種 目的地址為跟自己的組播地址范圍相同的數(shù)據(jù)包。

            在以太網(wǎng)的應(yīng)用當(dāng)中,如果你希望你的數(shù)據(jù)包只發(fā)給一個網(wǎng)卡,目的地址用對方的網(wǎng)卡地址;

            如果你想把數(shù)據(jù)包發(fā)給所有的網(wǎng)卡,目的地址用廣播地址;

            如果你想把數(shù)據(jù)包發(fā)給一組網(wǎng)卡,目的地址用組播地址。

            其他用到的寄存器:

            CR---命令寄存器 TSR---發(fā)送狀態(tài)寄存器 ISR---中斷狀態(tài)寄存器

            RSR---接收狀態(tài)寄存器 RCR---接收配置寄存器 TCR---發(fā)送配置寄存器

            DCR---數(shù)據(jù)配置寄存器 IMR---中斷屏蔽寄存器 NCR---包發(fā)送期間碰撞次數(shù)

            FIFO---環(huán)回檢測后,查看FIFO內(nèi)容

            CNTR0---幀同步錯總計數(shù)器

            CNTR1---CRC錯總計數(shù)器

            CNTR2---丟包總計數(shù)器

            PAR0-5---本節(jié)點MAC地址

            MAR0-7---多播地址匹配

            建議:將圖形中寄存器名稱標(biāo)注上頁號和地址偏移(如:BNRY 0頁0x03),打印出此圖,看圖編程,直觀且不容易出錯。

            備注:收緩沖區(qū)、發(fā)緩沖區(qū)、數(shù)據(jù)存儲區(qū)在16K雙口RAM里的安排由用戶自行決定,只要不引起沖突即可,以下源程序代碼實現(xiàn)的只是其中的一種分配方案。

            部分源程序清單:

            struct ethernet{

            unsigned char status; //接收狀態(tài)

            unsigned char nextpage; //下一個頁

            unsigned int length; //以太網(wǎng)長度,以字節(jié)為單位

            unsigned int destnodeid[3]; //目的網(wǎng)卡地址

            unsigned int sourcenodeid[3]; //源網(wǎng)卡地址

            unsigned int protocal; //下一層協(xié)議

            unsigned char packet[1500]; //包的內(nèi)容

            };

            void ne2000init()//ne2000網(wǎng)卡初始化

            {

            rtl8019as_rst();

            reg00=0x21; //選擇頁0的寄存器,網(wǎng)卡停止運行,因為還沒有初始化。

            delay_ms(10); //延時10毫秒,確保芯片進入停止模式

            //使芯片處于mon和loopback模式,跟外部網(wǎng)絡(luò)斷開

            page(0);

            reg0a=0x00;

            reg0b=0x00;

            reg0c=0xE0; //monitor mode (no packet receive)

            reg0d=0xE2; //loop back mode

            //使用0x40-0x4B為網(wǎng)卡的發(fā)送緩沖區(qū),共12頁,剛好可以存儲2個最大的以太網(wǎng)包。

            //使用0x4c-0x7f為網(wǎng)卡的接收緩沖區(qū),共52頁。

            reg01=0x4C; //Pstart 接收緩沖區(qū)范圍

            reg02=0x80; //Pstop

            reg03=0x4C; //BNRY

            reg04=0x40; //TPSR 發(fā)送緩沖區(qū)范圍

            reg07=0xFF;/*清除所有中斷標(biāo)志位*/

            reg0f=0x00;//IMR disable all interrupt

            reg0e=0xC8; //DCR byte dma 8位dma方式

            page(1); //選擇頁1的寄存器

            reg07=0x4D; //CURR

            reg08=0x00; //MAR0

            reg09=0x41; //MAR1

            reg0a=0x00; //MAR2

            reg0b=0x80; //MAR3

            reg0c=0x00; //MAR4

            reg0d=0x00; //MAR5

            reg0e=0x00; //MAR6

            reg0f=0x00; //MAR7

            initNIC(); //初始化MAC地址和網(wǎng)絡(luò)相關(guān)參數(shù)

            //將網(wǎng)卡設(shè)置成正常的模式,跟外部網(wǎng)絡(luò)連接

            page(0);

            reg0c=0xCC; //RCR

            reg0d=0xE0; //TCR

            reg00=0x22; //這時讓芯片開始工作?

            reg07=0xFF; //清除所有中斷標(biāo)志位

            }

            void send_packet(union netcard *txdnet,unsigned int length)//ne2000發(fā)包子程序

            {//發(fā)送一個數(shù)據(jù)包的命令,長度最小為60字節(jié),最大1514字節(jié)需要發(fā)送的數(shù)據(jù)包要先存放在txdnet緩沖區(qū)

            unsigned char i;

            unsigned int ii;

            page(0);

            if(length60) length=60;

            for(i=0;i3;i++)

            txdnet->etherframe.sourcenodeid[i]=my_ethernet_address.words[i];

            txd_buffer_select=!txd_buffer_select;

            if(txd_buffer_select)

            reg09=0x40 ; //txdwrite highaddress

            else

            reg09=0x46 ; //txdwrite highaddress

            reg08=0x00; //read page address low

            reg0b=length>>8; //read count high

            reg0a=length0xFF; //read count low;

            reg00=0x12; //write dma, page0

            for(ii=4;ii reg10=txdnet->bytes.bytebuf[ii];

            for(i=0;i6;i++){ //最多重發(fā)6次

            for(ii=0;ii1000;ii++) //檢查txp為是否為低

            if((reg000x04)==0) break;

            if((reg040x01)!=0) break; //表示發(fā)送成功

            reg00=0x3E;

            }

            if(txd_buffer_select) reg04=0x40; //txd packet start;

            else reg04=0x46; //txd packet start;

            reg06=length>>8; //high byte counter

            reg05=length0xFF; //low byte counter

            reg00=0x3E; //to sendpacket;

            }

            bit recv_packet(union netcard *rxdnet)//ne2000收包子程序

            {

            unsigned char i;

            unsigned int ii;

            unsigned char bnry,curr;

            page(0);

            reg07=0xFF;

            bnry=reg03; //bnry page have read 讀頁指針

            page(1);

            curr=reg07; //curr writepoint 8019寫頁指針

            page(0);

            if(curr==0)

            return 0; //讀的過程出錯

            bnry=bnry++;

            if(bnry>0x7F) bnry=0x4C;

            if(bnry!=curr){ //此時表示有新的數(shù)據(jù)包在緩沖區(qū)里

            //讀取一包的前18個字節(jié):4字節(jié)的8019頭部,6字節(jié)目的地址,6字節(jié)原地址,2字節(jié)協(xié)議

            //在任何操作都最好返回page0

            page(0);

            reg09=bnry; //read page address high

            reg08=0x00; //read page address low

            reg0b=0x00; //read count high

            reg0a=18; //read count low;

            reg00=0x0A; //read dma

            for(i=0;i18;i++)

            rxdnet->bytes.bytebuf[i]=reg10;

            i=rxdnet->bytes.bytebuf[3]; //將長度字段的高低字節(jié)掉轉(zhuǎn)

            rxdnet->bytes.bytebuf[3]=rxdnet->bytes.bytebuf[2];

            rxdnet->bytes.bytebuf[2]=i;

            rxdnet->etherframe.length=rxdnet->etherframe.length-4; //去掉4個字節(jié)的CRC

            //表示讀入的數(shù)據(jù)包有效

            if(((rxdnet->bytes.bytebuf[0]0x01)==0)||(rxdnet->bytes.bytebuf[1]>0x7F)||(rxdnet->bytes.bytebuf[1]0x4C)||(rxdnet->bytes.bytebuf[2]>0x06)){

            //接收狀態(tài)錯誤,或者next_page_start錯誤或者長度錯誤,將丟棄所有數(shù)據(jù)包

            page(1);

            curr=reg07; //page1

            page(0); //切換回page0

            bnry=curr-1;

            if(bnry0x4C) bnry=0x7F;

            reg03=bnry; //write to bnry

            return 0;

            }

            else{//表示數(shù)據(jù)包是完好的.讀取剩下的數(shù)據(jù)

            if((rxdnet->etherframe.protocal==0x0800)||(rxdnet->etherframe.protocal==0x0806)){

            //協(xié)議為IP或ARP才接收

            reg09=bnry; //read page address high

            reg08=4; //read page address low

            reg0b=rxdnet->etherframe.length>>8; //read count high

            reg0a=rxdnet->etherframe.length0xFF; //read count low;

            reg00=0x0A; //read dma

            for(ii=4;iietherframe.length+4;ii++)

            rxdnet->bytes.bytebuf[ii]=reg10;

            }

            bnry=rxdnet->bytes.bytebuf[1]-1;//next page start-1

            if(bnry0x4C) bnry=0x7F;

            reg03=bnry; //write to bnry

            return 1; //have new packet

            }

            }

            return 0;

            }



          關(guān)鍵詞: 51單片機 RTL8019AS網(wǎ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); })();