본문 바로가기

[INTERFACE]/WIZNET_EVM

W5300 을 이용한 네트워크 카메라 구현 2/3 - TCP 전송률 테스트

Wiznet ioLibrary Driver 포팅 및 TCP Loopback 전송률 테스트

 

Wiznet ioLibrary Driver 포팅

W5300을 제어 하기 위해 가장 기본적으로 해야 할 일이 W5300의 레지스터에 원하는 값을 쓰고 읽어 보는 것이다.

레지스터의 값을 쓰고 읽는 함수는 Wiznet ioLibrary Driver에 포함되어 있고 보드에 맞도록 포팅해 주어야 한다.

 

W5300 loopback 테스트 소스코드는 https://github.com/elabsystem/STM32_RP/tree/master/ex10_w5300_loopback 에서 확인 가능하다.

 

 

W5300 테스트를 위한 [STM32F4-RP] 보드의 기본 개발환경 설정이 완료 되었다면 다운로드 받은 ioLibrary의 Ethernet 폴더에 W5300관련 코드를 프로젝트에 복사 하고 컴파일 해 보자



아래와 같이 에러가 발생 한다.

헤더파일의 디렉토리를 찾을수 없다는 에러가 발생 한다.



STM32CubeIDE의 환경설정에서 ioLibrary의 include paths를 설정해 주면 해결된다.

../Src
../Src/ioLibrary_Driver-master/Ethernet
../Src/ioLibrary_Driver-master/Ethernet/w5300





컴파일이 완료 되었다면 ioLibrary를 보드에 맞게 포팅해 주어야 하는데 W5300의 리셋함수, W5300 레지스터 읽기 함수(W5300_read), 쓰기 함수(W5300_write)를 등록 해 주면 된다.

 

#define W5300_BANK_ADDR                 ((uint32_t)0x64000000)
#define _W5300_DATA(p)                  (*(volatile unsigned short*) (W5300_BANK_ADDR + (p<<1)))


void Reset_W5300()
{
  HAL_GPIO_WritePin(RESET_W5300_GPIO_Port, RESET_W5300_Pin, GPIO_PIN_RESET);
  HAL_Delay(10);
  HAL_GPIO_WritePin(RESET_W5300_GPIO_Port, RESET_W5300_Pin, GPIO_PIN_SET);
  HAL_Delay(100);
}

void W5300_write(uint32_t addr, iodata_t wd)
{
  _W5300_DATA(addr) = wd;
}

iodata_t W5300_read(uint32_t addr)
{
  return _W5300_DATA(addr);
}




 

메인 함수에서 아래와 같이 코드를 작성하여 W5300의 SHAR 레지스터에 값을 쓰고 읽는 테스트를 해보자

  printf("W5300 Hello World!\r\n");

  Reset_W5300();
  reg_wizchip_bus_cbfunc(W5300_read, W5300_write);

  while(1)
  {
    wr_data = 0x1234;

    printf("write= %x\r\n", wr_data);
    WIZCHIP_WRITE(SHAR, wr_data);

    rd_data = WIZCHIP_READ(SHAR);
    printf("read= %x\r\n", rd_data);

    HAL_Delay(1000);
  }



프로그램을 실행 하면 시리얼 포트를 통해 W5300의 SHAR 레지스터에 쓴값을 동일하게 읽어 오는 것을 확인 할수 있다.

 




W5300 TCP Loopback 전송속도 테스트

W5300을 이용하여 TCP loopback 테스트를 하기 위해 loopback.c 파일을 사용하면 된다.

먼저 네트워크 환경을 wiz_NetInfo 구조체에 할당하고 초기화 코드를 작성해 준다.

wiz_NetInfo gWIZNETINFO = {
.mac = {0x00, 0x08, 0xdc, 0, 0, 0},
.ip = {172, 30, 1, 104},
.sn = {255, 255, 0, 0},
.gw = {172, 30, 1, 254},
.dns = {0, 0, 0, 0},
.dhcp = NETINFO_STATIC
};

void Reset_W5300()
{
  HAL_GPIO_WritePin(RESET_W5300_GPIO_Port, RESET_W5300_Pin, GPIO_PIN_RESET);
  HAL_Delay(10);
  HAL_GPIO_WritePin(RESET_W5300_GPIO_Port, RESET_W5300_Pin, GPIO_PIN_SET);
  HAL_Delay(100);
}

void W5300_write(uint32_t addr, iodata_t wd)
{
	_W5300_DATA(addr) = wd;
}

iodata_t W5300_read(uint32_t addr)
{
	return _W5300_DATA(addr);
}

void _InitW5300(void)
{
  unsigned int tmpaddr[4];

  Reset_W5300();
  reg_wizchip_bus_cbfunc(W5300_read, W5300_write);

  printf("getMR() = %04X\r\n", getMR());

  if (ctlwizchip(CW_INIT_WIZCHIP, (void*)wiznet_memsize) == -1)
  {
  	printf("W5300 memory initialization failed\r\n");
  }

  ctlnetwork(CN_SET_NETINFO, (void *)&gWIZNETINFO);

  print_network_information();
}

 

메인 루프에서 loopback_tcps() 함수를 주기적으로 호출 해 TCP 프로토콜을 처리 해 주면 TCP loopback 테스트 펌웨어 코드가 완성된다

int main(void)
{
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FSMC_Init();
  MX_USART1_UART_Init();


  /* USER CODE BEGIN 2 */
  printf("STM3F4 W5300 Test\r\n");

  _InitW5300();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  loopback_tcps(0, ether_buf,3000);
  }
  /* USER CODE END 3 */
}

 

 

프로그램을 실행하면 설정한 네트워크 정보가 표시 되며 TCP loopback server 가 수행된다.




펌웨어가 정상적으로 실행이 되었다면 Wiznet의 Loopback Test Program Ax를 이용하여 네트웍 전송률을 테스트 해볼 수 있다.

 

 

[1] iInChip Send: 20.5430 Mbps(12470418 bytes, 4.6314 sec)

iInChip Recv: 20.4434 Mbps(12470418 bytes, 4.6539 sec)

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



 STM32F4의 내장 Ethernet Controller의 TCP loopback 전송률 테스트 결과에서 30Mbps 와 비교 해보면 20Mbps 의 전송 속도는 아쉬움이 있다.

하지만 ioLibrary 로 기존에 작성된 다양한 쉽게 적용하여 네트워크 관련 응용 예제를 테스트 해 볼수 있을 것 같다.






최적화

ioLibrary 는 표준화된 코드이고 다양한 하드웨어를 지원하기 위한 코드로 작성되어 있기 때문에 최대 성능을 사용하려면 하드웨어에 맞도록 최적화가 필요 하다.

 

네트워크 전송 속도를 높이려면 W5300에 데이터를 최대한 빨리 읽고 써야 하는데  w5300.c 파일에 있는 WIZCHIP_WRITE(), WIZCHIP_READ() 함수를 수정하면 된다.

 

아래 코드와 같이 수정하면 함수 포인터를 거치는 지연없이 바로 메모리에 접근 할 수 있다.

이부분을 DMA를 사용하면 좀더 성능을 개선할 수 있을것 같다.

 

WIZCHIP_WRITE() 함수

 

WIZCHIP_READ() 함수





최적화를 통해 동일한 코드를 실행 하면 62 Mbps(7.7 Mbytes) 의 전송 속도를 확인 할수 있다.

(이 수치는 Host CPU의 속도에 따라 다른것 같다. i7-9700 @3Ghz 기준)

 



640 x 480 영상의 경우 한프레임이 614400byte(640x480x2) 이므로 7.7Mbyte/s 에서  최대 12프레임 정도 전송할 수 있는 성능이 될것 같다.

 

다음 포스트에서 네트웍을 통한 영상 전송을 테스트 볼 것이다.

https://nexp.tistory.com/3047





활용

ioLibrary 의 장점은 표준화된 코드로 다양한 네트워크 응용 프로그램을 쉽게 작성할 수 있다는 것이다. Wiz550web 예제( https://github.com/Wiznet/WIZ550web) 를 참고하여 Web Server 를 구현하면  간단히 W5300 Web Server 로 보드를 제어 할 수 있다.

 

W5300을 이용한  WebServer 테스트 테스트 동영상