首页 > 代码库 > 一步步玩pcDuino3--uboot下的ping,添加命令可以接受来自host的ping

一步步玩pcDuino3--uboot下的ping,添加命令可以接受来自host的ping

        uboot是一个非常优秀的开源项目。不仅仅可以学习bootloader,嵌入式,各种总线协议。还可以了解网络协议栈。在嵌入式开发中,经常使用uboot的tftp和nfs来加快开发的效率。那么在tftp可以使用之前,我们要保证host和pcDuino3可以ping通。在uboot下可以ping通host,但是host不能ping通uboot,这是因为uboot不是操作系统,我们需要做了个命令来循环等待来自host的ping命令。

        在为uboot添加命令接受来自host的ping之前,我们先了解一下ping的过程:

硬件环境:host主机的ip是192.168.1.11,mac地址是5c:26:0a:5c:91:50.

pcDuino3的ip是192.168.1.188,mac地址是12:34:56:78:11:22.

        我们从uboot往host发送ping 192.168.1.188时,这个过程可以用wireshark抓下来:

        

        首先是广播发送一个ARP请求,然后host会回复该请求,这样uboot端就得到了host的mac地址;

        接下来就是发送ICMP协议的Echo request,收到Echo reply,就表示ping通了。

        其实从host往pcDuino3发送ping过程也是一样的,我们仅仅需要添加几行简单的代码就可以了,

        为uboot添加一条recvping命令:

static int recv_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	printf("recv ping command excute \n");	
	if (NetLoop(RECVPING) < 0) {
		printf("ping failed; ");
		return 1;
	}

	printf("host  is alive\n");

	return 0;
	
}

U_BOOT_CMD(
	recvping,	2,	1,	recv_ping,
	"recv ICMP ECHO_REQUEST from network host",
	"wait the ping from other host"
);

       接着在NetLoop中添加处理RECVPING的处理分支:

		case RECVPING:
			
			recvping_start();
			break;

其中recvping_start函数如下:

void recvping_start(void)
{
	
	printf("Using %s device\n", eth_get_name());
	NetSetTimeout(100000UL, ping_timeout);
	
}

这样,我们再次从主机ping,使用wireshark抓包:


        因为host会发送四次ICMP包,所以就有多次Echo request。

        这么一看,网络协议栈也蛮简单清晰的,透过这个过程,仅仅为了对网络协议栈的理解,而不仅仅是会UNIX网络编程中的socket,listen,bind等。