512|0

504

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

【得捷电子Follow me第4期】基础任务一-以太网ip设置ping与抓包 [复制链接]

 

 

 

4.1 准备

参考

链接已隐藏,如需查看请登录或者注册

 

下载代码

git clone --recurse-submodules

链接已隐藏,如需查看请登录或者注册

 

Pico-Vscode打开文件夹

D:\BOARD\followme4\RP2040-HAT-C

会自动clone和应用patch,构建

 

 

修改RP2040-HAT-C/CMakeLists.txt里

# Set ethernet chip

set(WIZNET_CHIP W5100S)

# Set ethernet chip

set(WIZNET_CHIP W5500)

 

从以下地址下载picotool.exe、pioasm.exe、elf2uf2.exe放到

SDK安装路径我这里是D:\Program Files\Raspberry Pi\Pico SDK v1.5.1\picotool。

https://sourceforge.net/projects/rpi-pico-utils/files/v1.3.0/

 

修改D:\BOARD\followme4\RP2040-HAT-C\CMakeLists.txt

在pico_sdk_init()前添加

# Avoid building 'pioasm'

add_executable(Pioasm IMPORTED)

set_property(TARGET Pioasm PROPERTY IMPORTED_LOCATION

"pioasm.exe")

set(Pioasm_FOUND 1)

 

# Avoid building 'elf2uf2'

 

add_executable(ELF2UF2 IMPORTED)

set_property(TARGET ELF2UF2 PROPERTY IMPORTED_LOCATION

"elf2uf2.exe")

set(ELF2UF2_FOUND 1)

 

添加系统环境变量path

D:\Program Files\Raspberry Pi\Pico SDK v1.5.1\pico-sdk-tools

 

编译

点击build,弹出选择工具链,选择arm-none-eabi-gcc

 

编译后程序位于D:\BOARD\followme4\RP2040-HAT-C\build\examples

下载运行\RP2040-HAT-C\build\examples\loopback\w5x00_loopback.uf2

 

4.2 W5500初始化(静态IP配置)

修改g_net_info

配置和局域网同一网段

static wiz_NetInfo g_net_info =

    {

        .mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56}, // MAC address

        .ip = {192, 168, 31, 111},                    // IP address

        .sn = {255, 255, 255, 0},                    // Subnet Mask

        .gw = {192, 168, 31, 1},                     // Gateway

        .dns = {8, 8, 8, 8},                         // DNS server

        .dhcp = NETINFO_STATIC                       // DHCP enable/disable

};

 

接上网口,可以看到打印IP地址等信息

 

4.3 电脑ping开发板与抓包

 

Wireshark抓包如下

 

 

 

网络调试助手tcp连接开发板IP端口5000,开发板收到数据原样返回

 

 

4.4 开发板ping外网

参考https://docs.wiznet.io/img/products/w5500/w5500_ap_ipraw_v110e.pdf

https://docs.wiznet.io/img/products/w5500/w5500_apc_ipraw_v110.zip

 

 

ping.c

#include <stdio.h>
#include <stdint.h>
#include "socket.h"
#include "wizchip_conf.h"
#include "ping.h"
#include "port_common.h"

#include "wizchip_conf.h"
#include "socket.h"
#include "w5x00_spi.h"
#include "time.h"
#include "pico/stdlib.h"

PINGMSGR PingRequest;	 // Variable for Ping Request
PINGMSGR PingReply;	     // Variable for Ping Reply
static uint16_t RandomID = 0x1234; 
static uint16_t RandomSeqNum = 0x4321;
uint8_t ping_reply_received = 0; 
uint8_t req=0;
uint8_t rep=0;

#define Sn_PROTO(ch) (0x001408 + (ch << 5))

uint8_t ping_auto(uint8_t s, uint8_t *addr)
{
	uint8_t i;
	int32_t len = 0;
	uint8_t cnt=0;
for(i = 0; i<=3;i++){

		switch(getSn_SR(s))
		{
			case SOCK_CLOSED:
				close(s);
				IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP);              // set ICMP Protocol
				if(socket(s,Sn_MR_IPRAW,3000,0)!=0){       // open the SOCKET with IPRAW mode, if fail then Error
					printf( "\r\n socket %d fail r\n",   (0)) ;
#ifdef PING_DEBUG
					return SOCKET_ERROR;
#endif
				}
		/* Check socket register */
				while(getSn_SR(s)!=SOCK_IPRAW);
					sleep_ms(1000); // wait 1000ms
					sleep_ms(1000); // wait 1000ms
					break;
			case SOCK_IPRAW:
    			ping_request(s, addr);
    			req++;
    			while(1){
    				if ( (len = getSn_RX_RSR(s) ) > 0)
    				{
    					ping_reply(s, addr, len);
    					rep++;
    					break;
    				}
    				else if(cnt > 100)
    				{
    					printf( "Request Time out. \r\n");
    					cnt = 0;
    					break;
    				}
    				else
    				{
    					cnt++;
    					sleep_ms(50); // wait 50ms
    			    }
    	// wait_time for 2 seconds, Break on fail
    			}

    			break;
			default:
				break;

		}
#ifdef PING_DEBUG
		if(req>=3)
	   	{

	  		printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);

	  		if(rep == req)
	  			return SUCCESS;
	  		else
	  			return REPLY_ERROR;

	  	}
#endif
	}
}


uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t *addr){

	uint16_t rlen, cnt,i;
	cnt = 0;
	 	 
	for(i=0; i<pCount+1;i++){

	if(i!=0){
		/* Output count number */
			printf( "\r\nNo.%d\r\n",   (i-1));
	}

  	switch(getSn_SR(s))
		{
			case SOCK_CLOSED:
				close(s);  
				                                                  // close the SOCKET
				/* Create Socket */  
				IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP);              // set ICMP Protocol
				if(socket(s,Sn_MR_IPRAW,3000,0)!=s){       // open the SOCKET with IPRAW mode, if fail then Error
					printf( "\r\n socket %d fail r\n",   (s)) ;
#ifdef PING_DEBUG
					return SOCKET_ERROR;
#endif
				}	
				/* Check socket register */
				while(getSn_SR(s)!=SOCK_IPRAW);

				sleep_ms(1000); // wait 1000ms
				sleep_ms(1000); // wait 1000ms
				break;

			case SOCK_IPRAW:
				 ping_request(s, addr);
				 req++;
				while(1){
						if ( (rlen = getSn_RX_RSR(s) ) > 0){
							ping_reply(s, addr, rlen);
							rep++;
							if (ping_reply_received)  break;
						   
						}

					     /* wait_time for 2 seconds, Break on fail*/
						if ( (cnt > 100) ) {
							printf( "\r\nRequest Time out. \r\n") ;
							cnt = 0;
							break;
						}else { 
							cnt++; 	
							sleep_ms(50); // wait 50ms
						}
				     }

				break;

			default:		
				break;
		
       }
#ifdef PING_DEBUG
  		if(req>=pCount)
  		   	{
  		  		printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);

  		  		if(rep == req)
  		  			return SUCCESS;
  		  		else
  		  			return REPLY_ERROR;
  		  	}
#endif
   }


}

uint8_t ping_request(uint8_t s, uint8_t *addr){
  uint16_t i;

	//Initailize flag for ping reply
	ping_reply_received = 0;
	/* make header of the ping-request  */
	PingRequest.Type = PING_REQUEST;                   // Ping-Request
	PingRequest.Code = CODE_ZERO;	                   // Always '0'
	PingRequest.ID = htons(RandomID++);	       // set ping-request's ID to random integer value
	PingRequest.SeqNum =htons(RandomSeqNum++);// set ping-request's sequence number to ramdom integer value
	//size = 32;                                 // set Data size

	/* Fill in Data[]  as size of BIF_LEN (Default = 32)*/
  	for(i = 0 ; i < BUF_LEN; i++){	                                
		PingRequest.Data[i] = (i) % 8;		  //'0'~'8' number into ping-request's data 	
	}
	 /* Do checksum of Ping Request */
	PingRequest.CheckSum = 0;		               // value of checksum before calucating checksum of ping-request packet
	PingRequest.CheckSum = htons(checksum((uint8_t*)&PingRequest,sizeof(PingRequest)));  // Calculate checksum
	
     /* sendto ping_request to destination */
	if(sendto(s,(uint8_t *)&PingRequest,sizeof(PingRequest),addr,3000)==0){  // Send Ping-Request to the specified peer.
	  	 printf( "\r\n Fail to send ping-reply packet  r\n") ;					
	}else{
	 	  printf( "Send Ping Request  to Destination (") ;					
          printf( "%d.%d.%d.%d )",   (addr[0]),  (addr[1]),  (addr[2]),  (addr[3])) ;
		  printf( " ID:%x  SeqNum:%x CheckSum:%x\r\n",   htons(PingRequest.ID),  htons(PingRequest.SeqNum),  htons(PingRequest.CheckSum)) ;
	}
	return 0;
} // ping request

uint8_t ping_reply(uint8_t s, uint8_t *addr,  uint16_t rlen){
	 
	 uint16_t tmp_checksum;	
	 uint16_t len;
	 uint16_t i;
	 uint8_t data_buf[128];
	 uint16_t port = 3000;
	 PINGMSGR PingReply;
		/* receive data from a destination */
	  	len = recvfrom(s, (uint8_t *)data_buf,rlen,addr,&port);
			if(data_buf[0] == PING_REPLY) {
				PingReply.Type 		 = data_buf[0];
				PingReply.Code 		 = data_buf[1];
				PingReply.CheckSum   = (data_buf[3]<<8) + data_buf[2];
				PingReply.ID 		 = (data_buf[5]<<8) + data_buf[4];
				PingReply.SeqNum 	 = (data_buf[7]<<8) + data_buf[6];

				for(i=0; i<len-8 ; i++)
				{
					PingReply.Data[i] = data_buf[8+i];
				}
					/* check Checksum of Ping Reply */
				tmp_checksum = ~checksum(data_buf,len);
				if(tmp_checksum != 0xffff)
					printf("tmp_checksum = %x\r\n",tmp_checksum);
				else{
					/*  Output the Destination IP and the size of the Ping Reply Message*/
				    	printf("Reply from %d.%d.%d.%d  ID:%x SeqNum:%x  :data size %d bytes\r\n",
						  (addr[0]),  (addr[1]),  (addr[2]),  (addr[3]),  htons(PingReply.ID),  htons(PingReply.SeqNum),  (rlen+6) );
				    	printf("\r\n");
				    	/*  SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
					ping_reply_received =1;
				}
			}
			else if(data_buf[0] == PING_REQUEST){
				PingReply.Code 	 = data_buf[1];
				PingReply.Type 	 = data_buf[2];
				PingReply.CheckSum  = (data_buf[3]<<8) + data_buf[2];
				PingReply.ID 		 = (data_buf[5]<<8) + data_buf[4];
				PingReply.SeqNum 	 = (data_buf[7]<<8) + data_buf[6];

				for(i=0; i<len-8 ; i++)
				{
					PingReply.Data[i] = data_buf[8+i];
				}
					/* check Checksum of Ping Reply */
				tmp_checksum = PingReply.CheckSum;
				PingReply.CheckSum = 0;
				PingReply.CheckSum = htons(checksum((uint8_t*)(&PingReply),len));

						if(tmp_checksum != PingReply.CheckSum){
							printf( " \n CheckSum is in correct %x shold be %x \n",   (tmp_checksum),  htons(PingReply.CheckSum)) ;
						}else{
							//printf( "\r\n Checksum is correct  \r\n") ;					
						}
		
					/*  Output the Destination IP and the size of the Ping Reply Message*/
				    	printf("Request from %d.%d.%d.%d  ID:%x SeqNum:%x  :data size %d bytes\r\n",
						  (addr[0]),  (addr[1]),  (addr[2]),  (addr[3]),  (PingReply.ID),  (PingReply.SeqNum),  (rlen+6) );
					/*  SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/		   
					ping_reply_received =1;

			}
			else{      
 					 printf(" Unkonwn msg. \n");
			}


			return 0;
}// ping_reply



uint16_t checksum(uint8_t * data_buf, uint16_t len)

{
  uint16_t sum, tsum, i, j;
  uint32_t lsum;

  j = len >> 1;
  lsum = 0;
  tsum = 0;
  for (i = 0; i < j; i++)
    {
      tsum = data_buf[i * 2];
      tsum = tsum << 8;
      tsum += data_buf[i * 2 + 1];
      lsum += tsum;
    }
   if (len % 2)
    {
      tsum = data_buf[i * 2];
      lsum += (tsum << 8);
    }
    sum = (uint16_t)lsum;
    sum = ~(sum + (lsum >> 16));
  return sum;

}


uint16_t htons( uint16_t hostshort)
{
#if 1
  //#ifdef LITTLE_ENDIAN
	uint16_t netshort=0;
	netshort = (hostshort & 0xFF) << 8;

	netshort |= ((hostshort >> 8)& 0xFF);
	return netshort;
#else
	return hostshort;
#endif
}

#if 0
/*****************************************************************************************
	Function name: wait_1us
	Input		:	cnt; Delay duration = cnt * 1u seconds
	Output	:	non
	Description
	: A delay function for waiting cnt*1u second.
*****************************************************************************************/
void wait_1us(unsigned int cnt)
{
	unsigned int i;

	for(i = 0; i<cnt; i++) {

		}
}

/*****************************************************************************************
	Function name: sleep_ms
	Input		:	cnt; Delay duration = cnt * 1m seconds
	Output	:	non
	Description
	: A delay function for waiting cnt*1m second. This function use wait_1us but the wait_1us
		has some error (not accurate). So if you want exact time delay, please use the Timer.
*****************************************************************************************/
void sleep_ms(unsigned int cnt)
{
	unsigned int i;
	for (i = 0; i < cnt; i++) wait_1us(1000);
}
#endif

/*****************************************************************************************
	Function name: wait_10ms
	Input		:	cnt; Delay duration = cnt * 10m seconds
	Output	:	non
	Description
	: A delay function for waiting cnt*10m second. This function use sleep_ms but the sleep_ms
		has some error (not accurate more than wait_1us). So if you want exact time delay,
		please use the Timer.
*****************************************************************************************/
void wait_10ms(unsigned int cnt)
{
	unsigned int i;
	for (i = 0; i < cnt; i++) sleep_ms(10);
}

Ping.h

#include "wizchip_conf.h"


#define BUF_LEN 32
#define PING_REQUEST 8
#define PING_REPLY 0
#define CODE_ZERO 0

#define SOCKET_ERROR 1
#define TIMEOUT_ERROR 2
#define SUCCESS 3
#define REPLY_ERROR 4
#define PING_DEBUG


typedef struct pingmsg
{
  uint8_t  Type; 		// 0 - Ping Reply, 8 - Ping Request
  uint8_t  Code;		// Always 0
  int16_t  CheckSum;	// Check sum
  int16_t  ID;	            // Identification
  int16_t  SeqNum; 	// Sequence Number
  int8_t	 Data[BUF_LEN];// Ping Data  : 1452 = IP RAW MTU - sizeof(Type+Code+CheckSum+ID+SeqNum)
} PINGMSGR;


uint8_t ping_auto(uint8_t s, uint8_t *addr);
uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t *addr);
uint8_t ping_request(uint8_t s, uint8_t *addr);
uint8_t ping_reply(uint8_t s,  uint8_t *addr, uint16_t rlen);
uint16_t checksum(uint8_t * data_buf, uint16_t len);
uint16_t htons( uint16_t  hostshort);	/* htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).*/

 

测试代码如下

uint8_t pDestaddr[4] = {120,232,145,144};

     uint8_t tmp=0;

        tmp = ping_auto(0,pDestaddr);

        if(tmp == SUCCESS)

            printf("-----------PING TEST OK----------\r\n");

        else

            printf("----------ERROR  = %d----------\r\n",tmp);

        sleep_ms(50);

 

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表