본문 바로가기

RaspberryPi/W55RP20

[W55RP20-4032] W55RP20 Arduino - Ethernet3 라이브러리를 이용한 iperf 전송률 개선 하기

 

W55RP20 Arduino lwIP 에서 이더넷 전송률 테스트 결과 너무 느려서 찾아보다 보니 W55RP20-Ethernet3 라이브러리가 있다.

 

https://github.com/WIZnet-ioNIC/W55RP20-Ethernet3

 

W55RP20 PIO기반 라이브러리로 소트웨어 IP를 사용하는 것이 아니라 Wiznet의 하드웨어 스택을 사용할수 있어 속도가 빠르다고 한다.

 

 

우선 iperf로 TCP 전송률 테스트를 해보자.

 

#include <W55RP20_Ethernet3.h>

const uint16_t port = 5001;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };


IPAddress ip(192, 168, 1, 104);
IPAddress subnet(255, 255, 254, 0);   
IPAddress gateway(192, 168, 1, 1);


EthernetServer server(port); 
byte buf[2048];  

unsigned long lastReportTime = 0;
unsigned long long totalBytesReceived = 0;

void setup() {
  Serial.begin(115200);
  delay(5000);
  Serial.println("\n--- W55RP20 하드웨어 가속 (Ethernet3) TCP 테스트 ---");

  Ethernet.begin(mac, ip, subnet, gateway);

  Serial.print("Ethernet Ready. Static IP: ");
  Serial.println(Ethernet.localIP());

  server.begin();
  Serial.println("Listening for TCP iperf connections...");
}

void loop() {
  EthernetClient client = server.available();

  if (client) {
    Serial.println("\n[측정 시작] PC가 TCP로 연결되었습니다. 데이터 수신 중...");
    totalBytesReceived = 0;
    lastReportTime = millis();
    
    while (client.connected() || client.available() > 0) {
      int availableBytes = client.available();
      
      if (availableBytes > 0) {
        int bytesToRead = availableBytes;
        if (bytesToRead > sizeof(buf)) {
          bytesToRead = sizeof(buf);
        }

        int readBytes = client.read(buf, bytesToRead);
        if (readBytes > 0) {
          totalBytesReceived += readBytes;
        }
      }

      if (millis() - lastReportTime >= 1000) {
        unsigned long now = millis();
        unsigned long durationMs = now - lastReportTime;
        
        double mbps = (totalBytesReceived * 8.0) / (durationMs / 1000.0) / 1000000.0;
        
        Serial.print("-> [TCP 보드 실측] 수신 속도: ");
        Serial.print(mbps, 2);
        Serial.println(" Mbps");
        
        totalBytesReceived = 0;
        lastReportTime = now;
      }
    }
   

    client.stop();
    Serial.println("[측정 종료] TCP 클라이언트 연결 해제. 대기 상태 복귀");
  }
}

 

 

5Mbps 정도의 전송률이 나온다. pi pico SDK 보다는 빠르지 않지만 그래도 2배 이상 성능이 좋아진것 같다. 드라이버파일을 들여다보면 속도를 더 올릴수 있겠지만 일단 이정도면 96khz 고음질 음성 전송에도 문제가 없을것 같다.

 


UDP는 1Mbps 정도로 측정이 된다.

이정도면 네트웍 스피커로 사용할수가 없는데...

 

D:\iperf>iperf -c 192.168.1.104 -u
------------------------------------------------------------
Client connecting to 192.168.1.104 , UDP port 5001
Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
UDP buffer size:  208 KByte (default)
------------------------------------------------------------
[  3] local 192.168.1.104 port 49723 connected with 192.168.1.104 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  1.25 MBytes  1.05 Mbits/sec
[  3] Sent 893 datagrams
[  3] WARNING: did not receive ack of last datagram after 10 tries.


[측정 시작] PC로부터 UDP 패킷 수신 중...
-> [보드 하드웨어 실측] 수신 속도: 1.06 Mbps
-> [보드 하드웨어 실측] 수신 속도: 1.05 Mbps
-> [보드 하드웨어 실측] 수신 속도: 1.05 Mbps

 

 

UDP는 디폴트로 전송 하면 1M씩 보낸다고 한다. UDP는 ACK 체크를 하지 않기 때문에 iperf에서 정상 속도를 알수 없다.

 

10M로 보내 보자

 

D:\iperf>iperf -c 192.168.1.104 -u -b 10M

------------------------------------------------------------

Client connecting to 192.168.1.104, UDP port 5001

Sending 1470 byte datagrams, IPG target: 1176.00 us (kalman adjust)

UDP buffer size:  208 KByte (default)

------------------------------------------------------------

[  3] local 192.168.1.104 port 59028 connected with 192.168.1.104 port 5001

[ ID] Interval       Transfer     Bandwidth

[  3]  0.0-10.0 sec  11.9 MBytes  10.0 Mbits/sec

[  3] Sent 8505 datagrams

[  3] WARNING: did not receive ack of last datagram after 10 tries.



[측정 시작] PC로부터 UDP 패킷 수신 중...

-> [보드 하드웨어 실측] 수신 속도: 3.73 Mbps

-> [보드 하드웨어 실측] 수신 속도: 3.75 Mbps

-> [보드 하드웨어 실측] 수신 속도: 3.75 Mbps

-> [보드 하드웨어 실측] 수신 속도: 3.80 Mbps

-> [보드 하드웨어 실측] 수신 속도: 3.76 Mbps

 

실제 전송시간 기준으로 계산하면 3.7Mbps로 측정된다.

그런데 왜 UDP는 TCP보드 속도가 더 느릴까?

 


옵티마이즈 때문인가?

옵티마이즈 변경해도 동일하다.

 

 

라이브러리파일을 들여다보자
W55RP20-Ethernet3\src\utility\w5500.h

 

파일에 MAX_SOCK_NUM 가 보인다. 이값에 따라 버퍼 사이즈를 결정하는것 같다. 최대로 늘여보자.

//#define MAX_SOCK_NUM 8
#define MAX_SOCK_NUM 1


동일하다.

 

init 함수에서 버퍼 사이즈 설정하는 부분이 있다. 이것도 수정해 보자.

 Ethernet.init(1);

 

 

6.2Mbps 로 두배 정도 빨라졌다.

--- W55RP20 하드웨어 가속 (Ethernet3) 테스트 ---
Ethernet Ready. IP: 192.168.1.104
Listening for UDP iperf (Hardware TOE via PIO)...

[측정 시작] PC로부터 UDP 패킷 수신 중...
-> [보드 하드웨어 실측] 수신 속도: 6.12 Mbps
-> [보드 하드웨어 실측] 수신 속도: 6.11 Mbps

SPI   클럭 설정부분도 있다.

20Mhz로 설정되어 있는데 이부분을 올리면 장치가 동작하지 않는다.

 

// W5500 controller instance
W5500Class w5500;
#define SPI_CLOCK 20000000

PioSPI spiBus(23, 22, 21, 20, SPI_MODE0, SPI_CLOCK); //MOSI, MISO, SCK, CS, CPHA, CPOL, FREQUENCY

// SPI details
SPISettings wiznet_SPI_settings(SPI_CLOCK, MSBFIRST, SPI_MODE0);

 

 

  pi pico SDK 보다 느리지? 

아무튼 결론적으로 W55RP20의 Arduino 환경에서  UDP전송률은 6Mbps가 최대치인것 같다. 우선 오디오 전송에는 문제가 없을것 같다.


 

참고 : W55RP20 Pi Pico C/C++ SDK환경에서 UDP 최대  전송률 측정