新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51單片機(jī)ARP協(xié)議實現(xiàn)原理

        51單片機(jī)ARP協(xié)議實現(xiàn)原理

        作者: 時間:2012-10-12 來源:網(wǎng)絡(luò) 收藏


        ----------
        |網(wǎng)卡中斷|
        ----------
        |
        V
        ---------- |>
        |發(fā)信號量| | 收完/收溢出錯
        |SemPost |---->-------------- RxSemPost
        ---------- |>
        | | 發(fā)完/發(fā)被中斷錯
        ---------->-------------- TxSemPost
        圖5 網(wǎng)卡中斷處理程序


        進(jìn)入
        | ------
        V | | 發(fā)
        ---------- | 低優(yōu)先級
        ------> | 等待 |---
        | |TxQPend |--------------------- -----
        | ---------- | | |
        | | TxQFIFO非空 | | |
        | V | ------| |------
        | ---------- | 數(shù)據(jù)源 | | 各任務(wù)發(fā)送來的數(shù)據(jù)
        | | 發(fā)送包 | | | |
        | ---------- | -----
        | | | TxQFIFO
        | V |
        | --------------------- |
        | | 釋放內(nèi)存 | |
        | |(包已存入網(wǎng)卡RAM里)| |
        | --------------------- |
        | | ----- |
        | V | | |
        | ----------- | |
        | | 等待 |-- | (等效發(fā)送包被拋棄)
        | |TxSemPend|----------- |
        | ----------- | |
        | | 發(fā)完/超時 | |
        | V | |
        | Y ---------------- ----------- |
        ----| 發(fā)送成功嗎? | |重發(fā)第n次| |
        |(無錯且不超時)| | nN | |
        ---------------- ----------- |
        | N /^ |
        V N | |
        ------------------>------ |
        |已發(fā)了N次嗎?|---------->--------
        --------------- Y

        圖6 發(fā)送流程圖


        進(jìn)入
        | -----
        V | | 收
        ----------- | 高優(yōu)先級
        ------------------>| 等待 |--
        | --------->|RxSemPend|---------------
        | | ----------- /| /|
        | | | 收到包 或 | |
        | | V 收錯 或 | |
        | | | 超時 | |
        | | ----------- | ----------
        | | |存并清ISR| | |復(fù)位網(wǎng)卡|
        ----------- | ----------- | ----------
        |RxSemPost| | | | /^ /^
        ----------- | V | | |
        | | -------------------- | | |
        | | |超時且無新包且無錯| Y| | |
        | | | (防死鎖) |->- | |
        | | -------------------- | |
        /| |(不執(zhí)行 | N | |
        | |RxSemPost) V | |
        | | ------------ Y | |
        | | | 收溢出錯 |--->--------- |
        | | | ISR之OVW | |
        | Y | N ------------ |
        ------------------ | N |
        |網(wǎng)卡中還有包嗎?| V |
        | CURR!=BNRY+1 | ------------------------ Y |
        ------------------ |讀出包頭,查有無邏輯錯|--->-------
        | ------------------------
        /| | N
        | V
        | ------------------------
        ---------- |按包長度申請合適的大中|
        |釋放內(nèi)存| |小號內(nèi)存,并存入整個包|
        ---------- |,再調(diào)整BNRY |
        /^ /^ ------------------------
        | | |
        | | V
        | | N ----------------------------
        | ------|是否是發(fā)給自己IP地址的包?|
        | ----------------------------
        | | Y
        | V
        | ------------
        | | 包分發(fā) |
        | ------------
        | |
        | V
        | ----------------------------
        | | | | |
        | V -------------------------- IP_in過濾
        | | V V V
        | ARP ICMP(Ping) UDP TCP
        | | | | |
        | ----------------------------
        | | 串行處理
        | | (32bitMCU可設(shè)計成并發(fā)模式)
        |----------------------

        圖7 接收流程圖

        我仔細(xì)檢查了幾遍,似乎比較完備了,各種情況下均可以正常工作。在超負(fù)荷流量下,只會拋包,不會死機(jī)。當(dāng)然,由于本人接觸資料有限和個人局限性,肯定有錯誤和疏漏之處,希望大家提出意見和建議。

        偽代碼清單:
        ARP_init() //ARP緩存初始化
        {
        for(i=0;iARPTabSize;i++)
        ARPTable[i].status=0;
        }

        ARP_request(目的IP地址) //ARP請求
        {
        //判斷IP地址是否屬于同一子網(wǎng)的任務(wù)交給上層軟件處理
        //(由它決定請求網(wǎng)卡IP地址還是默認(rèn)網(wǎng)關(guān)IP地址),
        //這有利于減少代碼量。

        //申請小號內(nèi)存
        pARP=OSMemGet();

        //填以太網(wǎng)幀
        以太網(wǎng)協(xié)議=0x0806;//
        目的MAC地址=0xffff;//廣播地址
        源MAC地址=自己的MAC地址;

        //填A(yù)RP表
        硬件類型=0x0001;
        協(xié)議類型=0x0800;
        硬件地址長度=0x06;
        協(xié)議長度=0x04;
        操作=0x0001;//請求
        發(fā)送方首部=自己的MAC地址;
        發(fā)送方IP地址=源IP地址;
        目標(biāo)首部=0x0000;
        目標(biāo)IP地址=目的IP地址;

        //填充PAD
        沒有內(nèi)容處填充0;

        //發(fā)送ARP包至TxQFIFO緩存
        OSQSend(QID,*pARP);
        }

        ARP_answer(*pARP) //ARP應(yīng)答
        {
        學(xué)習(xí)/更新ARP緩存表;

        //修改收到的ARP包,形成ARP應(yīng)答
        //填以太網(wǎng)幀
        目的MAC地址=對方(網(wǎng)卡/網(wǎng)關(guān))發(fā)來的源MAC地址;
        源MAC地址=自己的MAC地址;

        //填A(yù)RP表
        目標(biāo)首部=發(fā)送方首部;發(fā)送方首部=自己的MAC地址;
        交換發(fā)送方IP地址和目標(biāo)IP地址;
        操作=0x0002;//ARP應(yīng)答

        //發(fā)送ARP包至TxQFIFO緩存
        OSQSend(QID,*pARP);
        }

        ARP_process(*pARP) //ARP應(yīng)答處理
        {
        //更新
        for(i=0;iARPTabSize;i++){
        if(ARPTab[i].status==1){
        if(ARPTab[i].IPAdr==收到的ARP應(yīng)答包源IP地址){
        ARPTab[i].ttl=最大壽命;
        ARPTab[i].IPAdr=收到的包的源IP地址;
        ARPTab[i].MACAdr=收到的包的源MAC地址;
        return;
        }
        }
        }

        //學(xué)習(xí)
        for(i=0;iARPTabSize;i++){
        if(ARPTab[i].status==0){
        ARPTab[i].status=1;
        ARPTab[i].ttl=最大壽命;
        ARPTab[i].IPAdr=收到的包的源IP地址;
        ARPTab[i].MACAdr=收到的包的源MAC地址;
        return;
        }
        }

        //表滿處理,有損性能的快速算法
        ARPTab[index].status=1; //注:index為全局變量,保存ARP緩存表項索引。每次處理加1取模。
        ARPTab[index].ttl=最大壽命;
        index++;
        if(index>=ARPTabSize) index=0;
        }

        IP_in(*pIP) //IP包過濾(ARP地址學(xué)習(xí)) 注:這里處理的是IP包,偽代碼與上面程序相似,但源代碼差別很大。
        {
        //更新
        for(i=0;iARPTabSize;i++){
        if(ARPTab[i].status==1){
        if(ARPTab[i].IPAdr==收到的IP包源IP地址){
        ARPTab[i].ttl=最大壽命;
        ARPTab[i].IPAdr=收到的包的源IP地址;
        ARPTab[i].MACAdr=收到的包的源MAC地址;
        return;
        }
        }
        }

        //學(xué)習(xí)
        for(i=0;iARPTabSize;i++){
        if(ARPTab[i].status==0){
        ARPTab[i].status=1;
        ARPTab[i].ttl=最大壽命;
        ARPTab[i].IPAdr=收到的包的源IP地址;
        ARPTab[i].MACAdr=收到的包的源MAC地址;
        return;
        }
        }

        //表滿處理,有損性能的快速算法
        ARPTab[index].status=1; //注:index為全局變量,保存ARP緩存表項索引。每次處理加1取模。
        ARPTab[index].ttl=最大壽命;
        index++;
        if(index>=ARPTabSize) index=0;
        }

        timer() //軟定時器任務(wù),用于ARP老化
        {
        for(;;){
        taskDelay(1秒);
        for(i=0;iARPTabSize;i++){
        if(ARPTab[i].status==1){
        if(ARPTab[i].ttl==0)
        ARPTab[i].status=0;
        else
        ARPTab[i].ttl--;
        }
        }
        }

        主程序框架:
        initNIC //初始化網(wǎng)卡
        //創(chuàng)建資源
        TxSem和RxSem信號量
        TxQFIFO隊列
        大中小內(nèi)存設(shè)立
        //創(chuàng)建任務(wù)

        發(fā)




        參考文獻(xiàn):
        1。《用TCP/IP進(jìn)行網(wǎng)際互連》(第3版)第一、二、三卷 DOUGLAS E.COMER著 電子工業(yè)出版社


        上一頁 1 2 下一頁

        評論


        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 罗源县| 嘉义市| 手游| 湖南省| 景宁| 宜兰县| 平乡县| 米林县| 修文县| 阳新县| 阳高县| 大英县| 正镶白旗| 丰台区| 仁寿县| 友谊县| 南丰县| 顺义区| 沭阳县| 宝鸡市| 涟水县| 炎陵县| 普兰县| 和政县| 新疆| 长治市| 鸡西市| 泰宁县| 烟台市| 鱼台县| 衡阳市| 东源县| 大方县| 张家界市| 泌阳县| 鱼台县| 文水县| 九龙城区| 慈利县| 长丰县| 裕民县|