微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机驱动DM9000网卡芯片详细调试过程

单片机驱动DM9000网卡芯片详细调试过程

时间:12-03 来源:互联网 点击:

端格式存储*/

void arp_request(void) //发送ARP请求数据包

{

//以太网首部

memcpy(ARPBUF->ethhdr.d_mac, host_mac_addr, 6);

/*字符串拷贝函数,文件要包含头文件。参数依次是,拷贝目标指针,拷贝数据源指针,拷

贝字符数*/

memcpy(ARPBUF->ethhdr.s_mac, mac_addr, 6);

ARPBUF->ethhdr.type = HON( 0x0806 );

/*小端格式的编译器,可以用HON()宏来转换成大端格式,如果你的编译器是大端格式,直接填写

0x0806即可*/

/*就是简单的按照协议格式填充,以下同*/

//ARP首部

ARPBUF->hwtype = HON( 1 );

ARPBUF->protocol = HON( 0x0800 );

ARPBUF->hwlen = 6;

ARPBUF->protolen = 4;

ARPBUF->opcode = HON( 0 );

memcpy(ARPBUF->smac, mac_addr, 6);

memcpy(ARPBUF->sipaddr, ip_addr, 4);

memcpy(ARPBUF->dipaddr, host_ip_addr, 4);

packet_len = 42;//14+28=42

sendpacket( Buffer, packet_len );

}

注释:ARPBUF的宏定义和ARP首部结构,在前面已经讲过。同时注意执行该函数时中断的处理。这里没

作处理。

看上去很easy吧,下面函数实现接收ARP请求或接收ARP应答的处理。

unsigned char arp_process(void)//ARP接收函数,成功返回1,否则返回0

{

//简单判断ARP数据包有无损坏,有损坏则丢弃,不予处理

if( packet_len < 28 )//ARP数据长度为28字节为无效数据

{

return 0;

}

switch ( HON( ARPBUF->opcode ) )

{

case 0 : //处理ARP请求

if( ARPBUF->dipaddr[0] == ip_addr[0] &&

ARPBUF->dipaddr[1] == ip_addr[1] &&

ARPBUF->dipaddr[2] == ip_addr[2] &&

ARPBUF->dipaddr[3] == ip_addr[3] )//判断是否是自己的IP,是否向自己询问MAC地址

{
ARPBUF->opcode = HON( 2 );//设置为ARP应答

memcpy(ARPBUF->dmac, ARPBUF->smac, 6);

memcpy(ARPBUF->ethhdr.d_mac, ARPBUF->smac, 6);

memcpy(ARPBUF->smac, mac_addr, 6);

memcpy(ARPBUF->ethhdr.s_mac, mac_addr, 6);

memcpy(ARPBUF->dipaddr, ARPBUF->sipaddr, 4);

memcpy(ARPBUF->sipaddr, ip_addr, 4);

ARPBUF->ethhdr.type = HON( 0x0806 );

packet_len = 42;

sendpacket( Buffer, packet_len );//发送ARP数据包

return 1;

}

else

{

return 0;

}

break;

case 1 : //处理ARP应答

if( ARPBUF->dipaddr[0] == ip_addr[0] &&

ARPBUF->dipaddr[1] == ip_addr[1] &&

ARPBUF->dipaddr[2] == ip_addr[2] &&

ARPBUF->dipaddr[3] == ip_addr[3] )//再次判断IP,是否是给自己的应答

{

memcpy(host_mac_addr, ARPBUF->smac, 6);//保存服务器MAC地址

return 1;

}

else

{

return 0;

}

break;

default ://不是ARP协议

return 0;

}

}

根据ARP协议格式看这两个函数并不困难。于是我们又得到两个函数:arp_request()和

arp_process()。

3、ARP程序调试

下面我们修改主函数和中断处理函数。

将mian()函数中的“sendpacket(60);”语句换成“arp_request();”语句。

void int_issue(void) //中断处理函数,需要根据自己的处理器进行设置

{

unsigned int i;

i = receivepacket(Buffer);//将数据读取到Buffer中。

if(i == 0)

{

return;

}

else

{

i = arp_process();

if(i == 1)//判断是否是ARP协议

print_hostmacaddr();//打印目标机的MAC地址,就是用串口打印host_mac_addr[]中的6

个字节

}

}

保存运行调试。

图7 主机MAC地址

至此,关于DM9000的调试过程就完成了。之后我还调试了UDP通讯、TCP通讯等,主要是关于协议的

处理了,这里就不介绍了。有兴趣的朋友可以参看《TCP/IP协议》第一卷,将会有很大帮助。希望这些

调试过程能为读者或多火烧的提供些有用的信息,也欢迎大家和我一起讨论。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top