上一章我们用开发板作为UDP Server进行数据回环测试,本章我们让我们的开发板作为UDP Client进行数据回环测试。
使开发板和我们的电脑处于同一网段:
我们打开例程中库文件的loopback.c文件,可以看到udp server回环测试函数,它有四个参数:socket(套接字)端口号(0~7个端口,可开8路socket)、数据收发缓存buf、目标IP和目标端口;原理上依旧是通过Switch状态机轮询socket端口(所开端口的套接字)状态,根据不同状态做出相应处理;如果为关闭状态就初始化socket状态为udp协议模式;如果状态已经处于udp模式,即socket初始化后,就主动给目标IP和设置的目标端口发送数据,并且进行判断是否收到数据,收到就进行回传。如下所示:
int32_t loopback_udpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport)
{
int32_t ret;
uint16_t size = 0, sentsize=0;
static uint16_t any_port = 50000;
switch(getSn_SR(sn))
{
case SOCK_UDP :
sendto(sn, "test", 4, destip, destport);
if((size = getSn_RX_RSR(sn)) > 0)
{
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
buf[ret]=0x00;
printf("recv form[%d.%d.%d.%d][%d]: %s\n", destip[0],destip[1],destip[2],destip[3],destport,buf);
if(ret <= 0)
{
#ifdef _LOOPBACK_DEBUG_
printf("%d: recvfrom error. %ld\r\n",sn,ret);
#endif
return ret;
}
size = (uint16_t) ret;
sentsize = 0;
while(sentsize != size)
{
ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport);
if(ret < 0)
{
#ifdef _LOOPBACK_DEBUG_
printf("%d: sendto error. %ld\r\n",sn,ret);
#endif
return ret;
}
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
}
}
break;
case SOCK_CLOSED:
#ifdef _LOOPBACK_DEBUG_
//printf("%d:UDP loopback start\r\n",sn);
#endif
if((ret = socket(sn, Sn_MR_UDP, any_port, 0x00)) != sn)
return ret;
#ifdef _LOOPBACK_DEBUG_
printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, any_port);
#endif
break;
default :
break;
}
return 1;
}
然后我们初始化网络配置信息,目标IP(本机电脑IP)和目标端口,在主函数里循环调用测试函数即可。如下所示:
#define SOCKET_ID 0
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
void network_init(void);
wiz_NetInfo net_info = {
.mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},
.ip = {192, 168, 1, 10},
.sn = {255, 255, 255, 0},
.gw = {192, 168, 1, 1},
.dns = {8, 8, 8, 8},
.dhcp = NETINFO_STATIC};
wiz_NetInfo get_info;
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0,};
static uint8_t destip[4]={192, 168, 1, 2};
static uint16_t destport = 8080;
static uint16_t local_port =8000; //UDP Server listener port
int main()
{
stdio_init_all();
sleep_ms(2000);
network_init();
while(true)
{
loopback_udpc(SOCKET_ID, ethernet_buf, destip, destport);
// loopback_udps(SOCKET_ID, ethernet_buf, local_port);
sleep_ms(500);
}
}
void network_init(void)
{
uint8_t temp;
wizchip_initialize();
printf("W5500 udp client example.\r\n");
sleep_ms(2000);
wizchip_setnetinfo(&net_info);
print_network_information(get_info);
sleep_ms(2000);
}
编译烧录后,打开串行监视器,看到网络信息配置成功后,打开两个网络调试助手,参数依次设置为UDP、开发板初始化的目标IP和目标端口,远程主机地址和端口为我们开发板的本地IP和端口,注意这里的端口是在回环函数内部实现的,这里为50000,注意区分UDP Server模式下的本地端口,打开后我们即可看到收到开发板主动发来的数据,然后我们发送0~9十个阿拉伯数字,可以看到串口打印收到的数据,而且调试助手也分别收到了对应回传的数据。如下图所示:
我们可以打开wireshark抓包工具,输入命令
本章相关例程链接https://gitee.com/wiznet-hk/w5500-evb-pico-routine.git