单片机驱动DM9000网卡芯片详细调试过程
端格式存储*/
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协议》第一卷,将会有很大帮助。希望这些
调试过程能为读者或多火烧的提供些有用的信息,也欢迎大家和我一起讨论。
单片机驱动DM9000网卡芯片调试过 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
