517|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/10 下一条
福禄克有奖直播:高精度测温赋能电子制造 报名中!
直播时间:2025年2月28日(周五)上午10:00
直播主题:高精度测温赋能电子制造
小伙伴们儿快来报名直播吧~好礼等你拿!

查看 »

 
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
快速回复 返回顶部 返回列表