51單片機ARP協(xié)議實現(xiàn)原理
----------
|網(wǎng)卡中斷|
----------
|
V
---------- |>
|發(fā)信號量| | 收完/收溢出錯
|SemPost |---->-------------- RxSemPost
---------- |>
| | 發(fā)完/發(fā)被中斷錯
---------->-------------- TxSemPost
圖5 網(wǎng)卡中斷處理程序
進入
| ------
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ā)送流程圖
進入
| -----
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 接收流程圖
我仔細檢查了幾遍,似乎比較完備了,各種情況下均可以正常工作。在超負荷流量下,只會拋包,不會死機。當(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地址還是默認網(wǎng)關(guān)IP地址),
//這有利于減少代碼量。
//申請小號內(nèi)存
pARP=OSMemGet();
//填以太網(wǎng)幀
以太網(wǎng)協(xié)議=0x0806;//ARP協(xié)議
目的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ā)
。
。
。
參考文獻:
1?!队肨CP/IP進行網(wǎng)際互連》(第3版)第一、二、三卷 DOUGLAS E.COMER著 電子工業(yè)出版社
評論