.
Arduino IDE 환경에서 TCP전송률 테스트 결과 12Mbps 정도로 측정이 되서 다른 MCU들의 iperf 테스트 결과와 비교해 느린것 같아 SDK 환경에서 테스트 해볼 필요가 있을것 같다.
RP2040 C/C++ SDK 개발환경 예제를 이용하여 W5500 TCP 전송률 테스트를 해보자
라이브러리는 Wiznet의 W5500 SDK를 다운받아 사용하였다.
RP2040에서 W5500 테스트 기본 예제는 아래코드로 작성했다.
#include "pico/critical_section.h"
#include "hardware/clocks.h"
#include "wizchip_conf.h"
#include "w5x00_spi.h"
#include "socket.h"
#define _USE_LOOPBACK 0
#define PLL_SYS_KHZ (133 * 1000)
//#define PLL_SYS_KHZ (125 * 1000)
/* Buffer */
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
//#define ETHERNET_BUF_MAX_SIZE (1460 * 2)
#define DATA_BUF_SIZE ETHERNET_BUF_MAX_SIZE
/* Socket */
#define SOCKET_LOOPBACK 0
/* Port */
#define PORT_LOOPBACK 5001
int main() {
int retval = 0;
set_clock_khz();
// Enable UART so we can print status output
stdio_init_all();
#if !defined(spi_default) || !defined(PICO_DEFAULT_SPI_SCK_PIN) || !defined(PICO_DEFAULT_SPI_TX_PIN) || !defined(PICO_DEFAULT_SPI_RX_PIN) || !defined(PICO_DEFAULT_SPI_CSN_PIN)
#warning spi/spi_dma example requires a board with SPI pins
puts("Default SPI pins were not defined");
#else
printf("RP2040 W5500 iperf test\n");
wizchip_spi_initialize();
wizchip_cris_initialize();
wizchip_reset();
wizchip_initialize();
wizchip_check();
network_initialize(g_net_info);
/* Get network information */
print_network_information(g_net_info);
gpio_init(LED_PIN1);
gpio_set_dir(LED_PIN1, GPIO_OUT);
while (1)
{
/* TCP server loopback test */
if ((retval = iperf_tcps(SOCKET_LOOPBACK, g_loopback_buf, PORT_LOOPBACK)) < 0)
{
printf(" Loopback error : %d\n", retval);
while (1)
;
}
}
}
네트웍 전송율 테스트를 위해 PC에서는 iperf 프로그램을 사용하고 W5500 TCP loopback 테스트 코를 조금 수정해 iperf 서버 코드로 작성했다.
int32_t iperf_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
{
int32_t ret;
uint16_t size = 0, sentsize=0;
#ifdef _LOOPBACK_DEBUG_
uint8_t destip[4];
uint16_t destport;
#endif
switch(getSn_SR(sn))
{
case SOCK_ESTABLISHED :
if(getSn_IR(sn) & Sn_IR_CON)
{
#ifdef _LOOPBACK_DEBUG_
getSn_DIPR(sn, destip);
destport = getSn_DPORT(sn);
printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
#endif
setSn_IR(sn,Sn_IR_CON);
}
if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
{
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
ret = recv(sn, buf, size);
if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
size = (uint16_t) ret;
#if _USE_LOOPBACK
sentsize = 0;
while(size != sentsize)
{
ret = send(sn, buf+sentsize, size-sentsize);
if(ret < 0)
{
close(sn);
return ret;
}
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
}
#endif
}
break;
case SOCK_CLOSE_WAIT :
#ifdef _LOOPBACK_DEBUG_
//printf("%d:CloseWait\r\n",sn);
#endif
if((ret = disconnect(sn)) != SOCK_OK) return ret;
#ifdef _LOOPBACK_DEBUG_
printf("%d:Socket Closed\r\n", sn);
#endif
break;
case SOCK_INIT :
#ifdef _LOOPBACK_DEBUG_
printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port);
#endif
if( (ret = listen(sn)) != SOCK_OK) return ret;
break;
case SOCK_CLOSED:
#ifdef _LOOPBACK_DEBUG_
//printf("%d:TCP server loopback start\r\n",sn);
#endif
if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
#ifdef _LOOPBACK_DEBUG_
//printf("%d:Socket opened\r\n",sn);
#endif
break;
default:
break;
}
return 1;
}
DMA를 사용하지 않고 테스트 해 보면 5Mbps 정도로 측정이 된다.
DMA 를 사용하여 RP2040의 W5500 iperf TCP 전송률은 14.5Mbps 정도로 측정된다.
TCP loopback 테스트로 송수신 통신을 구현하면 Wiznet에서 제공하는 Loopback Test Program Ax에서 13Mbps 로 측정이 된다.
그렇다면 수신만 체크하는 iperf 에서 20Mbps 이상은 나와야 할것 같은데...
Cortex-M0+코어에 64Mhz로 동작하는 STM32G0에서 W5500 iperf 테스트 결과와 비교해도 속도가 빠르지 않다.
속도를 높일 수 있는 방법을 위해 좀더 검토가 필요해 보인다.
반응형