6410实现网卡(DM9000A)收发功能及ARP协议实现
1. 网卡硬件结构(DM9000A)
网卡的实质就是MAC通过MII接口控制PHY的过程。
MAC主要负责数据帧的构建、数据差错检查、传送控制等。
PHY是物理接口收发器,属于物理层,当它收到MAC过来的数据时,它会去加上校验码,然后按照物理层的规则进行数据编码,再发送到传输介质上,接收过程则相反。
MII:媒体独立接口, “媒体独立”表明MAC一定情况下,任何类型的PHY设备都可以正常工作。
2. DM9000A硬件接口
由上图得到以下信息:
dm9000的片选信号CS#接到Xm0CSn1,Xm0CSn1选择的是Bank1,那么片选的起始地址为0x18000000;cmd引脚接到Xm0ADDR2,那么数据端口地址为0x18000004。
3. 软件设计
3.1 设置SROM Register
读写时序控制
3.2 设置DM9000A相关参数(初始化)
参考uboot
3.3 初步测试
测试结果与设置的一样,说明读写操作正常。
测试代码:
//各种初始化...包括串口初始化等等
//下面是读取一些芯片的出厂信息
tmp = (unsigned char)ior(0x2c);
printf("CHIP Revision:%2x\n\r", tmp);
tmp = (unsigned char)ior(0x28);
printf("Vendor ID_L:%2x \n\r", tmp);
tmp = (unsigned char)ior(0x29);
printf("Vendor ID_H:%2x \n\r", tmp);
tmp = (unsigned char)ior(0x2a);
printf("Product ID_L:%2x \n\r", tmp);
tmp = (unsigned char)ior(0x2b);
printf("Product ID_H:%2x \n\r", tmp);
4. ARP协议实现
4.1 基础知识
4.1.1 以太网的格式
目的MAC地址:接收者的物理地址;源MAC地址:发送者的物理地址;类型:标明高层的数据使用的协议类型;数据:高层的数据;CRC:校验码
4.1.2 ARP功能
在以太网络中,每台计算机的唯一身份标示是MAC地址(物理层的地址),两台计算机要进行通讯,也必须知道对方的MAC地址,但是用户通常只知道对方的IP地址,这个时候,就可以利用ARP(地址解析协议)来向局域网中的所有计算机发送ARP请求包,收到请求包且满足条件的计算机将回复ARP应答包,告知其MAC地址。所以ARP协议是一种利用IP地址或者MAC地址的协议.
4.1.3 ARP格式
ARP包分为请求包和应答包,通过OP字段来区别。
4.2 ARP收发
注意字节序!
5. 代码
#include "arp.h" #define HON(n) ((((u16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8)) /*1.发送arp请求包*/
void arp_request()
{
/*1.构成arp请求包*/
memcpy(arpbuf.ethhdr.d_mac,host_mac_addr,);
memcpy(arpbuf.ethhdr.s_mac,mac_addr,);
arpbuf.ethhdr.type = HON(0x0806); arpbuf.hwtype = HON();
arpbuf.protocol = HON(0x0800); arpbuf.hwlen = ;
arpbuf.protolen = ; arpbuf.opcode = HON(); memcpy(arpbuf.smac,mac_addr,);
memcpy(arpbuf.sipaddr,ip_addr,);
memcpy(arpbuf.dipaddr,host_ip_addr,); packet_len = +; /*2.调用dm9000发送函数,发送应答包*/
dm9000_tx(buffer,packet_len);
} /*2.解析arp应答包,提取mac*/
u8 arp_process()
{ u32 i; if (packet_len<)
return ; memcpy(host_ip_addr,arpbuf.sipaddr,);
printf("host ip is : ");
for(i=;i<;i++)
printf("%03d ",host_ip_addr[i]);
printf("\n\r"); memcpy(host_mac_addr,arpbuf.smac,);
printf("host mac is : ");
for(i=;i<;i++)
printf("%02x ",host_mac_addr[i]);
printf("\n\r"); }
arp.c
#include "dm9000.h"
#include "printf.h"
#include "arp.h" // SROM Controller
#define SROM_BW (*((volatile unsigned long*)0x70000000))
#define SROM_BC1 (*((volatile unsigned long*)0x70000008)) #define IOADDR (*((volatile unsigned short*)0x18000000))
#define IODATA (*((volatile unsigned short*)0x18000004)) u8 *buffer = &arpbuf; u8 host_mac_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
u8 mac_addr[] = {,,,,,};//随意
u8 ip_addr[] = {,,,};
u8 host_ip_addr[] = {,,,};
u16 packet_len; void delay(int n)
{
int i,j;
for(i=;i<;i++)
{
for(j=;j<n;j++)
;
}
}
void iow(u16 reg,u16 data)
{
IOADDR = reg;
IODATA = data;
} u8 ior(u16 reg)
{
IOADDR = reg;
return IODATA;
} void dm9000_reset()
{
iow(DM9000_GPCR, GPCR_GPIO0_OUT);
// power on the dm9000
iow(DM9000_GPR, );
//dm9000_reset
iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
iow(DM9000_NCR, );
delay();//second reset
iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); iow(DM9000_NCR, );
delay();
} int dm9000_probe(void)
{
u32 id_val;
id_val = ior(DM9000_VIDL);
id_val |= ior(DM9000_VIDH) << ;
id_val |= ior(DM9000_PIDL) << ;
id_val |= ior(DM9000_PIDH) << ;
if (id_val == DM9000_ID) {
printf("dm9000 is found !\n\r");
return ;
} else {
printf("dm9000 not found !\n\r");
return -;
}
} #define Tacs 2
#define Tcos 2
#define Tacc 3
#define Tcoh 2
#define Tcah 2
#define Tacp 0
int dm9000_init()
{
int i;
//设置SROM Register
SROM_BW &= (~(0xf<<));
SROM_BW |= (<<);
SROM_BC1 = (Tacs << ) | (Tcos << ) | \
(Tacc << ) | (Tcoh << ) | \
(Tcah << ) | (Tacp << ); dm9000_reset();
dm9000_probe(); //MAC初始化
/* Program operating register, only internal phy supported */
iow(DM9000_NCR, 0x0);
/* TX Polling clear */
iow(DM9000_TCR, );
/* Less 3Kb, 200us */
iow(DM9000_BPTR, BPTR_BPHW() | BPTR_JPT_600US);
/* Flow Control : High/Low Water */
iow(DM9000_FCTR, FCTR_HWOT() | FCTR_LWOT());
/* SH FIXME: This looks strange! Flow Control */
iow(DM9000_FCR, 0x0);
/* Special Mode */
iow(DM9000_SMCR, );
/* clear TX status */
iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
/* Clear interrupt status */
iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); /* fill device MAC address registers */
for (i = ;i < ; i++)
iow(DM9000_PAR+i, mac_addr[i]); /* Activate DM9000 */
/* RX enable */
iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
/* Enable TX/RX interrupt mask */
iow(DM9000_IMR, IMR_PAR);
} void dm9000_tx(u8 *data,u32 length)
{
int i;
/*禁止中断*/
iow(DM9000_IMR,0x80); /*写入发送数据的长度*/
iow(DM9000_TXPLH, (length >> ) & 0xff); //高8位
iow(DM9000_TXPLL, length & 0xff); //低8位 /*写入待发送的数据*/
IOADDR = DM9000_MWCMD; for(i=;i<length;i+=)
{
IODATA = data[i] | (data[i+]<<);
} /*启动发送*/
iow(DM9000_TCR, TCR_TXREQ); /*等待发送结束*/
while()
{
u8 status;
status = ior(DM9000_TCR);
if((status&0x01)==0x00)
break;
} /*清除发送状态*/
iow(DM9000_NSR,0x2c); /*恢复中断使能*/
iow(DM9000_IMR,0x81);
} #define PTK_MAX_LEN 1522
u32 dm9000_rx(u8 *data)
{
u8 status,len;
u16 tmp;
u32 i; /*判断是否产生中断,且清除*/
if(ior(DM9000_ISR) & 0x01)
iow(DM9000_ISR,0x01);
else
return ; /*空读*/
ior(DM9000_MRCMDX); /*读取状态*/
status = ior(DM9000_MRCMD); /*读取包长度*/
len = IODATA; /*读取包数据*/
if(len<PTK_MAX_LEN)
{
for(i=;i<len;i+=)
{
tmp = IODATA;
data[i] = tmp & 0x0ff;
data[i+] = (tmp>>)&0x0ff;
}
}
} void dm9000_arp()
{
while()
{
arp_request();
delay();
}
} //初步测试
void dm9000_test(void)
{
char buf[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
char c; printf("DM9000 test :\n\r");
printf("press q to exit\n\r"); while( )
{
scanf("%c",&c);
if (c == 'q' || c == 'Q')
{
printf("%s line %d\n\r", __FUNCTION__, __LINE__);
return ;
}
unsigned char tmp; //各种初始化...包括串口初始化等等
//下面是读取一些芯片的出厂信息
tmp = (unsigned char)ior(0x2c);
printf("CHIP Revision:%2x\n\r", tmp);
tmp = (unsigned char)ior(0x28);
printf("Vendor ID_L:%2x \n\r", tmp);
tmp = (unsigned char)ior(0x29);
printf("Vendor ID_H:%2x \n\r", tmp);
tmp = (unsigned char)ior(0x2a);
printf("Product ID_L:%2x \n\r", tmp);
tmp = (unsigned char)ior(0x2b);
printf("Product ID_H:%2x \n\r", tmp); printf("%s line %d\n\r", __FUNCTION__, __LINE__);
//dm9000_tx( buf, sizeof(buf) );
printf("%s line %d\n\r", __FUNCTION__, __LINE__);
}
}
dm9000.c
#if 0
#define EXT_INT_0_CON (volatile unsigned long*)0x7f008900
#define EXT_INT_0_MASK (volatile unsigned long*)0x7f008920
#define VIC0INTENABLE (volatile unsigned long*)0x71200010
#define EINT0_VECTADDR (volatile unsigned long*)0x71200100
#define EXT_INT_0_PEND (volatile unsigned long*)0x7f008924
#define VIC0ADDRESS (volatile unsigned long*)0x71200f00
#endif #define GPNCON (*((volatile unsigned long*)0x7F008830))
#define GPNDAT (*((volatile unsigned long*)0x7F008834)) #define EINT0CON0 (*((volatile unsigned long*)0x7F008900))
#define EINT0MASK (*((volatile unsigned long*)0x7F008920))
#define EINT0PEND (*((volatile unsigned long*)0x7F008924))
#define VIC0INTENABLE (*((volatile unsigned long*)0x71200010))
#define EINT7_VECTORADDR (*((volatile unsigned long*)0x71200104))
#define EINT0_VECTADDR (*((volatile unsigned long*)0x71200100)) #define VIC0ADDRESS (*((volatile unsigned long*)0x71200F00))
#define VIC1ADDRESS (*((volatile unsigned long*)0x71300F00)) #include "arp.h" void key1_handle()
{
__asm__( "sub lr,lr,#4\n"
"stmfd sp!,{r0-r12,lr}\n"
:
:
); led_rol(); EINT0PEND = ~0x0;
VIC0ADDRESS = ; __asm__(
"ldmfd sp!,{r0-r12,pc}^ \n"
:
:
); } void dm9000_int_issue()
{ __asm__(
"sub lr,lr,#4\n"
"stmfd sp!,{r0-r12,lr}\n"
:
:
); packet_len = dm9000_rx(buffer);
arp_process(); EINT0PEND = ~0x0;
VIC0ADDRESS = ;
//VIC1ADDRESS = 0;
__asm__(
"ldmfd sp!,{r0-r12,pc}^ \n"
:
:
);
} void init_irq()
{
EINT0CON0 |= 0B010;
EINT0MASK = ;
VIC0INTENABLE |= 0X01;
EINT0_VECTADDR = (unsigned long)key1_handle; //arp
GPNCON &= (~(0x2<<));
GPNCON |= (0x2<<);
EINT0CON0 &= (~(0x7<<));
EINT0CON0 |= (0x1<<);
EINT0MASK = ;
VIC0INTENABLE |= (<<);
EINT7_VECTORADDR = (unsigned long)dm9000_int_issue; __asm__(
"mrc p15,0,r0,c1,c0,0\n"
"orr r0,r0,#(1<<24)\n"
"mcr p15,0,r0,c1,c0,0\n" "mrs r0,cpsr\n"
"bic r0, r0, #0x80\n"
"msr cpsr_c, r0\n"
:
:
);
}
interrupt.c
6. 参考资料:
http://www.codeforge.cn/read/243433/dm9000.c__html?go_blog_box=1
http://blog.csdn.net/lzjsqn/article/details/42170375
6410实现网卡(DM9000A)收发功能及ARP协议实现的更多相关文章
- ARP协议与ARP攻击入门
一 ARP协议 ARP协议是一个年代相当"久远"的网络协议.ARP协议制定于1982年11月,英文全称:Address Resolution Protocol,即"地址解 ...
- Lvs原理及部署之ARP协议
1.什么使ARP协议 ARP协议,全称"Address Resolution Protocol" ,中文名是地址解析协议,使用ARP协议可实现通过IP地址获得对应的物理地址(MAC ...
- 关于ARP协议
什么是arp协议: arp协议是地址解析协议,英文是address resolution protocol 通过IP地址可以获得mac地址 两个主机的通信归根到底是MAC地址之间的通信 在TCP/IP ...
- 什么是ARP协议?
ARP协议,全称“Address Resolution Protocol”,中文名是地址解析协议, 使用ARP协议可实现通过IP地址获得对应主机的物理地址(MAC地址). 在TCP/IP的网络环境下, ...
- TX2平台CAN总线收发功能的测试
前言 项目实现过程中需要将获取的数据信息通过CAN总线传输到控制规划模块,本文主要介绍如何在TX2平台测试CAN总线的收发功能. TX2是英伟达旗下为嵌入式平台人工智能应用开发出的一个硬件平台,TX1 ...
- ARP协议的基础知识
关于ARP协议的基础知识 1.ARP的工作原理 本来我不想在此重复那些遍地都是的关于ARP的基本常识,但是为了保持文章的完整性以及照顾初学者,我就再啰嗦一些文字吧,资深读者可以直接跳过此节 ...
- ARP协议详解RARP
简单来说,ARP协议是IP地址转换成MAC地址的协议.链路层协议.过程如下: 1:首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系. 2:当源主机要 ...
- 从零开始学安全(四十二)●利用Wireshark分析ARP协议数据包
wireshark:是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与网卡进行数据报文交换,是目前 ...
- 图解ARP协议(三)ARP防御篇-如何揪出“内鬼”并“优雅的还手”
一.ARP防御概述 通过之前的文章,我们已经了解了ARP攻击的危害,黑客采用ARP软件进行扫描并发送欺骗应答,同处一个局域网的普通用户就可能遭受断网攻击.流量被限.账号被窃的危险.由于攻击门槛非常低, ...
随机推荐
- h5调用摄像头
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...
- Maven安装使用
环境:Ubuntu 12.04LTS,jdk1.6 1.下载maven3.05: 2.解压并获取M2/bin/mvn地址: 3.创建~/.mavenrc文件,并加入JAVA_HOME并export(需 ...
- Android NDK几点回调方式
一.NDK中获取android设备ID的方式 Java代码如下(获取设备ANDROID_ID): final String androidId = Secure.getString(context.g ...
- linux下软件安装与升级
待续 sudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade
- Beta版本测试报告
爬虫测试: 由于爬虫是整个系统的数据来源,十分的重要,但是由于引用了jar包并且运行复杂,这里主要做功能性测试,通过增加seed,运行爬虫,可以在后台控制台看到日志的不断刷新以及数据库条目的不断增加, ...
- 关于位图读取函数int Load_Bitmap_File的lseek问题。
事情是这样的,本人在编译3D游戏编程大师技巧中的程序是遇到了一个关于位图读取函数int Load_Bitmap_File的lseek问题. 我使用以下位图读取函数读取位图事报错如下: int Load ...
- 强制span不换行
对于上一篇提到的overflow的问题我好像搞懂一些了.事情大概是这个样子的:如果用了float属性,那么元素就会脱离文本的束缚,无法无天起来,这肯定是猿类无法忍受的.要想让他们乖乖就范,要么用清除浮 ...
- 跳过IE10安装VS2013
@ECHO OFF :IE10HACK REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer" /v Ver ...
- online_jf.lua --累计在线时间领取物品(积分)的lua脚本
原作者: ayase 8-27修正 修复首次使用后的红字不需要额外进数据库导入计分表,这lua全自动生成 ----------------------------------------------- ...
- (转)网上总结的 NIPS 201 参会感受
1. http://www.machinedlearnings.com/2016/12/nips-2016-reflections.html 2. http://blog.arpitmohan.com ...